HaskellのOptparse-Applicativeの底力を知る
元ネタ RubyのOptionParserの底力を知る - ザリガニが見ていた...。
Haskell版で苦労最小限でオプションを解析できるのか、調べてみた。
使うライブラリは optparse-applicative
理由は最近見かけたこのスライドで推薦されていたから
Getting it Done with Haskell - Google スライド
optparse-applicative のバージョンは 0.9.1.1
githubの最新版ではいくつかの関数・APIが変更されているようで、使用バージョンではマニュアル通りに書いてもエラーになるものもあった。
基本
module Main where import Data.Monoid import Options.Applicative data MyOption= MyOption { optName :: String } runWithOptions :: MyOption -> IO () runWithOptions opts = putStrLn $ "name = " ++ optName opts main :: IO () main = execParser opts >>= runWithOptions where parser = MyOption <$> argument str (metavar "NAME") opts = info parser mempty
- オプション定義のデータ型を定義する
- ハイフン付きのオプションだけでなく素の引数も定義できる
- 簡単なヘルプが自動で出力される
$ runghc ex01.hs foo name = foo $ runghc ex01.hs Usage: ex01.hs NAME
1文字オプション
- 1文字オプションは、-で始まる1文字のオプション名。
- short で設定する
module Main where import Options.Applicative data MyOption= MyOption { optName :: String , a :: Bool , b :: String , c :: Maybe String } deriving Show run :: MyOption -> IO () run opts = print opts parser = MyOption <$> argument str (metavar "NAME") <*> switch (short 'a' <> help "1文字オプション 引数なし") <*> strOption (short 'b' <> help "1文字オプション 引数あり (必須)") <*> optional (strOption (short 'c' <> help "1文字オプション 引数あり (省略可能)")) main :: IO () main = execParser opts >>= run where opts = info parser idm
1文字オプションとロングオプション
- ロングオプションは、--で始まる2文字以上のオプション名。
module Main where import Options.Applicative data MyOption= MyOption { optName :: String , a :: Bool , b :: String , c :: Maybe String } deriving Show run :: MyOption -> IO () run opts = print opts parser = MyOption <$> argument str (metavar "NAME") <*> switch (short 'a' <> long "along" <> help "1文字オプション 引数なし") <*> strOption (short 'b' <> long "blong" <> help "1文字オプション 引数あり (必須)") <*> optional (strOption (short 'c' <> long "clong" <> help "1文字オプション 引数あり (省略可能)")) main :: IO () main = execParser opts >>= run where opts = info parser idm
noオプション
- noオプションにあたるものは無さそう
オプション引数を数値や配列として受け取る
- ハイフン指定無しの文字列引数は argument str
- 文字列引数は strOption
- 整数値などは option
- 文字列リストは many . strOption
- 整数リストはいくつか試してみたが方法がわからず
module Main where import Options.Applicative data MyOption= MyOption { optName :: String , optStr :: String , optStr2 :: String , optInt :: Int , optDouble :: Double , optStrList :: [String] -- , optIntList :: [Int] } deriving Show run :: MyOption -> IO () run opts = print opts parser = MyOption <$> argument str (metavar "NAME") <*> strOption (short 's' <> long "string" <> help "string") <*> option (short 'x' <> long "string2" <> help "string2") <*> option (short 'i' <> long "int" <> help "int") <*> option (short 'd' <> long "double" <> help "double") <*> (many . strOption) (short 'S' <> long "strlist" <> help "string list") -- <*> (many . option) (short 'I' <> long "intlist" <> help "int list") main :: IO () main = execParser opts >>= run where opts = info parser idm
オプション引数の選択肢
TODO
オプション引数のパターン指定
TODO
ヘルプ表示をデザインする
TODO
その他の関数
このあたりを読めば他に使えそうな関数が見つかる
- github最新版 optparse-applicative/Builder.hs at master · pcapriotti/optparse-applicative · GitHub
- リリース最新版(0.9.1.1)
Options.Applicative.Builder
また、gitコマンドのようにサブコマンドを定義する方法も用意されていて便利そう
optparse-applicative/Cabal.hs at master · pcapriotti/optparse-applicative · GitHub
マニュアル
- Hackage: optparse-applicative: Utilities and combinators for parsing command line options
- pcapriotti/optparse-applicative · GitHub
自分の勉強のために書いてみましたが、公式マニュアルが綺麗にまとまっているのでそっちを読んだ方がいいですよ、というオチ。
Haskellのデバッグ方法(受け売り)
Twitterでボヤいていたらいろいろ教えて頂いたので今後のために残しておこうと思います。
.@objectxplosive @mathshun 純粋なコードで無理矢理 trace を書いても利用されなければ trace が起動しません。純粋なモナドでは、 !_ <- return $ trace (show a) a と書くことで、a の値を無理矢理使えます。
— 山本和彦 (@kazu_yamamoto) 2014, 8月 21
Haskell でのデバッグは、これぐらいを押さえておけば OK。http://t.co/rOUJxElZRJ http://t.co/KebuXqAQHn http://t.co/LYabGVhH7V テストに関してはこれ。 http://t.co/wiEQmpeziw
— 山本和彦 (@kazu_yamamoto) 2014, 8月 21
純粋なモナドでの
!_ <- return $ trace (show a) a
は知らなかったのではまったら使いたいですね。
「エンジニアの学び方─効率的に知識を得て,成果に結び付ける」まとめ
記事の要約・引用。一部自分の言葉で若干表現を変えたかも。
1. 効率的に学ぶには
知識には3つの軸がある
- 「広い視野」軸
- 学ぶべき対象を見つける。勉強会・ブログ記事・ニュース記事。
- 「深い理解」軸
- 学びの効率化と応用のために必要
- 「応用対象」軸
- 自分の理解を応用して成果を出すために必要。
学びには3つのフェーズがある
- 「知識収集」フェーズ
- 情報収集
- 「抽象化」フェーズ
- 知識からモデルを作る
- 「応用」フェーズ
- 成功すると、正しく理解できているという自信が生まれる
やる気不足
- やる気と成果は鶏と卵の関係。何かをやって成果を出すことで、次のやる気につながる。
- 最初の一歩を踏み出す事が重要。
2. 最初の一歩をどう踏み出すか
- やる気がでない場合、「勉強」を漠然とした大きなタスクとしてとらえていて、その大きさに圧倒されていることがよくある。
- 近いゴールを設定し、そこまで走ることを目標にすることが必要。
必要なところから学ぶ
前提条件
- 目標が明確化されている
- 達成したかどうかを判断できることが必要
- 目標が実現可能である
- 「たどり着けそう」であることが必要
- 大まかに全体像を把握している
大まかに全体像をつかむ
- 論文を最初から読んでも全然頭に入らない時、印刷し、25分間で章見出しとキーワードを赤ペンで囲う作業をした。
- 論文を理解するというあいまいな目標の代わりに、時間を区切って明確なゴールを作り、大まかな構造を頭に入れようとした。
片っ端から写経する
時間を区切ろう
- 本1冊を丸ごと写経するとどれくらいの時間がかかるでしょう。ゴールが見えないのでは、やる気がなくなります。そこで、時間を区切りましょう。たとえば「今から25分でできるとこまで写経するぞ」と目標を設定するのです。
- 25分やってみると、やる前よりもいろいろなことがわかるようになります。「知りたいこと」が生まれているかもしれません。全体像がなんとなくわかったかもしれません。
- もし何も得られた感じがしないのであれば、その本はあなたのニーズやレベルに合っていません。
3. どうやって深く理解するか
自分の知識が浅い気がする原因
- 「深い理解」方向の知識が足りない
- 「抽象化のフェーズ」に慣れていない
- 「情報収集」だけでは成果は出せません。得た知識を自分の中で「抽象化」してモデルにし、自分の問題に応用して、はじめて成果が出ます。
なぜ抽象化が必要?
- 抽象化によって応用範囲が広がります。抽象化は一般化・汎用化なのです。
どうやって抽象化するか
比較から学ぶ
- 同じ目的についての異なる著者の本を数冊、比較しながら読む。
歴史から学ぶ
抽象から学ぶ
- 応用できる知識かどうかのチェックポイント
- 自分の言葉で説明できるか?
- 自分の経験に基づいた具体例を挙げることができるか?
- 自分の目的を達成するためにその知識を使えるか?
作って学ぶ
試してみて結果が期待どおりかを検証する
- 本で読んだり勉強会で「なるほど、わかった」と思ったとします。
- 「わかった」は「仮説」であり、「検証」が必要です。
- 検証のためには、自分の理解をもとに行動をして、その結果が自分の期待どおりであるかをチェックする必要があります。
モデルが修正されるサイクル
作るものを高度にしすぎない
- 遠すぎる目標を立てない
- 作るものはプログラムとは限らず、「まだ知らない人、1日前の自分に説明するとしたら、どう説明するか?」を考えてブログ記事を書くのも「作る」です。
プログラミングは検証がしやすい
- 他人の手を借りずに検証のサイクルを回せる
- もしミュージシャンだったら、曲を作って演奏し、反響を見るまでにどれくらいの時間がかかることでしょう。
- プログラマは理解を深めるうえでとても恵まれた環境にいるわけです。これを活かさないのはもったいないことです。
3のまとめ
- モデルは正しくなくても、ないよりはマシ。
- モデルがあれば、答えを知らない問題に対しても自分なりの答えを出すことができるようになります。
4. 何を学ぶか、何を作るか
やれと言われたことをやる
他人の真似をする
「解決すべき問題」を見つける
完璧を求めない
RJagsでMCMCやってみた (緑本9章)
データ解析のための統計モデリング入門――一般化線形モデル・階層ベイズモデル・MCMC (確率と情報の科学)
- 作者: 久保拓弥
- 出版社/メーカー: 岩波書店
- 発売日: 2012/05/19
- メディア: 単行本
- 購入: 16人 クリック: 163回
- この商品を含むブログ (18件) を見る
9章の例題をやってみたメモ。
MacなのでWinBUGSは動かないからRJagsで。
インストール
Jags本体と、Rから使うためのRJagsを入れる必要がある。
Jags
Mac用のパッケージ(dmg)を入れた。
homebrewにもJagsはあるようだが、PATHがRJagsが想定しているデフォルトとは違うらしく面倒そう。特にこだわりが無ければパッケージを入れた方が楽。
RJags
普通に install.packages("rjags") するだけ
Rコード
使用するデータは書籍のサポートサイトからダウンロードできる。
同じ人の別記事にあるコードをちょっと変えただけで動いた。
library(rjags) # 本のサポートサイトからダウンロードしたデータ読み込み load("d.RData") # データの準備 list.data <- list( N = nrow(d), Y = d$y, X = d$x, Mean.X = mean(d$x) ) # 初期値の準備 inits <- list( beta1 = 0, beta2 = 0 ) # R内でのモデルの定義 m <- jags.model( file = "model.txt", data = list.data, inits = list(inits, inits, inits), n.chain = 3 ) # burn-in のためのカラまわしMCMC計算 update(m, 100) # MCMC計算で事後分布からサンプリング x <- coda.samples( m, c("beta1", "beta2"), thin = 3, n.iter = 1500, n.burnin = 100 ) plot(x)
- 本の例題(WinBUGS)と違うのは、RJags では update(m, 100) がburn-inのための空回しらしい点。n.burnin=100 でも指定できているようだからどちらかが要らないと思う。
BUGSのコード (model.txt)
model { for (i in 1:N) { Y[i] ~ dpois(lambda[i]); log(lambda[i]) <- beta1 + beta2 * (X[i] - Mean.X); } beta1 ~ dnorm(0, 1.0E-4); beta2 ~ dnorm(0, 1.0E-4); }
- Jagsではセミコロン必須らしい
ログの収集・可視化サービス
人に教えてもらった。知らないのがたくさんある。
とりあえず貼っとくだけ。あとで軽く調べて概要書いてみる。
2つの正規分布(pdf)の積はまた正規分布?
PRML2章 (2.139)~(2.143)の式変形がわからない。
http://en.wikipedia.org/wiki/Conjugate_prior
http://www.cs.ubc.ca/~murphyk/Papers/bayesGauss.pdf
この辺を見ても同じことが書いてあるが手計算しても合わない。
あとでまた戻ってくるようにメモっとく。
「社内の情報共有・情報発信」(Web+DB Vol.77) を読んだ
今さら感満載だけど読んだ。というか読みなおした。社内でちょっとやってみようと思うので記事の内容を簡単にまとめておく。
書く側のメリット
- 伝える技術を身につけられる
- 書くことにより伝える事もうまくなる
- 自分用メモ
読む側のメリット
- いろいろな人のいろいろな見方・考え方を知ることができる
- 誰がどんな仕事をしているのかがわかる
何を・何処に・誰が
情報の流通制御
- 情報は流通すればするほど情報過多になってしまう
- プッシュ型とプル型を使い分ける
- 本当に知る必要があるものはプッシュ型。メールなど。
- 必要と感じた時に能動的に受け取る情報はプル型
- 価値の高い情報の見せ方
- 「いいね」がたくさん集まったページをトップページに
まとめ
- 社内で情報共有しよう。社内ブログやWikiを活用しよう。
- 自分の知識や考えを伝えたり他人の知識を吸収できる。
- 組織に所属するワクワク感アップ。
- まずは1人でも書き始めてみる。
- 作者: 中川勝樹,山内沙瑛,舟崎健治,吉荒祐一,今井雄太,八木橋徹平,安川健太,近藤宇智朗,奥野幹也,天野祐介,賈成カイ,伊藤直也,住川裕岳,北川貴久,菅原一志,後藤秀宣,久森達郎,登尾徳誠,渡邊恵太,中島聡,A-Listers,小俣裕一,はまちや2,川添貴生,石本光司,舘野祐一,沖田邦夫,澤村正樹,卜部昌平,吉藤博記,片山暁雄,平山毅,WEB+DB PRESS編集部
- 出版社/メーカー: 技術評論社
- 発売日: 2013/10/24
- メディア: 大型本
- この商品を含むブログ (2件) を見る