方法が分かったので、メモしておきます。
シードを変更しないと、毎回同じ乱数が生成されてしまうので

シードの変更にはsetall(long iseed1,long iseed2)という関数を使います。
これですべての乱数発生パラメータに引数の値を設定するのだとか。
(iseed1とiseed2の違いについては、マニュアルには載っていませんでした)
他の関数でvoid setsd(long iseed1,long iseed2)というのもあるのですが、
この関数をコールするにはその前にsetall()を実行していないといけないらしいので、
setall()のみをつかえばいいかな・・・と。
実際には↓こんな感じで使っています。
これだと、実行するたびに乱数が異なります
(1秒間に何回もプログラムを起動した場合はおなじですけど)
「Bayesian Data Analysis(Second Edition)」(Andrew Gelman et al.)から逆カイ2乗分布についてメモ。
どこが違うのかというと、昨日のは候補の発生は現在の点+αで行っていましたが、
今日のは候補の発生は現在の点とは独立して行います。
使用する例は昨日のと同じものを使います。ただし候補を発生させる提案分布は以下のものを使います。
【メトロポリスヘイスティングス法(independence chainアルゴリズム)の手順】
この手順を基にして作ったプログラムと結果が以下になります。
ちなみにaccept率は77.5%でした。割と高いっすね。
その中でもrandom walk chain(酔歩連鎖)についてです。
だんだんめんどくさくなってきたので、今日はいきなり例を出していきます。
【メトロポリスヘイスティングス法(random walk chainアルゴリズム)の手順】
この手法の長所はアルゴリズムの構築が簡単な点ですが、短所は提案分布のチューニングが
必要な点です。現在の点と候補の距離(分散などのちらばり)が小さくなるように提案分布を設定すると
候補のaccept率は上がりますが状態空間の一部ばかりをサンプリングしてしまいます。
逆にばらつきが大きいとaccept率が低下してサンプリング効率は悪くなってしまいます。
この手法のプログラムは以下のようになります↓
このプログラムで提案密度のパラメータを0.2としたときのサンプリングの様子をプロットしてみました↓
このときの事後平均の結果は5.06で、accept率は71.2%でした。
今度はパラメータを0.001に変更してサンプリングしてみました↓
このときのaccept率は83.4%と高くなりましたが、真の値にたどり着くまでのサンプリングの動きが緩やか
になっています。
今度はパラメータを4.0にしてサンプリングしてみました↓
このときのaccept率は70.4%で、サンプリング幅が大きくなっています。
教科書などでは「ギブスサンプラー」と書かれている方が多いのですが、
私はGibbs Samplingで習ったのでここではこれで通します。
【Gibbs Samplingの手順】

事後平均の結果は平均が4.965364で分散が1.037286で、そこそこ正確に推定することができました。
したのプロットは上が平均のサンプリングの様子で下が分散のサンプリングの様子です。
学部生の頃はまさか自分がMCMC法をこんな勉強することになるとは夢にも思わなかったので
(なんかよくわからんけど文献に時々出てくるスゴイmethodみたいな認識でした)、
なんだかちょっと感慨深けです

今日はA-R(acceptance-rejection)法をやります。自分がある密度関数
から乱数を生成したいけど、分布関数が非常に複雑で乱数発生が困難な時、正規分布などの簡単な確率分布の密度関数
を使って目的の確率分布の乱数を生成する方法です。【A-R法の手順】
1.確率密度関数
から乱数
を生成する。2.区間(0,1)から乱数
を生成する。3.乱数
のaccept/reject判定基準として以下のrを計算する。
ここでcは
であるすべてのxについて
が成り立つような正の定数である。
4.
ならば
はrejectされ、それ以外ならばacceptされる。この手法の長所としては
の基準化定数を求めなくて済むこと(メトロポリス法も求めなくてよい)だそうですが、短所としては
に近似する
を見つけなくてはいけないことと、cの値を大きくしすぎるとサンプリング効率が悪くなってしまうことです。そう考えると、ちょっとめんどーな方法と言えなくもないなー
以下のソースは自由度1のカイ2乗分布を用いてガンマ分布(2,1)からサンプリングを発生させています。cの値は3とし、各確率密度関数は以下の通りになります。

