Haskell でProbabilistic programming その3

  • こちらの記事HaskellをベースにしたProbabilistic programmingについてメモをした
  • このペイパーを読みつつHaskellとその中でのMonadの使用方法について勉強した
  • こちらこちらに、それが提供するhaskell パッケージの使い方について書いた
  • そのパッケージでは、benchmarkがサンプルとしてついており、benchmarkを実行するといくつかの使用例の入出力を確認できる
  • それを使って、パッケージ内のソースを読んで勉強してみる
  • Linear Gaussian State Space モデル LGSS.hs
    • 何をやっているかといえば、カルマンフィルタを使ったLinear Gaussian State Spaceモデルでの性能評価(のはず)
    • したがって、何か乱雑項込みの動きが生成され、なにかしらの評価をしているはずで、それをある条件(もしくは複数の条件)で何度も試行しているのだろうとあたりをつけてコードを読むことにする
    • main 関数のdoでやっていることを確認する
      • 条件分岐はあるが
sampleIO $ lgssBenchmark cachePath 50 100 (map (2^) [1..10])
      • この1行がやっていることの全体を表している(はず)
      • lgssBenchmarkという関数が、cachePath,50,100, (map (2^n) [1..10]) という4引数をとってベンチマーク実験を規定している
      • 50は、観測点の数、100はベンチマーク評価のために行う繰り返し実行回数、map (2^n) [1..10]は、[2,4,8,...]のことで、推定実験条件を規定している
      • lgssBenchmarkという関数は、LGSS.hs内に定義されており、SamplerIO() を返す
      • SampleIOはこのSamplerIO()を受け取り、擬似乱数生成オブジェクトとともにモンテカルロ試行をしてその結果を出力可能にする
      • lgssBenchmarkの中身を見ると、do記法で書かれているように、逐次処理をするが、do記法にかかれているのは、liftIOする部分と、do内部で使用するためにlet記法で定義したいくつかの変数・関数からできている
      • 主要なLiftIOは後半の"points"をファイルに書き出す部分
      • したがってこの"points"が大事な生成物
      • "points"はlet記法で書かれており、
let points = zip (map fromIntegral ns) (transpose scores)
      • これは、実験条件nsごとに出るscoresとnsの値をzipにしたもの
      • よってnsの値ごとに出る"scores"が大事
      • "scores"はdo記法を使って生成する値のnRuns (100) 回の同一条件試行の分の値の集まりらしい
      • "scores"を定める、do記法では、ysとrefという2つのベクトルから出す2つの値の差の絶対値であるとわかる
      • "ys","ref"は、それぞれsynthesizeData,kalmanという関数の生成物で、どちらも同じ引数paramを用いて作られている
      • ただし、"ref"の生成には"ys"が使われている
    • synthesizeDataは
      • 初期x値を正規乱数で発生させ、その後、一次線形運動に正規乱雑項が付加された値を、時刻ごとのx値とし、実際の観測値はそれにさらに正規乱雑誤差を加えてysとして得る
      • 今、観測データから知りたいのは、一次線形運動を定めたパラメタとそこからのxとしてのずれと観察としての誤差とを規定する正規分布パラメタである