2016-01-23 151 views
2

我想從一組選項中選擇多個項目。每個選項都有自己的一組選擇或不選擇的概率。隨機選擇多選項選項

福克斯例如:
選擇 「是」, 「否」
「九月」,0.90,0.10
「十月」,0.25,0.75
「十一月」,0.45,0.55
「 12月「,0.50,0.50

」yes「表示選項被選中,」no「表示未選中。因此對於第一卷,選擇可以是[「9月」,「12月」],對於第二卷可以是[「9月」,「10月」,「11月」等等)。

與選擇或不選擇其中一個選項的複選框選項相似。

我可以通過循環到每個給定的選擇通過numpy.random.choice。但是我想知道是否有更優雅/更高效的方式來做到這一點?

這是我做過什麼

choices = { 
    "September":0.90, 
    "October":0.25, 
    "November":0.45, 
    "December":0.50 
} 

resp = [] 
for ch, pr in choices: 
    pick = 1 
    probs = [pr, 1-pr] 
    select = ["yes", "no"] 
    choose = numpy.random.choice(select, pick, probs) 
    if "yes" in choose[0]: 
     resp.append(ch) 

感謝。

回答

1

您可以使用numpy.random.uniform函數在區間[0,1]中生成樣本。通過將這些與choices中的概率進行比較,您可以創建具有指定概率的隨機樣本。由於自動廣播,每列與choices相應的概率進行比較。

這樣,你可以創建一個矩陣,尺寸(n_rolls, n_choices),其中n_rolls是要重複這個(這可能是1如果你只需要一個樣本)的次數,並且n_choices是不同的選擇的數量。

import numpy 
from collections import OrderedDict 

choices = OrderedDict() 
choices["September"] = 0.90 
choices["October"] = 0.25 
choices["November"] = 0.45 
choices["December"] = 0.50 

n_rolls = 5 
probs = numpy.random.uniform(size=(n_rolls, len(choices))) 
samples = probs < choices.values() 

其結果將是一個布爾值陣列,其中,每列對應於從choices一個選項,每行包含一個嘗試。在我們使用OrderedDict時,結果將按照輸入字典數據的相同方式進行排序。

>>> samples 
array([[False, False, False, False], 
     [ True, True, True, False], 
     [ True, False, False, False], 
     [ True, False, True, True], 
     [ True, False, True, False]], dtype=bool) 

作爲一個試驗:讓我們找出每一列的概率爲n_rolls=1000000

>>> numpy.mean(samples, axis=0) 
array([ 0.899713, 0.249405, 0.449437, 0.499881]) 

這個結果轉換爲像您指定的一個列表,你可以使用的numpy.wherenumpy.choose組合:

res = numpy.choose(numpy.where(samples[0, :]), choices.keys()) 

print samples[0,:],'\n',res 
[ True False True True] 
[['September' 'November' 'December']] 

不幸的是,這部分只適用於一個單列,因此,如果您有多個卷,你需要做最後的STE p在一個循環中。

+0

這正是我想要的。謝謝。 – soacq