2010-06-12 120 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]