在scipy中为计数器分配

2024-03-28 10:03:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个集合。计数器对象,其不同值的出现次数如下所示:

1:193260
2:51794
3:19112
4:9250
5:6486

我如何在scipy中为这些数据拟合一个概率分布?scipy.stats.expon.fit()似乎需要一个数字列表。创建一个包含193260[1]s,51794[2]s等的列表似乎很浪费。有没有更优雅或更有效的方法?在


Tags: 数据对象方法列表stats计数器浪费数字
1条回答
网友
1楼 · 发布于 2024-03-28 10:03:50

看起来像scipy.stats.expon.fit基本上是一个小包装scipy.optimize.minimize.最小化,它首先创建一个函数来计算负对数似然,然后使用scipy.optimize.minimize.最小化以适应pdf参数。在

所以,我认为你需要做的是编写你自己的函数来计算counter对象的neg log可能性,然后调用scipy.optimize.minimize.最小化你自己。在

更具体地说,scipy在这里定义了expon'scale'参数 http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.expon.html

因此,pdf是:

pdf(x) = 1 / scale * exp ( - x / scale)

所以,取两边的对数,我们得到:

^{pr2}$

因此,您的counter object中所有内容的负对数似然性为:

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 

相关问题 更多 >