以下のグラフは上記A-R法で得られたガンマ分布(2,1)の乱数のプロットです。
ちゃんとガンマ分布(2,1)に従っていることが分かります( ´_ゝ`)

次のグラフはA-R法で得られたガンマ分布(2,1)の乱数とカイ2乗分布のプロットです。
これを見るとxが0.0~1.0あたりのとき2つの分布の近似が良くないためにサンプリング効率が悪くなっています。ちなみに上記プログラムでは10000回反復のうち、acceptされたのは 約3300回でした。
変数が従う分布は前回と同じで、
には以下のような制約が存在し、
その範囲外での確率は0とします。このとき、メトロポリス法は以下のような手順で実行します。
(ちなみに1.~3.までは制約なしのメトロポリスと同じです)
【2変量正規分布の制約ありのメトロポリス法の手順】
1.
の任意の初期値を設定する。2.
を原点対照の確率密度
から発生させる。3.「候補」を以下のように設定する。

4.
ならば候補はrejectされ、手順2.に進む。acceptされる場合は5.に進む。5.候補の状態と現在の状態の確率の比を計算する。

6.
の一様乱数を生成する。
ならば候補の値を現在の値とし、それ以外はrejectする。7.2.~6.を繰り返す。
手順4.はとりあえず候補を選んで、範囲外ならrejectするというアルゴリズムが正しい。範囲外にならないように候補を選ぶといった方法を使ってはいけない。上記メトロポリス法の例からサンプルの様子を出力してみました↓
上記グラフで、点線部分は
です。これを見ると範囲内にちゃんとサンプリングされていることが分かります。以下のグラフは平均値の動く様子です。平均値は1点に収束されていくのが分かります。
2変量正規分布

から各確率変数をメトロポリス法によってサンプリングします。ここで
は正規化定数ですが、候補と現在の確率の比を計算するときに相殺されるので、ここでは計算しません。【2変量正規分布のメトロポリス法の手順】
1.
の任意の初期値を設定する。2.
を原点対称の確率密度
から発生させる。3.「候補」を以下のように設定する。

4.「候補」の状態と現在の状態の確率の比を計算する。

5.
の一様乱数を生成する。
ならば、「候補」の値を現在の値とし、それ以外は何もしない。6.2.~5.を繰り返す。
ここで確率密度
はいろいろな方法がありますが、私は
を適当な「ステップ幅」として、平均0、分散
の正規分布から
を独立に選ぶという方法をとりました。上記のメトロポリス法の例を使って、サンプリングを行うプログラムを作成してみました。
ちなみに、
の初期値は(3.0,9.0)とし、
は0.8としました。また、
は0.8としました。
サンプリング結果をプロットすると、以下のようになりました。

昨日はマルコフ連鎖モンテカルロ法の1つであるメトロポリス法を勉強しました。
今回の教科書は計算統計Ⅱです。以前にGibbsSamplingもこれで勉強したのですが、なかなか分かりやすいと思います。
そもそもマルコフ連鎖モンテカルロ法とは複雑な分布に従う確率変数についてパラメータ(期待値や
分散など)が不明なとき、データが与えられた時のパラメータのもとでのデータの確率とパラメータの
事前分布を使って、パラメータの条件付き事後確率からサンプリングしたデータからパラメータを
求める方法です。
要はちょっとずつ事後分布を変更しながら何回もサンプリングを行い、そのサンプリングから
パラメータを求めるという方法です。
メトロポリス法については3つの離散確率変数
がそれぞれ1もしくは-1をとるときを例として説明してありました。
【メトロポリス法の手順】
1.3つの離散確率変数
における分布が
のとき、変数のどれか1つを選ぶ。
2.選んだ変数
の値を
で置き換えて、他の2つの変数をそのまました状態を次のサンプリングの「候補」とする。
ex. 状態
で
を選んだとすると、候補は
となる。3.「候補」の確率と現在の状態の確率の比rを求める。

4.
となる一様乱数Rを生成する。5.
なら「候補」を次の状態に採用する(accept)。
なら現在の状態をそのまま次の状態とする(reject)。
この方法では「候補」の確率が現在より大きい場合は候補は必ず採用される。また、「候補」の確率が現在より小さい場合は確率rで候補は採用される。
このメトロポリス法を十分に繰り返した後に得られるサンプルを使って
の平均や分散を計算する手法をマルコフ連鎖モンテカルロ法という。
メトロポリス法によって得られたサンプル間には相関が存在するため、分散や精度の高いパラメータの計算を行う場合は、サンプル相関の補正が必要となる。また、十分に間隔を開けて収集したサンプルは
ほぼ独立のサンプルとみなすことができるので、例えば採取したサンプルのうち10000回に1個ずつを
パラメータの推定に用いれば相関による影響はないとみなすことができる。
上記のような間隔をあけてサンプルを収集する場合は、rejectされた場合も1回とカウントする。また、このように収集したサンプルの繰り返し数をモンテカルロ・ステップ(MCS)と呼ぶ。上記のメトロポリス法の例を使って、
の平均を求めるプログラムを作成してみました↓
これでθが0.2の場合と0.8の場合の
の平均値の収束具合を比較してみました。上段が0.2で下段が0.8です。これを見るとθが大きくなると収束が遅くなることがわかります。
正規乱数を生成するプログラムをC言語で書きました。
引数のチェックなどは省略してあります。
ちなみに、参考にしたサイトはここ。C++ですが、かなり丁寧に書いてあって、ものすごく参考になりました
あと、ここにも載っていました。こっちはCです。
#include
#include
#include
const int PI = 3.141592653589793
static int BOX_MULLER = 0;
static double X_NORMAL_RAN = 0.0;
static double Y_NORMAL_RAN = 0.0;
double normalRandom( double mean, double var )
{
int i;
double u1 = 0.0;
double u2 = 0.0;
if( BOX_MULLER == 0 ) {
BOX_MULLER = 1;
u1 = (double)rand() / (double)RAND_MAX;
while( u1 == 0.0 ) {
u1 = (double)rand() / (double)RAND_MAX;
}
u2 = (double)rand() / (double)RAND_MAX;
X_NORMAL_RAN = sqrt( -2.0 * log( u1 ) ) * cos( 2.0 * PI * u2 );
Y_NORMAL_RAN = sqrt( -2.0 * log( u1 ) ) * sin( 2.0 * PI * u2 );
return X_NORMAL_RAN * sqrt( var ) + mean;
} else {
BOX_MULLER = 0;
return Y=NORMAL_RAN * sqrt( var ) + mean;
}
}