加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 在scipy中将分布适合计数器

发布时间:2020-12-20 13:40:29 所属栏目:Python 来源:网络整理
导读:我有一个collections.Counter对象,其中包含不同值的出现次数,如下所示: 1:1932602:517943:191124:92505:6486 如何在scipy中为这些数据拟合概率分布? scipy.stats.expon.fit()似乎想要一个数字列表.使用193260 [1] s,51794 [2]等创建列表似乎很浪费.是否有
我有一个collections.Counter对象,其中包含不同值的出现次数,如下所示:

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’scale’参数
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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读