モンテカルロシミュレーションを使用した近似


35

私は最近、モンテカルロシミュレーションを見ていて、π(長方形内の円、比例領域)などの定数を近似するために使用しています。

ただし、モンテカルロ積分を使用してe [オイラー数]の値を近似する対応する方法を考えることはできません。

これをどのように行うことができるかについての指針はありますか?


7
これを行うには、非常に多くの方法があります。これがそうであることは、Rコマンド2 + mean(exp(-lgamma(ceiling(1/runif(1e5))-1)))が何をするかを熟考することによって明らかになるかもしれません。(ログガンマ関数の気を使っている場合は、でそれを置き換える2 + mean(1/factorial(ceiling(1/runif(1e5))-2))。のみ加算、乗算、除算、および切り捨てを使用すると、オーバーフローの警告を無視して)大きな関心があるかもしれない何になり、効率的なシミュレーション:あなたは数を最小限に抑えることができますeを任意の精度で推定するために必要な計算手順は?
whuber

4
なんて楽しい質問でしょう!他の人の答えを読むのを楽しみにしています。あなたがこの質問に本当に注意を引くことができる1つの方法-おそらくもう半ダースの答え-は、whuberが示唆するように、質問を修正し、効率的な答えを求めることでしょう。これは、CVユーザーのキャットニップのようなものです。
Sycoraxは回復モニカ言う

1
@EngrStudent 幾何学的アナログが存在するかどうかわかりませんe。それは単にような自然な(しゃれを意図した)幾何学的量ではありませんπ
アクサカル

6
@Aksakal は、非常に幾何学的な量です。最も基本的なレベルでは、双曲線に関連する領域の表現に自然に現れます。少し高度なレベルでは、幾何学的な内容が明らかな三角関数を含むすべての周期関数と密接に関連しています。ここでの本当の課題は、eに関連する値を非常に簡単にシミュレートすることです!ee
whuber

2
@StatsStudent:自体は面白くない。しかしながら、等量の不偏推定量と、このリード場合EXP { X 0 F Y D G yは}これはMCMCアルゴリズムのために最も有用であろう。e
exp{0バツfydGy}
西安

回答:


34

この論文ではモンテカルロによるを推定するシンプルでエレガントな方法について説明します。この論文は、実際にeを教えることに関するものです。したがって、このアプローチはあなたの目標に完全に適合しているようです。このアイデアは、Gnedenkoによる確率論に関するロシアの人気教科書の演習に基づいています。p.183のex.22を参照ee

ように発生します。ここで、ξは次のように定義されたランダム変数です。これは、最小の数だNようΣ N iは= 1、R I > 1及びrは、私は上の一様分布からランダムな番号である[ 0 1 ]。美しいですね。E[ξ]=eξn=1nr>1r[01]

それは演習なので、ここに解決策(証明)を投稿するのがいいかどうかわかりません:)自分でそれを証明したい場合は、ここにヒントがあります:この章は「モーメント」と呼ばれ、あなたは正しい方向に。

自分で実装する場合は、これ以上読み進めないでください!

これは、モンテカルロシミュレーション用のシンプルなアルゴリズムです。合計が1を超えるまで、一様な乱数を描画し、次に別の乱数を描画します。描画される乱数の数が最初の試行です。あなたが得たとしましょう:

 0.0180
 0.4596
 0.7920

その後、最初のトライアルがレンダリングされます。3。これらのトライアルを続けると、平均してが得られることに気付くでしょう。e

MATLABコード、シミュレーション結果、およびヒストグラムが続きます。

N = 10000000;
n = N;
s = 0;
i = 0;
maxl = 0;
f = 0;
while n > 0
    s = s + rand;
    i = i + 1;
    if s > 1
        if i > maxl
            f(i) = 1;
            maxl = i;
        else
            f(i) = f(i) + 1;
        end
        i = 0;
        s = 0;
        n = n - 1;
    end
end

