バイアスされたコインを使用して、ベルヌーイ変数を確率シミュレートします


9

誰かがどのようにシミュレートするために、私に教えてもらえます、(あなたが必要な回数だけ)コインを使用しては、投げると?BNPH=PBernoulli(ab)a,bNP(H)=p

拒否のサンプリングを使用することを考えていましたが、それを明確にすることはできませんでした。


1
これは、コースまたは教科書からの質問ですか?その場合は、[self-study]タグを追加してWikiをお読みください。質問の最後に助けを求める必要がないことに注意してください。ここに投稿するすべての人が助けを望んでいることはわかっています。
Silverfish

1
@Glen_bの優れた投稿がどこかに(どこにあるかは覚えていませんが)、「確率バイアスコイン」のようなものがない理由はありますが、これはあなたの質問の周辺の問題にすぎません。p
Silverfish

2
@dsaxton質問には「必要な数だけ」と書かれています。確率1で有限ですが、制限はありません(固定数のトスを超える可能性があります)が、これに基づいて反対することは、「頭が出るまで公正なコインを投げる」と言ったようなものであり、ジオメトリを生成する方法としては実行できません。 (乱数。12
Glen_b -Reinstateモニカ

1
@AbracaDabraこれはクラスの練習ですか?そうでない場合、どのように発生しますか?
Glen_b-2016

1
@Glen_b:私のクラスからの演習ではありません。それはこの一連の考えの中で私に発生しました...:古典的な確率に従って、公平なコインを取り、トスの数を増やすと、比率が半分に収束します。したがって、偏ったものにも当てはまるはずです...これは、コインを特定の数に収束させることを意味し、をその数にする必要があります。さて、数字を生成したいのですが、と別の数字(既知または不明)のコインがあると思いました。 PHPH#Heads#tailsP(H)P(H)
AbracaDabra 2016

回答:


8

数え切れないほど多くの解決策があるので、効率的な解決策を見つけましょう。

この背後にあるアイデアは、ベルヌーイ変数を実装する標準的な方法から始まります。一様確率変数をパラメーターと比較します。場合、リターン。それ以外の場合は返し。a / b U < a / b 1 0Ua/bU<a/b10

-coinを一様乱数ジェネレータとして使用できますp。任意の間隔内で数値均一に生成するには、コインを裏返します。頭になったら、間隔の最初の部分に均一な値再帰的に生成します。末尾の場合、間隔の最後の部分からを再帰的に生成します。ある時点で、ターゲット間隔が非常に小さくなり、そこから数値をどのように選択するかは重要ではありません。それが再帰の開始方法です。誘導によって容易に証明されるように、この手順が(任意の精度まで)均一な変量を生成することは明らかです。[ x y X p X 1 pU[x,y)XpX1p

このアイデアは効率的ではありませんが、効率的な方法につながります。 各段階で、ある与えられた間隔から数値を描画するので、まずそれを描画する必要があるかどうかを最初に確認しませんか?ターゲット値がこの間隔の外にある場合、ランダム値とターゲットの比較結果はすでにわかっています。 したがって、このアルゴリズムは急速に終了する傾向があります。(これは、質問で要求された拒否サンプリング手順として解釈される可能性があります。)[x,y)

このアルゴリズムをさらに最適化できます。 どの段階でも、実際に使用できるコインは2つあります。コインのラベルを変更することで、偶然にコインにすることができます。したがって、事前計算として、再ラベル付けにより、終了に必要なフリップの予想される回数が少なくなる方を再帰的に選択できます。 (この計算は高価なステップになる可能性があります。)1p

たとえば、ベルヌーイ変数を直接エミュレートするためにコインを使用することは非効率的です。平均でほぼ10回のフリップが必要です。しかし、コインを使用する場合、2回のフリップで確実に実行され、予想されるフリップの数はます。0.01 p = 1 0.0 = 0.1 1.2p=0.9(0.01)p=10.0=0.11.2

詳細はこちら。

与えられたハーフオープン間隔を間隔に分割しますI=[x,y)

[x,y)=[x,x+(yx)p)[x+(yx)p,y)=s(I,H)s(I,T).

これは、半開区間で動作する2つの変換およびを定義します。s(,H)s(,T)

用語の問題として、が実数のセットである場合、式をI

t<I

意味では下行きである:すべてのための。同様に、意味上部にバインドされている。tIt<xxIt>ItI

書きます。(実際、が有理数ではなく実数である場合、違いはありません。必要なのはのみです。)a/b=tt0t1

次に、目的のベルヌーイパラメーターを使用して変量を生成するアルゴリズムを示します。Z

  1. セットと。n=0In=I0=[0,1)

  2. while {コインをを生成します。セット 増分します。}(tIn)Xn+1In+1=S(In,Xn+1).n

  3. もし次にセット。それ以外の場合は、設定し。t>In+1Z=1Z=0


実装

説明のためにR、関数としてのアルゴリズムの実装を次に示しますdraw。その引数は、ターゲット値と間隔、最初はです。実装する補助関数を使用します。必要はありませんが、コインのトスの数も追跡します。ランダム変数、トスの数、および検査した最後の間隔を返します。t[x,y)[0,1)ss

s <- function(x, ab, p) {
  d <- diff(ab) * p
  if (x == 1) c(ab[1], ab[1] + d) else c(ab[1] + d, ab[2])
}
draw <- function(target, p) {
  between <- function(z, ab) prod(z - ab) <= 0
  ab <- c(0,1)
  n <- 0
  while(between(target, ab)) {
    n <- n+1; ab <- s(runif(1) < p, ab, p)
  }
  return(c(target > ab[2], n, ab))
}

その使用とその精度のテストの例として、との場合を考えます。アルゴリズムを使用して値を描画し、平均(およびその標準誤差)をレポートして、使用されたフリップの平均数を示します。t=1/100p=0.910,000

target <- 0.01
p <- 0.9
set.seed(17)
sim <- replicate(1e4, draw(target, p))

(m <- mean(sim[1, ]))                           # The mean
(m - target) / (sd(sim[1, ]) / sqrt(ncol(sim))) # A Z-score to compare to `target`
mean(sim[2, ])                                  # Average number of flips

このシミュレーションでは、フリップのがヘッドでした。ターゲットのよりは低いですが、Zスコアは重要ではありません。この偏差は偶然に起因する可能性があります。フリップの平均回数は回で、10弱弱でした。私たちが使用していた場合はコインを、平均はあったであろう --stillない大幅に異なるターゲットよりも、唯一のフリップは平均的に必要とされていたであろう。0.00950.010.51549.8861p0.00941.177


このソリューションとソリューション2の類似点は私の回答でしか見えません。私は公平なコイン(PSはバイアスコインの問題に対する非常に興味深い解決策)を想定し、すべての計算/比較をbase-2で行いますが、すべての計算/比較はbase 10で行います。
Cam.Davidson.Pilon

1
@cam私はあなたが私の例にだまされるかもしれないと思います:ベース10で素敵な数字を使っていますが、構造は特定のベースとは何の関係もありません。
whuber

2
(+1)非常にきちんとした解像度。最適化は、上限と下限のやような累乗を使用して行われ。シミュレートされたベルヌーイの数に関して最適な二分法を見つけるとよいでしょう。a/bpn(1p)m(n+mm)pn(1p)m
西安

4

ここに解決策があります(少し厄介なものですが、それは私の最初の刺し傷です)。実際にはを無視することができ、WLOGは 1/2と仮定します。どうして?2つのバイアスされたコインフリップから公平なコインフリップを生成するための巧妙なアルゴリズムが存在します。したがって、 1/2と仮定できます。P(H)=pP(H)=1/2P(H)=1/2

を生成するために、2つの解決策を考えることができます(最初の解決策は自分のものではありませんが、2番目の解決策は一般化です):Bernoulli(ab)

解決策1

公平なコインを回反転させます。頭がない場合、最初からやり直します。場合ヘッドがある(ので、最初の硬貨がヘッドであるか否かリターン本)baaP(first coin is heads | a heads in b coins)=ab

解決策2

これは任意の値に拡張できます。書き込みバイナリ形式インチ たとえば、Bernoulli(p)p0.1=0.0001100110011001100110011...base 2

コイン投げを使用して新しい2進数を作成します。から始め、頭(1)または尾(0)が表示されるかどうかに応じて数字を追加します。フリップするたびに、新しい2進数をの2進数表現と同じ桁まで比較します。最終的に2つは分岐し、が2進数より大きい場合に戻ります。p b i n p 0.p bin(p)

Pythonの場合:

def simulate(p):
    binary_p = float_to_binary(p)
    binary_string = '0.'
    index = 3
    while True:
        binary_string += '0' if random.random() < 0.5 else '1'
        if binary_string != binary_p[:index]:
            return binary_string < binary_p[:index]
        index += 1

いくつかの証拠:

np.mean([simulate(0.4) for i in range(10000)])

約0.4(ただし速くない)


いい答えですが、方法1を使って、不合理なpをどうするか説明できますか
AbracaDabra 2016

2
@AbracaDabraなぜの合理性が重要なのでしょうか?p
Glen_b-2016

@AbracaDabra:の値が何であれ、とを取得する確率は同じ、つまりであるため、一方を他方に対して取得する確率はです。0 1 1 0 、P 1 - P )、1 / 2p(0,1)(1,0)p(1p)1/2
西安

4

私は簡単な解決策を見つけましたが、間違いなくそれを行う方法はたくさんあります。おそらくこれよりも簡単な方法もあります。このアプローチは、次の2つのステップに分けることができます。

  1. 不当なコイン投げの手順(特定のコインとそれを投げる方法を組み合わせて確率頭を発生させる方法の組み合わせ)を与えられた2つのイベントから等しい確率で生成します。これら2つの同等の可能性のあるイベントをおよびと呼ぶことができます。[これには単純なアプローチがあり、トスとペアを取り同等の可能性が高い2つの結果を生成し、他のすべての結果は新しいペアの生成につながります。再試行するロールの。]H T H = H T T = T H pHTH=(H,T)T=(T,H)

  2. 次に、シミュレーションされたフェアコインを使用して、2つの吸収状態のランダムウォークを生成します。原点からの吸収状態の距離(1つ上および1つ下)を選択することにより、たとえば、上部の吸収状態を整数の望ましい比率になるように吸収の可能性を設定できます。具体的には、あなたがで上方吸収バリア配置する場合とでより低い1(と原点からプロセスを開始)、および吸収されるまでランダムウォークを実行し、上部バリアでの吸収の確率はある。b a aa(ba)aa+(ba)=ab

    (これを示すためにここで行ういくつかの計算がありますが、再帰関係を操作することで確率をかなり簡単に得ることができます...または無限系列を合計することでそれを行うことができます...または他の方法があります。)

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