【问题标题】:Choose list variable given probability of each variable选择列表变量给定每个变量的概率
【发布时间】:2020-12-31 01:56:34
【问题描述】:

我一直在尝试编写一个中间使用softmax激活函数的程序。

现在,我有一个这样的概率列表:

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

我完全不知道从哪里开始。任何帮助,将不胜感激。 :)

【问题讨论】:

  • 您正在寻找的是一个加权随机生成,虽然它不是内置的,但有a lot of standard recipes for this
  • 实际上,从 Python 3.6 开始,random.choices(注意末尾的 's')允许提交相对权重。

标签: python probability


【解决方案1】:

您可以使用 numpy.它有一个choice 函数,接受概率参数。

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

【讨论】:

  • 简洁,虽然我认为numpy 在这里有点矫枉过正,特别是如果脚本没有超出标准库的依赖项
【解决方案2】:

基本上,创建一个cumulative probability distribution (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]

(结果会,并且应该会有所不同)。当然,对于这么少的可能索引,二进制搜索是相当不必要的,但绝对推荐用于具有更多可能索引的分布。

【讨论】:

    【解决方案3】:

    嗯,有意思,怎么样……

    1. 生成一个介于 0 和 1 之间的数字。

    2. 遍历列表,从你的数字中减去每个项目的概率。

    3. 选择减法后将您的数字降至 0 或以下的项目。

    这很简单,O(n) 并且应该可以工作:)

    【讨论】:

    • 如果概率以降序方式预先排序会有所帮助 - 迭代可能会更快终止。
    【解决方案4】:

    这个问题相当于从categorical distribution 中采样。这种分布通常与多项分布混为一谈,该分布对来自分类分布的多个样本的结果进行建模。

    在 numpy 中,使用 numpy.random.multinomial 从多项分布中进行采样很容易,但不存在特定的分类版本。但是,可以通过一次试验从多项分布中采样,然后在输出中返回非零元素来完成。

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

    【讨论】:

    • 我认为使用 argmax() 而不是 where()[0][0] 更简单,效果也一样。
    【解决方案5】:
    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 秒我还以为我是原创者
    • 这总是需要 O(n) 时间,其中 n 是 len(probs)。我们能做得更好吗?
    • @Sush 是的:我们可以对概率进行排序并进行二进制搜索。这将减少到 O(log n)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    • 2015-06-06
    • 2017-07-31
    • 2016-10-31
    • 2019-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多