web-dev-qa-db-ja.com

各変数の確率を指定してリスト変数を選択

私は途中でソフトマックス起動機能を使用するプログラムをコーディングしようとしています。

現在、私はこのような確率のリストを持っています:

P[0.10,0.25,0.60,0.05]

Pのすべての変数の合計は常に1です。

確率が付いているリストのインデックスを選択する方法が必要でした。または、言い換えると、返された関数

0 - 10% of the time
1 - 25% of the time
2 - 60% of the time
3 - 5% of the time

私はこれからどこから始めればいいのか全く分かりません。任意の助けいただければ幸いです。 :)

30
Roughmar

これはnumpyで簡単に実現できます。確率のパラメーターを受け入れる choice 関数があります。

np.random.choice(
  ['pooh', 'rabbit', 'piglet', 'Christopher'], 
  5,
  p=[0.5, 0.1, 0.1, 0.3]
)
40
Salvador Dali

基本的に、 累積確率分布 (CDF)配列を作成します。基本的に、特定のインデックスのCDFの値は、そのインデックス以下のPのすべての値の合計に等しくなります。次に、0と1の間の乱数を生成し、バイナリ検索(または必要に応じて線形検索)を実行します。簡単なコードをいくつか示します。

from bisect import bisect
from random import random

P = [0.10,0.25,0.60,0.05]

cdf = [P[0]]
for i in xrange(1, len(P)):
    cdf.append(cdf[-1] + P[i])

random_ind = bisect(cdf,random())

もちろん、次のようなものでランダムなインデックスの束を生成できます

rs = [bisect(cdf, random()) for i in xrange(20)]

降伏

[2, 2, 3, 2, 2, 1, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 2, 2, 2]

(結果は変化し、変化するはずです)。もちろん、可能性のあるインデックスの数が少ない場合は、バイナリ検索はどちらかと言えば不要ですが、より多くの可能性のあるインデックスを持つ分布に対しては確実に推奨されます。

11
Justin Peel

おもしろい、どうだ...

  1. 0と1の間の数を生成します。

  2. あなたの番号から各項目の確率を引いてリストを歩きます。

  3. 減算後、番号が0以下になったアイテムを選択してください。

それは簡単です、O(n)で動作するはずです:)

10
slezica

この問題は、 カテゴリカル分布 からのサンプリングと同等です。この分布は、一般に、カテゴリカル分布からの複数のサンプルの結果をモデル化する多項分布と融合しています。

Numpyでは、多項分布から numpy.random.multinomial を使用して簡単にサンプリングできますが、これの特定のカテゴリバージョンは存在しません。ただし、1回の試行で多項分布からサンプリングし、出力に非ゼロ要素を返すことで実現できます。

import numpy as np
pvals = [0.10,0.25,0.60,0.05]
ind = np.where(np.random.multinomial(1,pvals))[0][0]
4
animus144
import random

probs = [0.1, 0.25, 0.6, 0.05]
r = random.random()
index = 0
while(r >= 0 and index < len(probs)):
  r -= probs[index]
  index += 1
print index - 1
2
sje397