分配到一個計數器我有一個collections.Counter對象使用不同的值的出現這樣的計數:適合在SciPy的
1:193260
2:51794
3:19112
4:9250
5:6486
我怎麼能適應的概率分佈這一數據SciPy的? scipy.stats.expon.fit()似乎想要一個數字列表。用193260 [1] s,51794 [2]等創建一個列表似乎很浪費。是否有更優雅或更高效的方式?
分配到一個計數器我有一個collections.Counter對象使用不同的值的出現這樣的計數:適合在SciPy的
1:193260
2:51794
3:19112
4:9250
5:6486
我怎麼能適應的概率分佈這一數據SciPy的? scipy.stats.expon.fit()似乎想要一個數字列表。用193260 [1] s,51794 [2]等創建一個列表似乎很浪費。是否有更優雅或更高效的方式?
看起來像scipy.stats.expon.fit基本上是scipy.optimize.minimize的一個小包裝,它首先創建一個函數來計算neg-log-likelihood,然後使用scipy.optimize.minimize來擬合pdf參數。
所以,我認爲你需要做的是編寫你自己的函數來計算counter對象的neg-log-likelihood,然後調用scipy.optimize.minimize你自己。
更具體地說,SciPy的定義expon '規模' 在這裏參數 http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.expon.html
所以,PDF是:
pdf(x) = 1/scale * exp (- x/scale)
所以,對兩邊的對數,我們得到:
log_pdf(x) = - log(scale) - x/scale
因此,您反物體中所有物品的負對數似然爲:
def neg_log_likelihood(scale):
total = 0.0
for x, count in counter.iteritems():
total += (math.log(scale) + x/scale) * count
return total
這是一個程序來試試。
import scipy.stats
import scipy.optimize
import math
import collections
def fit1(counter):
def neg_log_likelihood(scale):
total = 0.0
for x, count in counter.iteritems():
total += (math.log(scale) + x/scale) * count
return total
optimize_result = scipy.optimize.minimize(neg_log_likelihood, [1.0])
if not optimize_result.success:
raise Exception(optimize_result.message)
return optimize_result.x[0]
def fit2(counter):
data = []
# Create an array where each key is repeated as many times
# as the value of the counter.
for x, count in counter.iteritems():
data += [x] * count
fit_result = scipy.stats.expon.fit(data, floc = 0)
return fit_result[-1]
def test():
c = collections.Counter()
c[1] = 193260
c[2] = 51794
c[3] = 19112
c[4] = 9250
c[5] = 6486
print "fit1 'scale' is %f " % fit1(c)
print "fit2 'scale' is %f " % fit2(c)
test()
這裏是輸出:
fit1 'scale' is 1.513437
fit2 'scale' is 1.513438
或許這可以幫助? http://stackoverflow.com/questions/7805552/fitting-a-histogram-with-python – Sahand