2010-06-12 123 views
4

我需要生成一个[0,1]如 之间的随机浮点数的向量,它们的总和等于1并且分布不均匀。 是否有任何生成这种向量的python函数?非均匀分布的随机数组

最良好的祝愿

+4

你需要指定好你所需要的分布。作为一种极端情况,您可以在[0,0.001]范围内生成九个数字,然后从1中减去它们之和得到第十个数字。这当然符合你的标准,但它似乎有点人为,所以你应该在一定程度上加强这些标准。 – paxdiablo 2010-06-12 12:06:23

+0

@ paxdiablo方法的一个改进是在任意范围内生成n个数字,然后用矢量和来划分它们中的每一个。这将给一个向量与总和1.然而,分布是另一个问题。 – 2010-06-12 12:16:00

+1

我认为这些数字“非均匀分布”意味着数字不应该全部(大致)相等 - 我根据这个假设给出了一个答案。如果这不是你的意思,请澄清你的问题,因为即使是一个固定的矢量,包含一些随机顺序中的[[0.05,0.2,0.3,0.45]],也满足你的标准:它是随机的,不均匀的,并且总结为1. – 2010-06-12 12:25:24

回答

16

你可能寻找被称为Dirichlet distribution分布。有没有在Python中没有内置函数用于从狄利克雷分布图纸随机数,但NumPy包含了一个:

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

这会给你ň数字,加起来为1,并且每个这种组合的概率将是平等的。

或者,如果你没有NumPy的,则可以利用其从Ñ维狄利克雷分布绘制的随机样品可以通过从gamma distribution绘制Ñ独立样品具有形状来产生这样的事实和尺度参数为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] 

为什么你需要一个狄利克雷分布的原因是因为如果你简单地均匀地从某个区间得出的随机数,然后通过总和除以他们他们,由此产生的分布将偏向样本c数量大致相等。有关此主题的更多信息,请参见Luc Devroye's book

+0

谢谢Tamás,那就是我正在寻找的东西! – Javier 2010-06-12 12:40:59

+0

太棒了!如果您对这个解决方案感到满意,请考虑将解决方案标记为“已接受”。 – 2010-06-12 14:12:43

+1

为什么不使用更简单的'random.expovariate'? – 2010-06-12 19:49:05

2

Wikipedia page: Dirichlet distribution有一个更好的例子。下面 的代码生成K尺寸的样品:

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