【发布时间】:2014-06-13 07:19:56
【问题描述】:
我正在尝试找到适合 beta 分布的正确方法。这不是现实世界的问题,我只是在测试几种不同方法的效果,而这样做让我感到困惑。
这是我正在编写的 Python 代码,我在其中测试了 3 种不同的方法: 1>:使用矩(样本均值和方差)拟合。 2>:通过最小化负对数似然来拟合(通过使用 scipy.optimize.fmin())。 3>:只需调用 scipy.stats.beta.fit()
from scipy.optimize import fmin
from scipy.stats import beta
from scipy.special import gamma as gammaf
import matplotlib.pyplot as plt
import numpy
def betaNLL(param,*args):
'''Negative log likelihood function for beta
<param>: list for parameters to be fitted.
<args>: 1-element array containing the sample data.
Return <nll>: negative log-likelihood to be minimized.
'''
a,b=param
data=args[0]
pdf=beta.pdf(data,a,b,loc=0,scale=1)
lg=numpy.log(pdf)
#-----Replace -inf with 0s------
lg=numpy.where(lg==-numpy.inf,0,lg)
nll=-1*numpy.sum(lg)
return nll
#-------------------Sample data-------------------
data=beta.rvs(5,2,loc=0,scale=1,size=500)
#----------------Normalize to [0,1]----------------
#data=(data-numpy.min(data))/(numpy.max(data)-numpy.min(data))
#----------------Fit using moments----------------
mean=numpy.mean(data)
var=numpy.var(data,ddof=1)
alpha1=mean**2*(1-mean)/var-mean
beta1=alpha1*(1-mean)/mean
#------------------Fit using mle------------------
result=fmin(betaNLL,[1,1],args=(data,))
alpha2,beta2=result
#----------------Fit using beta.fit----------------
alpha3,beta3,xx,yy=beta.fit(data)
print '\n# alpha,beta from moments:',alpha1,beta1
print '# alpha,beta from mle:',alpha2,beta2
print '# alpha,beta from beta.fit:',alpha3,beta3
#-----------------------Plot-----------------------
plt.hist(data,bins=30,normed=True)
fitted=lambda x,a,b:gammaf(a+b)/gammaf(a)/gammaf(b)*x**(a-1)*(1-x)**(b-1) #pdf of beta
xx=numpy.linspace(0,max(data),len(data))
plt.plot(xx,fitted(xx,alpha1,beta1),'g')
plt.plot(xx,fitted(xx,alpha2,beta2),'b')
plt.plot(xx,fitted(xx,alpha3,beta3),'r')
plt.show()
我遇到的问题是关于标准化过程 (z=(x-a)/(b-a)),其中 a 和 b 分别是样本的最小值和最大值。
当我不进行归一化时,一切正常
但是当我进行标准化时,这是我得到的结果图。
只有矩方法(绿线)看起来没问题。
scipy.stats.beta.fit() 方法(红线)始终是统一的,无论我使用什么参数来生成随机数。
MLE(蓝线)失败。
所以看起来规范化正在造成这些问题。但我认为在 beta 发行版中有 x=0 和 x=1 是合法的。如果给定一个现实世界的问题,这不是标准化样本观察以使其介于 [0,1] 之间的第一步吗?那么,我应该如何拟合曲线?
【问题讨论】:
-
科学家是否曾经使用运算符之间的空格来格式化他们的代码...或者他们只是太忙忙:)
-
@Ffisegydd 感谢您的帮助。
标签: python curve-fitting beta-distribution