5

こんにちは、ゲノミクス クラスのコードを実行していますが、特定の部分で問題が発生しています。

イベント 1、イベント 2、... イベント n 確率のある一連の相互に排他的なイベントがありますp1、p2、... pn

指定された確率でイベントを n 回ランダムにサンプリングすることをシミュレートしたいと考えています。

入力: 確率 = {0.3, 0.2, 0.5} イベント{e1,e2,e3} n=100

出力: e3 では ~50、e2 では ~20、e1 では ~30 の結果があるはずです。経験値は理論値とは異なるため、これらはおそらく正確に 50、20、30 ではないことに注意してください...

4

2 に答える 2

5

Python には重み付けされたサンプリング機能が組み込まれていません (NumPy/SciPy には組み込まれています) が、このような非常に単純なケースでは、非常に簡単です。

import itertools
import random

probabilities = [0.3, 0.2, 0.5]
totals = list(itertools.accumulate(probabilities))

def sample():
    n = random.uniform(0, totals[-1])
    for i, total in enumerate(totals):
        if n <= total:
            return i

Python 3.2+ を持っていない場合、accumulate関数はありません。リストが本当に短い場合は、非効率的なワンライナーでそれを偽造できます。

totals = [sum(probabilities[:i+1]) for i in range(len(probabilities))]

…または、明示的なループまたは醜い呼び出しを作成するか、ドキュメントreduceから同等の Python 関数をコピーすることができます。


また、数値の合計が 1.0 になることが確実な場合random.uniform(0, totals[-1])は、より複雑な書き方になることに注意してください。random.random()


これをテストする簡単な方法:

>>> samples = [sample() for _ in range(100000)]
>>> samples.count(0)
29878
>>> samples.count(1)
19908
>>> samples.count(2)
50214

これらは、それぞれ 100000 の 30%、20%、50% にかなり近い値です。

于 2013-11-09T02:19:48.290 に答える
2

それぞれの確率が .3、.2、.5 の 3 つのイベントがあるとします。次に、生成された各サンプルに対して、範囲 [0,1) の数値を生成します。これを「rand」と呼びましょう。"rand" < .3 の場合はイベント 1 を生成し、.3 <= "rand" < .5 の場合は偶数 2 を生成し、そうでない場合はイベント 3 を生成します。これは、実際に数値を生成するrandom()を使用して達成できます範囲 [0,1)。

于 2013-11-09T02:20:49.337 に答える