Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9747

棄却サンプリング

$
0
0

棄却サンプリングは実装も簡単だし使い勝手も悪くないし、もっと流行ってもいいと思うの(そもそも最近はサンプラーなんて実装しないような気もするが・・・)

棄却サンプリングのアルゴリズム

アルゴリズム

必要な材料は以下の通り。
- $f(x)$:サンプリングをしたい確率密度関数。
- $g(x)$:提案分布。こちらからサンプリングした結果を使うので、簡単にサンプリングできる関数である必要がある。
- $M$: 定数。ただし両確率密度関数の定義域全体で $f(x)\le Mg(x)$ を満たす。

以下のようにサンプリングを行う。

  1. $x \sim g(x)$
  2. $u \sim U(0, 1)$
  3. $r = f(x) / Mg(x) $
  4. $u \le r$ ならサンプル $x$ を受領。そうでないなら棄却。

ここで $U(0, 1)$ は $[0, 1]$ の一様分布。

なぜワークするか

アルゴリズムでサンプリングされる対象について、特性関数を評価すればよい。

\begin{align}
\int dx e^{itx} \int_0^1 du \theta\left(\frac{f(x)}{Mg(x)} - u)\right) g(x) &= \int dx e^{itx} \int_0^{\frac{f(x)}{Mg(x)}} du g(x)\\
&= \int dx e^{itx} \frac{f(x)}{Mg(x)} g(x)\\
&= \int dx e^{itx} \frac{f(x)}{M}\\
&\propto \int dx e^{itx} f(x)=E_X^F\left[e^{itx}\right]
\end{align}

この通り、サンプリングする対象について特性関数を評価すれば $f(x)$ の特性関数に一致する。

実装

コード

publicIEnumerable<TargetDistributionDataType>GetSamples(RejectionSamplerConfig<TargetDistributionDataType,TargetDistributionParameter,ProposalDistributionParameter>samplerConfig){returnEnumerable.Range(0,samplerConfig.Count).Select(i=>{varuniformParam=newProbability.Parameter.Uniform(0,1);varuniform=newProbability.Distribution.Uniform();vartargetProbabilityDensityFunction=samplerConfig.TargetDistribution.GetProbabilityDensityFunction(samplerConfig.TargetDistParameter);varproposalProbabilityDensityFunction=samplerConfig.ProposalDistribution.GetProbabilityDensityFunction(samplerConfig.ProposalDistParameter);while(true){varsampleFromProposal=samplerConfig.ProposalDistribution.GetSamples(samplerConfig.ProposalDistParameter,1).First();varacceptProbability=targetProbabilityDensityFunction(sampleFromProposal)/(proposalProbabilityDensityFunction(sampleFromProposal)*samplerConfig.M);varsampleFromUniform=uniform.GetSamples(uniformParam,1).First();if(sampleFromUniform<acceptProbability)returnsampleFromProposal;}});}

数値実験

以下では平均値2の指数分布のサンプリングを、提案分布を平均値4の指数分布、 $M=2$ とした棄却サンプリングで行っている。乱数によるが、手元で回した結果は平均値2.0049、標準偏差1.9695が得られた。

staticvoidMain(string[]args){Console.WriteLine("Hello World!");varsize=10000;varrejectionSamplerConfig=newProbability.SamplerConfig.RejectionSamplerConfig<double,Probability.Parameter.Exponential,Probability.Parameter.Exponential>(newProbability.Distribution.Exponential(),newProbability.Parameter.Exponential(1),newProbability.Distribution.Exponential(),newProbability.Parameter.Exponential(2),size,2);varsampler=newProbability.Sampler.RejectionSampler<double,Probability.Parameter.Exponential,Probability.Parameter.Exponential>();varsampleFromSampler=sampler.GetSamples(rejectionSamplerConfig);Console.WriteLine(sampleFromSampler.Average());Console.WriteLine(sampleFromSampler.StadardDeviation());}

参考文献


Viewing all articles
Browse latest Browse all 9747

Trending Articles