【问题标题】:Loop over finite probability weights with SciPy/NumPy使用 SciPy/NumPy 循环有限概率权重
【发布时间】:2019-10-02 11:05:09
【问题描述】:

让我们有一个事件概率prob,它是一个介于 0-1 之间的标量。如果我想以 0.1 的增量迭代每个可能的概率,那么我可以使用:

prob = np.arange(0.01, 1, 0.1)

现在假设我有 5 个事件(独立,概率总和为 1),每个事件的概率为 p_i。我想要多维概率数组,例如:

1.0 - 0.0 - 0.0 - 0.0 - 0.0
0.9 - 0.1 - 0.0 - 0.0 - 0.0
0.9 - 0.0 - 0.1 - 0.0 - 0.0
0.9 - 0.0 - 0.0 - 0.1 - 0.0
0.9 - 0.0 - 0.0 - 0.0 - 0.1
0.8 - 0.1 - 0.1 - 0.0 - 0.0
0.8 - 0.1 - 0.0 - 0.1 - 0.0
.      .     .     .     .
.      .     .     .     .
.      .     .     .     . 
0.2 - 0.2 - 0.2 - 0.2 - 0.2

有没有比考虑 0 - 0.1 - ... - 1 的所有组合并删除总和不为 1 的行更聪明的方法?如果是,最简单的方法是什么?

【问题讨论】:

  • 应该是np.arange(0, 1.1, 0.1)吗?
  • 澄清一下,你想生成那个概率矩阵吗?或者您已经拥有它并想要删除总和不为 1 的行?
  • @DavidKong 我想自己安排这些界限。我不希望概率为零,1-0 = 1 也不希望。
  • @Brenlla 感谢您的提问。我想生成这个概率矩阵。

标签: python python-3.x numpy scipy probability


【解决方案1】:

您可以使用 itertools.productfilter 创建所有总和为 10 的组合并将其传递给数组:

import itertools
f = filter(lambda x: sum(x) == 10, itertools.product(*[range(11)]*5))
x = np.array(list(f)).astype(np.float)/10
x
>> array([[0. , 0. , 0. , 0. , 1. ],
       [0. , 0. , 0. , 0.1, 0.9],
       [0. , 0. , 0. , 0.2, 0.8],
       ...,
       [0.9, 0. , 0.1, 0. , 0. ],
       [0.9, 0.1, 0. , 0. , 0. ],
       [1. , 0. , 0. , 0. , 0. ]])

编辑

为了记录,这是一种不使用过滤的更有效的方法。本质上,您创建 k 箱(在您的示例中为 10),并使用 combinations_with_replacement

以所有可能的组合将它们“分配”给“n”个样本(在您的示例中为 3)

然后,您计算每个样本得到多少个 bin:这是您的概率。这种方法理解起来更复杂,但避免了filter,因此效率更高。您可以尝试使用 0.01 的除法 (k = 100)

n = 3 # number of samples
k = 100 # number of subdivisions

f = itertools.combinations_with_replacement(range(3),k) #your iterator
r = np.array(list(f)) #your array of combinations
x = np.vstack((r==i).sum(1) for i in range(n)).T/k #your probability matrix

【讨论】:

  • 你觉得把断点排成0.01等容易吗?
  • 是的,只需将range(11) 替换为range(101),将sum(x)== 10 替换为sum(x)== 100,将/10 替换为/100。警告你,这是一个巨大的矩阵!
  • 那只是出于好奇,我没有勇气去运行它:)
  • 我也很好奇,因为我知道必须有一种方法可以避免创建所有组合并过滤它们(我想我找到了)。我并将其添加到答案中。
【解决方案2】:

使用 itertools 可能有更优雅的解决方案,但这可能很好并且不使用依赖项?:

for i in prob:
  for j in prob:
     for k in prob:
        for l in prob:
           m = 1 - i - j - l
           if m>=0:
              print(i,j,k,l,m)

【讨论】:

    猜你喜欢
    • 2015-07-31
    • 1970-01-01
    • 2021-12-10
    • 2020-12-09
    • 1970-01-01
    • 2018-05-09
    • 1970-01-01
    • 2021-05-11
    • 1970-01-01
    相关资源
    最近更新 更多