Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的负二项式拟合_Python_Statistics_Scipy_Distribution_Statsmodels - Fatal编程技术网

python中的负二项式拟合

python中的负二项式拟合,python,statistics,scipy,distribution,statsmodels,Python,Statistics,Scipy,Distribution,Statsmodels,在scipy中,不支持使用数据拟合负二项分布 (可能是因为scipy中的负二项式只是离散的) 对于正态分布,我只需执行以下操作: from scipy.stats import norm param = norm.fit(samp) 在任何其他库中是否有类似的“即用”函数?不仅因为它是离散的,而且因为负二项式的最大似然拟合可能非常复杂,特别是在附加位置参数的情况下。这就是为什么没有为它提供.fit()方法的原因(以及Scipy中的其他离散分布),下面是一个示例: In [163]: impo

在scipy中,不支持使用数据拟合负二项分布 (可能是因为scipy中的负二项式只是离散的)

对于正态分布,我只需执行以下操作:

from scipy.stats import norm
param = norm.fit(samp)

在任何其他库中是否有类似的“即用”函数?

不仅因为它是离散的,而且因为负二项式的最大似然拟合可能非常复杂,特别是在附加位置参数的情况下。这就是为什么没有为它提供
.fit()
方法的原因(以及
Scipy
中的其他离散分布),下面是一个示例:

In [163]:

import scipy.stats as ss
import scipy.optimize as so
In [164]:
#define a likelihood function
def likelihood_f(P, x, neg=1):
    n=np.round(P[0]) #by definition, it should be an integer 
    p=P[1]
    loc=np.round(P[2])
    return neg*(np.log(ss.nbinom.pmf(x, n, p, loc))).sum()
In [165]:
#generate a random variable
X=ss.nbinom.rvs(n=100, p=0.4, loc=0, size=1000)
In [166]:
#The likelihood
likelihood_f([100,0.4,0], X)
Out[166]:
-4400.3696690513316
In [167]:
#A simple fit, the fit is not good and the parameter estimate is way off
result=so.fmin(likelihood_f, [50, 1, 1], args=(X,-1), full_output=True, disp=False)
P1=result[0]
(result[1], result[0])
Out[167]:
(4418.599495886474, array([ 59.61196161,   0.28650831,   1.15141838]))
In [168]:
#Try a different set of start paramters, the fit is still not good and the parameter estimate is still way off
result=so.fmin(likelihood_f, [50, 0.5, 0], args=(X,-1), full_output=True, disp=False)
P1=result[0]
(result[1], result[0])
Out[168]:
(4417.1495981801972,
 array([  6.24809397e+01,   2.91877405e-01,   6.63343536e-04]))
In [169]:
#In this case we need a loop to get it right
result=[]
for i in range(40, 120): #in fact (80, 120) should probably be enough
    _=so.fmin(likelihood_f, [i, 0.5, 0], args=(X,-1), full_output=True, disp=False)
    result.append((_[1], _[0]))
In [170]:
#get the MLE
P2=sorted(result, key=lambda x: x[0])[0][1]
sorted(result, key=lambda x: x[0])[0]
Out[170]:
(4399.780263084549,
 array([  9.37289361e+01,   3.84587087e-01,   3.36856705e-04]))
In [171]:
#Which one is visually better?
plt.hist(X, bins=20, normed=True)
plt.plot(range(260), ss.nbinom.pmf(range(260), np.round(P1[0]), P1[1], np.round(P1[2])), 'g-')
plt.plot(range(260), ss.nbinom.pmf(range(260), np.round(P2[0]), P2[1], np.round(P2[2])), 'r-')
Out[171]:
[<matplotlib.lines.Line2D at 0x109776c10>]
[163]中的

将scipy.stats导入为ss
按原样导入scipy.optimize
在[164]中:
#定义一个似然函数
def似然(P,x,neg=1):
n=np.round(P[0])#根据定义,它应该是一个整数
p=p[1]
loc=np.圆形(P[2])
返回neg*(np.log(ss.nbinom.pmf(x,n,p,loc)).sum()
在[165]中:
#生成一个随机变量
X=ss.nbinom.rvs(n=100,p=0.4,loc=0,尺寸=1000)
在[166]中:
#可能性
似然度f([100,0.4,0],X)
出[166]:
-4400.3696690513316
在[167]中:
#一个简单的拟合,拟合不是很好,参数估计也很差
result=so.fmin(似然[50,1,1],args=(X,-1),完整输出=True,disp=False)
P1=结果[0]
(结果[1],结果[0])
出[167]:
(4418.599495886474,数组([59.61196161,0.28650831,1.15141838]))
在[168]中:
#尝试一组不同的开始参数,拟合仍然不好,参数估计仍然相差很远
result=so.fmin(似然[50,0.5,0],args=(X,-1),完整输出=True,disp=False)
P1=结果[0]
(结果[1],结果[0])
Out[168]:
(4417.1495981801972,
阵列([6.24809397e+01,2.91877405e-01,6.63343536e-04]))
在[169]中:
#在这种情况下,我们需要一个循环来获得正确的结果
结果=[]
对于范围内的i(40120):#事实上(80120)应该足够了
_=so.fmin(似然[i,0.5,0],args=(X,-1),完整输出=True,disp=False)
result.append(([1],[0]))
在[170]中:
#获取MLE
P2=已排序(结果,键=λx:x[0])[0][1]
已排序(结果,键=λx:x[0])[0]
出[170]:
(4399.780263084549,
阵列([9.37289361e+01,3.84587087e-01,3.36856705e-04]))
在[171]中:
#哪一个视觉效果更好?
plt.hist(X,箱子=20,标准=真)
plt.plot(范围(260)、ss.nbinom.pmf(范围(260)、np.round(P1[0])、P1[1]、np.round(P1[2])、g-)
plt.plot(范围(260),ss.nbinom.pmf(范围(260),np.round(P2[0]),P2[1],np.round(P2[2]),r-)
出[171]:
[]

我知道这篇文章已经很老了,但现在的读者可能想看看这篇为此目的而制作的回购:


这里还有一个实现,尽管它是一个更大的包的一部分:

Statsmodels具有离散的.discrete\u model.negativeBionomial.fit(),请参见此处:

我意识到这是一个非常特别的解决方案。优化功能不总是起作用。你找到了这个问题的解决方案吗?请参阅@Eran的答案。statsmodels.discrete.discrete_model.NegativeBiomial