2016-01-23 153 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