disp ((1:maxl)*f'/sum(f))
bar(f/sum(f))
grid on

f/sum(f)

結果とヒストグラム:

2.7183


ans =

  Columns 1 through 8

         0    0.5000    0.3332    0.1250    0.0334    0.0070    0.0012    0.0002

  Columns 9 through 11

    0.0000    0.0000    0.0000

ここに画像の説明を入力してください

更新:コードを更新して、RAMを使用しないように試行結果の配列を削除しました。PMF推定値も印刷しました。

更新2:これが私のExcelソリューションです。Excelにボタンを配置し、次のVBAマクロにリンクします。

Private Sub CommandButton1_Click()
n = Cells(1, 4).Value
Range("A:B").Value = ""
n = n
s = 0
i = 0
maxl = 0
Cells(1, 2).Value = "Frequency"
Cells(1, 1).Value = "n"
Cells(1, 3).Value = "# of trials"
Cells(2, 3).Value = "simulated e"
While n > 0
    s = s + Rnd()
    i = i + 1
    If s > 1 Then
        If i > maxl Then
            Cells(i, 1).Value = i
            Cells(i, 2).Value = 1
            maxl = i
        Else
            Cells(i, 1).Value = i
            Cells(i, 2).Value = Cells(i, 2).Value + 1
        End If
        i = 0
        s = 0
        n = n - 1
    End If
Wend


s = 0
For i = 2 To maxl
    s = s + Cells(i, 1) * Cells(i, 2)
Next


Cells(2, 4).Value = s / Cells(1, 4).Value

Rem bar (f / Sum(f))
Rem grid on

Rem f/sum(f)

End Sub

セルD1に1000などの試行回数を入力し、ボタンをクリックします。最初の実行後の画面は次のようになります。

ここに画像の説明を入力してください

更新3:Silverfishは私を別の方法に刺激しました。最初の方法ほどエレガントではありませんが、まだクールです。Sobolシーケンスを使用してnシンプレックスのボリュームを計算しました。

s = 2;
for i=2:10
    p=sobolset(i);
    N = 10000;
    X=net(p,N)';
    s = s + (sum(sum(X)<1)/N);
end
disp(s)

2.712800000000001

偶然にも彼は私が高校で読んだモンテカルロ法に関する最初のを書いた。私の意見では、この方法を紹介するのに最適です。

更新4:

コメントのSilverfishは、単純なExcel式の実装を提案しました。これは、合計100万個の乱数と185K回の試行の後、彼のアプローチで得られる一種の結果です。

ここに画像の説明を入力してください

明らかに、これはExcel VBA実装よりもはるかに遅いです。特に、ループ内のセル値を更新しないようにVBAコードを変更し、すべての統計が収集された後にのみそれを行う場合。

更新5

Xi'anのソリューション#3は密接に関連しています(または、スレッド内のjwgのコメントごとに何らかの意味で同じです)。ForsytheやGnedenkoの最初のアイデアを思いついたのは誰なのかわかりません。ロシア語のGnedenkoの元の1950版には、章に問題のセクションはありません。そのため、後のエディションでは、この問題を一見して見つけることができませんでした。多分それは後で追加されたか、テキストに埋もれたでしょう。

西安の答えでコメントしたように、フォーサイスのアプローチは別の興味深い分野にリンクされています:ランダム(IID)シーケンスでのピーク間の距離の分布(極値)です。たまたま平均距離は3です。Forsytheのアプローチのダウンシーケンスはボトムで終わるため、サンプリングを続行すると、あるポイントで別のボトムが得られ、次に別のボトムが得られます。


かっこいい!これが機能する理由を説明する段落を1つまたは2つ追加できますか?
Sycoraxは回復モニカ言う

7
(+1)素晴らしい!均一なシミュレーションのみに依存しているため、答えは最高点に値します。また、モンテカルロによる近似以外の近似は使用しません。Gnedenkoに接続することは、さらなる特典です。
西安

2
クール!ワンライナーとしてのMathematicaコードを次に示します:
Mean[Table[ Length[NestWhileList[(Random[]+#) &, Random[], #<1&]], {10^6}]]
wolfies

4
@wolfies R西安の回答に投稿したソリューションの次の直接翻訳は、20倍高速です。n=10^6; 1. / Mean[UnitStep[Differences[Sort[RandomReal[{0, n}, n + 1]]] - 1]]
whuber

1
私は「なぜ平均か?」を投稿しました。それ自体が質問としての質問e ; 私のスケッチソリューション(問題の「明白な」視覚化としてすぐに思い浮かんだもの)は、必ずしもロシアの学生が意図した方法ではないのではないかと思います。したがって、代替ソリューションは大歓迎です。
シルバーフィッシュ

19

Aksakalの答えを支持することをお勧めします。偏りがなく、単位ユニフォーム偏差を生成する方法のみに依存します。

私の答えは任意に正確にすることができますが、それでも真の値から偏っています。e

西安の答えは正しいですが、関数またはポアソンランダム偏差の生成方法への依存は、目的がeを近似することである場合、少し循環的であると思います。loge

ブートストラップによる推定e

代わりに、ブートストラップ手順を検討してください。多数のオブジェクトあり、サンプルサイズnに置き換えて描画されます。各ドローで、特定のオブジェクトiをドローしない確率は1 n 1であり、そのようなドローはn個あります。特定のオブジェクトがすべてのドローから除外される確率は、p = 1 1nni1n1np=(11n)n.

私たちはそれを知っていると仮定していますので、

exp(1)=limn(11n)n

ので、我々はまた書くことができる

exp(1)p^=i=1mIiBjm

つまり、推定値は、m個のブートストラップ複製B jから特定の観測が省略される確率を推定することによって求められます。pmBj多くのそのような反復全体を-つまり、オブジェクトの出現割合ブートストラップインチi

この近似には2つのエラーの原因があります。有限は常に結果が近似値であること、つまり推定値に偏りがあることを意味します。またn、これはシミュレーションであるため、真値の周りに変動します。p^

行うには十分にほとんどないとの学部や他の人が近づく可能性があるため、このアプローチはやや魅力的な私を見つけるe人が推定できたのと同じ静脈では、カードのデッキ、手の小さな石、またはその他の項目の杭を使用して使用コンパス、まっすぐなエッジ、砂粒。数学をコンピューターのような現代の便利さから離すことができるのはいいことだと思います。π

結果

さまざまな数のブートストラップレプリケーションに対していくつかのシミュレーションを実施しました。標準誤差は通常の間隔を使用して推定されます。

ブートストラップされるオブジェクトの数選択すると、モンテカルロ法ではpが推定され、pnのみに依存するため、結果の精度の絶対的な上限が設定されることに注意してください。nを不必要に大きく設定すると、eの「大まかな」近似が必要なだけか、モンテカルロによる分散によってバイアスが圧倒されるため、コンピューターが邪魔になります。これらの結果は、ためのもので、N = 10 3P - 1nppnnen=103第三の小数に正確です。p1e

選択というこれは、プロットを示し中での安定性のための直接的かつ深遠な影響をもたらすのp。青い破線はpを示し、赤い線はeを示します。予想通り、サンプルサイズを大きくすると、これまで以上に正確な推定値を生成したpをmp^pep^ここに画像の説明を入力してください

このために、非常に長いRスクリプトを作成しました。改善のための提案は、20ドルの請求書の裏に提出できます。

library(boot)
library(plotrix)
n <- 1e3

## if p_hat is estimated with 0 variance (in the limit of infinite bootstraps), then the best estimate we can come up with is biased by exactly this much:
approx <- 1/((1-1/n)^n)

dat <- c("A", rep("B", n-1))
indicator <- function(x, ndx)   xor("A"%in%x[ndx], TRUE) ## Because we want to count when "A" is *not* in the bootstrap sample

p_hat <- function(dat, m=1e3){
    foo <- boot(data=dat, statistic=indicator, R=m) 
    1/mean(foo$t)
} 

reps <- replicate(100, p_hat(dat))

boxplot(reps)
abline(h=exp(1),col="red")

p_mean <- NULL
p_var <- NULL
for(i in 1:10){
    reps <- replicate(2^i, p_hat(dat))
    p_mean[i] <- mean(reps)
    p_var[i] <- sd(reps)
}
plotCI(2^(1:10), p_mean, uiw=qnorm(0.975)*p_var/sqrt(2^(1:10)),xlab="m", log="x", ylab=expression(hat(p)), main=expression(paste("Monte Carlo Estimates of ", tilde(e))))
abline(h=approx, col='red')

4
+1それは非常に理にかなっています。書いたコードを共有できる可能性はありますか?
アントニ・パレラダ16

2
これは任意に正確にすることができたとしても、それだけでシミュレートしているため、最終的には満足できるものではない近似ではなく、電子そのものを。ee
whuber

1
確かに。別の内部で1つのレプリケートコールで終了するだけです。これは基本的には現在と同じです。
シコラックスは、モニカの復活を

1
@whuber私は実際に任意に正確な近似を任意に正確な近似の区別が表示されていない、および任意に正確な近似をする電子自分自身を。ee
-jwg

1
@jwg概念的に重要であることに加えて、近似に対する近似を実装するには、2つの近似のそれぞれの正確さを追跡する必要があるため、実際的にも重要です。しかし、両方の近似が許容できるほど良好な場合、全体的なアプローチは実際に問題ないことに同意する必要があります。
whuber

14

解決策1:

Pλ

Pバツ=k=λkkeλ
バツP1
P(X=0)=P(X=1)=e1
e1ポアソンシミュレーションによる。また、ポアソンシミュレーションは、指数分布ジェネレーターから導出できます(最も効率的な方法でない場合)。

U(i:n)U(i1:n)B(1,n)

P(n{U(i:n)U(i1:n)}1)=(11n)n
e1n

解決策2:

e

X1,X2iidN(0,1)
(X12+X22)χ12
E(1/2)
P(X12+X222)=1{1exp(2/2)}=e1
e(X1,X2)X12+X222πX12+X22<1

解決策3:

u1,u2,...un+1>unNeNe1expG(x)ee1

1/n!n

Forsytheのメソッドの迅速なR実装は、より大きなブロックを優先してユニフォームのシーケンスを正確にたどることを控えることであり、これにより並列処理が可能になります。

use=runif(n)
band=max(diff((1:(n-1))[diff(use)>0]))+1
bends=apply(apply((apply(matrix(use[1:((n%/%band)*band)],nrow=band),
2,diff)<0),2,cumprod),2,sum)

12
e

5
If I call R rpoiss() generator, I can pretend I do not know e. More seriously, you can generate exponential variates E(1) [using a log function rather than e] until the sum exceeds 1 and the resulting number minus one is a Poisson P(1).
Xi'an

5
Computing log is tantamount to computing exp, since they are inverses. You can avoid computing any such function in various ways. Here is one solution based on your first answer: n <- 1e5; 1/mean(n*diff(sort(runif(n+1))) > 1) It uses only elementary arithmetic.
whuber

3
I believe that Forsythe's method is the same as Gnedenko's. Choosing a uniform xn such that nxi is less than 1 is the same as choosing xn smaller than 1n1xi, and if we are successful, 1nxi is conditionally uniformly distributed between 1n1xi and 0.
jwg

3
I wasn't aware of Forsythe's approach. However, it's linked to something else very interesting. If instead of stopping at n+1 you keep sampling, then the expectation of the distance from n to the next bottom is exactly 3.
Aksakal

7

解決策ではありません...コメントボックスには長すぎる簡単なコメントです。

アクサカル

Aksakalは、それらの和が1に超えてしまうような、我々は注意する必要があり、標準的な制服図面の予想数を計算するソリューションを投稿Mathematicaを私の最初の処方でした、:

mrM := NestWhileList[(Random[] + #) &, Random[], #<1 &]

Mean[Table[Length[mrM], {10^6}]] 

編集:これで簡単にプレイしただけで、次のコード(同じ方法-Mmaでも-ちょうど異なるコード)は約10倍高速です:

Mean[Table[Module[{u=Random[], t=1},  While[u<1, u=Random[]+u; t++]; t] , {10^6}]]

西安/フーバー

Whuberは、Xianのソリューション1をシミュレートするための高速でクールなコードを提案しています。

Rバージョン: n <- 1e5; 1/mean(n*diff(sort(runif(n+1))) > 1)

MMAバージョン: n=10^6; 1. / Mean[UnitStep[Differences[Sort[RandomReal[{0, n}, n + 1]]] - 1]]

彼は、最初のコードの20倍(または上の新しいコードの約2倍)速いことに気付きました。

楽しみのために、両方のアプローチが(統計的な意味で)同じくらい効率的かどうかを確認するのは面白いと思いました。そのために、以下を使用してeの2000の推定値を生成しました。

  • アクサカルの方法:dataA
  • Xian's method 1 using whuber code: dataB

... both in Mathematica. The following diagram contrasts a nonparametric kernel density estimate of the resulting dataA and dataB data sets.

enter image description here

So, while whuber's code (red curve) is about twice as fast, the method does not appear to be as 'reliable'.


A vertical line at the location of the true value would vastly improve this image.
Sycorax says Reinstate Monica

1
とても興味深い観察です、ありがとう。半値幅はシミュレーションのサイズに応じて二次関数でスケーリングされ、西安の方法の半値幅はAksakalの約2倍なので、4倍の反復を実行すると等しく正確になります。各反復でどれだけの労力が必要かという問題は残ります。西安の方法の1回の反復で労力が4分の1未満であれば、その方法はさらに効率的です。
whuber

1
両方の方法で必要な確率変数の実現数を比較すると、 n
whuber

1
@whuberは次のように書きました:running four times as many iterations will make them equally accurate///// .....これを簡単に試してみました:Xianの方法1で使用されるサンプルポイントの数を106 6 x 106 (つまり、ポイント数の6倍)は、Aksaksalと同様の曲線を生成します。
wolfies

1
コードはよくできています。それを改善するのは難しいでしょう。
whuber

2

途方もない量のサンプルを必要とする方法

まず、正規分布からサンプリングできる必要があります。関数の使用を除外すると仮定しますfバツ=eバツ、またはその関数から派生したテーブルを検索すると、CLTを介して正規分布から近似サンプルを生成できます。たとえば、均一(0,1)分布からサンプリングできる場合、バツ¯12n˙N01。whuberが指摘したように、最終的な見積もりアプローチをe サンプルサイズが近づくにつれて 、使用される均一なサンプルの数がアプローチであることが必要です。 サンプルサイズが無限に近づくにつれて。

十分な大きさのサンプルを使用して正規分布からサンプリングできる場合、密度の一貫した推定値を取得できます N01。これは、ヒストグラムまたはカーネルスムーザーを使用して実行できます(ただし、ガウスカーネルを使用して、eバツルール!)。密度の推定値を一致させるには、df(ヒストグラムのビンの数、より滑らかにするためのウィンドウの逆数)を無限大に近付ける必要がありますが、サンプルサイズよりも遅くなります。

したがって、多くの計算能力を使用して、の密度を近似することができます N01、つまり ϕ^バツ。以来ϕ2=2π1/2e1、あなたの見積もり e=ϕ^22π

あなたが完全にナッツに行きたいなら、あなたは推定することさえできます 2 そして 2π using the methods you discussed earlier.

Method requiring very few samples, but causing an ungodly amount of numerical error

A completely silly, but very efficient, answer based on a comment I made:

Let Xuniform(1,1). Define Yn=|(x¯)n|. Define e^=(1Yn)1/Yn.

This will converge very fast, but also run into extreme numerical error.

whuber pointed out that this uses the power function, which typically calls the exp function. This could be sidestepped by discretizing Yn, such that 1/Yn is an integer and the power could be replaced with repeated multiplication. It would be required that as n, the discretizing of Yn would get finer and finer,and the discretization would have to exclude Yn=0. With this, the estimator theoretically (i.e. the world in which numeric error does not exist) would converge to e, and quite fast!


2
最終的にこれらの値が正規分布していないことがわかるため、CLTアプローチは満足のいくものではありません。しかし、必要なく正常な変量を生成する方法はたくさんありますeまたは対数:Box-Mullerメソッドは1です。ただし、これにはトリガー関数が必要であり、(基本的なレベルでは)指数関数と同じです。
whuber

1
@whuber:必要なログ変換が本の指数関数に直接すぎたため、Box-Mullerは使用しませんでした。私 cosとsinを再帰的に許可していましたが、それはちょっとした複雑な分析を忘れていたからです。
クリフAB

1
ただし、生成された正規近似はこのアイデアの弱点であるという考えで議論します。密度推定はさらに弱いです!次の2つのパラメーターを持つという考え方を考えることができます。n1、「近似法線」で使用される番号制服 n2 使用される近似法線の数は、密度を推定します ϕ2。両方としてn1 そして n2 アプローチ 、推定量が近づく e。実際、収束率は次のようにはるかに制限されると確信しています。n2 より n1; ノンパラメトリック密度は収束速度が遅い!
クリフAB

2

かなり遅いですが、ここに別の方法があります。私は効率性を主張しませんが、完全性の精神でこの代替案を提供します。

Contra Xi'anの答え、この質問の目的のために、次のシーケンスを生成して使用できると仮定します。n 一様な擬似ランダム変数 うん1うんnIID U01 そして、あなたは推定する必要があります e 基本的な算術演算を使用するいくつかの方法(つまり、対数関数または指数関数、またはこれらの関数を使用する分布は使用できません)。 現在の方法は、一様なランダム変数を含む単純な結果によって動機付けられています。

Eうん1/eうん=1/e1dあなたはあなたは=1。

推定 eこの結果を使用して、最初にサンプル値を降順に並べ、順序統計を取得しますあなたは1あなたはn そして、部分和を定義します:

Snk1n=1k1あなたはすべてのために k=1n

今、みましょう m{k|Sk1} そして、推定 1/e順序付けられた均一変数の補間による。これにより、e によって与えられた:

e^2あなたはm+あなたはm+1

この方法には、若干のバイアスがあります(カットオフポイントの線形補間により、 1/e)しかし、それは一貫した推定量です e。このメソッドはかなり簡単に実装できますが、値のソートが必要です。これは、以下の決定論的計算よりも計算集約的です。e。このメソッドは値のソートを伴うため、時間がかかります。

Rでの実装: メソッドをR使用runifして実装すると、均一な値を生成できます。コードは次のとおりです。

EST_EULER <- function(n) { U <- sort(runif(n), decreasing = TRUE);
                           S <- cumsum(1/U)/n;
                           m <- min(which(S >= 1));
                           2/(U[m-1]+U[m]); }

このコードを実装すると、次の真の値に収束します。 e、しかし決定論的方法と比較すると非常に遅い。

set.seed(1234);

EST_EULER(10^3);
[1] 2.715426

EST_EULER(10^4);
[1] 2.678373

EST_EULER(10^5);
[1] 2.722868

EST_EULER(10^6); 
[1] 2.722207

EST_EULER(10^7);
[1] 2.718775

EST_EULER(10^8);
[1] 2.718434

> exp(1)
[1] 2.718282

私は、指数または対数を含む変換を利用する方法を避けたいと考えています。定義で指数関数を使用する密度を使用できる場合、導出することが可能ですe これらから、代数的に密度呼び出しを使用します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.