2014-09-23 66 views
7

我有一個很大的代碼,在一個點上根據probability density function(PDF)的概率從一個數組中取樣值。numpy 1.9.0:ValueError:概率不等於1

要做到這一點,我使用numpy.random.choice工作得很好,直到numpy 1.8.0。這裏有一個MWE(文件pdf_probs.txt可以下載here):

import simplejson 
import numpy as np 

# Read probabilities from file. 
f = open('pdf_probs.txt', 'r') 
probs = simplejson.load(f) 
f.close() 

print sum(probs) # <-- Not *exactly* 1. but very close: 1.00000173042 
# Define array. 
arr = np.linspace(1., 100., len(probs)) 

# Get samples using the probabilities in probs. 
samples = np.random.choice(arr, size=1000, replace=True, p=probs) 

的事情是,與numpy 1.9.0測試之後,上面的代碼失敗,出現錯誤:

Traceback (most recent call last): 
    File "numpy_180_vs_190_np_random_choice.py", line 13, in <module> 
    samples = np.random.choice(arr, size=1000, replace=True, p=probs) 
    File "mtrand.pyx", line 1083, in mtrand.RandomState.choice (numpy/random/mtrand/mtrand.c:10106) 
ValueError: probabilities do not sum to 1 

的PDF概率之和將不會總和爲 1.給出使用非常小的浮標時出現的小偏差。

從我可以收集的numpy1.8.0)的前一版本明顯比新的1.9.0版本有更大的容差,但我可能是錯的。

爲什麼它可以與numpy 1.8.0一起使用,但不能和1.9.0一起使用?我怎樣才能使我的代碼與新的1.9.0版本一起工作?

+2

這裏的變化的容限測試:1.9版本(https://github.com/numpy/numpy/blob /maintenance/1.9.x/numpy/random/mtrand/mtrand.pyx#L1082)vs [1.8版本](https://github.com/numpy/numpy/blob/maintenance/1.8.x/numpy/random/mtrand /mtrand.pyx#L1030)。 – user2357112 2014-09-23 02:09:40

回答

9

我認爲1.7e-6是一個足夠大的相對誤差值得抱怨。你可以很容易地重新歸一化不夠,不過,如果你自信的誤差可以忽略不計:

>>> probs = np.array(probs) 
>>> probs /= probs.sum() 
>>> probs.sum() 
1.0 
>>> samples = np.random.choice(arr, size=1000, replace=True, p=probs) 
>>> samples[:5] 
array([ 1.37635054, 1.1287515 , 1.7229892 , 19.8967587 , 2.07953181]) 
+0

謝謝@DSM,這是一個非常簡單的解決方案,我沒有想到。你有什麼想法從1.8.0更改爲1.9.0,以使代碼不再起作用嗎? – Gabriel 2014-09-23 01:05:33

+0

這不適合我,我的概率是大整數。當我經歷這個步驟'robs/= probs.sum()'時,它只會創建一個0的數組,所以我的sum()爲0 – jrubins 2015-05-28 18:21:07

+0

@jrubins這是整數除法的結果。如果你使用'probs/= probs.sum()。astype(float)',你應該沒問題。 – wflynny 2015-07-08 19:28:40