非均匀分布的随机数组

4 投票
2 回答
3389 浏览
提问于 2025-04-15 23:52

我需要生成一个随机的小数向量,这些小数的范围在0到1之间,并且它们的总和要等于1,而且这些小数的分布要不均匀。有没有什么Python函数可以生成这样的向量呢?

祝好!

2 个回答

2

维基百科的Dirichlet分布页面上有一个更好的例子。下面的代码可以生成一个k维的样本:

params = [a1, a2, ..., ak]
sample = [random.gammavariate(a,1) for a in params]
sample = [v/sum(sample) for v in sample]
16

你可能想要的分布叫做Dirichlet分布。在Python中没有直接的函数可以用来从Dirichlet分布中生成随机数,但NumPy库里有一个可以做到这一点:

>>> from numpy.random.mtrand import dirichlet
>>> print dirichlet([1] * n)

这个方法会给你个数字,它们加起来等于1,并且每种组合出现的概率是一样的。

另外,如果你没有NumPy,也可以利用一个特点来生成随机样本:从一个维的Dirichlet分布中抽样,可以通过从一个伽马分布中独立抽取个样本(形状和尺度参数都设为1),然后用这些样本的和来进行除法:

>>> from random import gammavariate
>>> def dirichlet(n):
...     samples = [gammavariate(1, 1) for _ in xrange(n)]
...     sum_samples = sum(samples)
...     return [x/sum_samples for x in samples]

你需要Dirichlet分布的原因是,如果你只是从某个区间均匀地抽取随机数,然后用它们的和去除,这样得到的分布会偏向于那些数字大致相等的样本。想了解更多,可以参考Luc Devroye的书

撰写回答