Изглежда, че scipy.stats.expon.fit е основно малка обвивка над scipy.optimize.minimize, където първо създава функция за изчисляване на neg-log-вероятност и след това използва scipy.optimize.minimize, за да пасне на pdf параметрите.
И така, мисля, че това, което трябва да направите тук, е да напишете своя собствена функция, която изчислява neg-log-вероятността на обекта на брояча, и след това да извикате scipy.optimize.minimize себе си.
По-конкретно, scipy дефинира параметъра 'scale' на 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
person
mattsh
schedule
23.02.2014