R言語でデータ拡大(Data Augmentation)サンプリング法を実装してみた
データ拡大 (Data Augmentation)サンプリング法ってのをお勉強したのでそのまとめ。
概要&アルゴリズム
説明は2つ目の参考LINKに書いてある方法でずばり良いと思う。
要するに
分布から直にサンプリングしたいんだけど、それが難しいという状況の時、適当なダミー変数的なものをかませて
となるようなを(適当に・何とかして)構築。
このに従う乱数をギブスサンプラー
- からを取得
- からを取得
を何度も繰り返し、系列データを生成する事が出来たならば、
ここで得られたの系列はまさに望むからの分布となっている
というもの。
元のが作る空間に加えてが作る空間も考えているわけなのでデータ"拡大"サンプリングということですかね。
元のからサンプルできない状況でも条件付のからサンプリングできればいいってのがアイディアの部分なのだろうか。
1つ前のエントリ
R言語でスライスサンプリング(Slice Sampling)を実装してみた - My Life as a Mock Quant
で書いたスライスサンプリングよりも、条件付分布をサンプリング対象の分布ごとに手計算してやらなければならないという意味で汎用性が落ちるように思える。
ちなみに↓の本では10章をデータ拡大 (Data Augmentation)の話に充てている。
R言語での実装&動かす
とまぁ、つらつら書いてきたけど、自分の中では「この手法、要するにギブスサンプラーだろ」と思ってしまっているので、あまり新規性を感じない。
というわけで、と一番簡単に生成・結果チェック出来るであろう正規分布としてやってみる*1。
この時、同時分布として
を考えると、それぞれの条件付分布は
となり、の周辺分布は
となるので、データ拡大アルゴリズムを適用してサンプリングを行えばに従うようなが手に入る。
#f(x|y)とf(y|x)。この例だとたまたま同じ関数でいける rand.conditional <- function(val){1/sqrt(2)*rnorm(1)+val/sqrt(2)} #Data Augmentationアルゴリズムで生成(要するにギブスサンプラー) SIZE <- 10^5 points <- numeric(SIZE) for(i in 1:SIZE) { y <- rand.conditional(points[i]) points[i+1] <- rand.conditional(y) } #yは完全に無視してx(points)のみの分布をチェック hist(points, SIZE^0.5, freq=FALSE) x<-seq(-3 ,3 ,0.01) lines(x, dnorm(x), col=2, lwd=3)
参考
- "The data augmentation algorithm: Theory and methodology" in Handbook of Markov Chain Monte Carlo
- F# でデータ拡大サンプリング - 捨てられたブログ