从 scipy 中分布的 pdf 值估计分布的 MLE参数

问题描述

我有对数逻辑分布的几个点 [x1,x2,x3,x4,x5 ...,xn] 的 pdf 值 [p1,p2,p3,p4,p5,....pn]

我想在scipy中找出这个分布的MLE参数。 (即)clocscale。 你能建议一种使用 scipy 库来做到这一点的方法吗? scipy 中的 log-logistic 函数scipy.stats.fisk

解决方法

方法 #1:最大似然估计

找到 Maximum Likelihood EstimatorLog-logistic distribution 的一种方法是使用 scipy 的 optimize 模块进行数值优化。

这是一个例子:

single.php

这将返回找到的参数向量 import numpy as np np.random.seed(42) from scipy import stats,optimize # Define negative log-Likelihood function def nll(theta,X): return -sum(stats.fisk.logpdf(x,theta[0],theta[1],theta[2]) for x in X) # true parameters c,loc,scale = 3.09,5,6 # generate artificial data X = stats.fisk.rvs(c,scale,size=100) # initial guess theta0 = [0.1,0.,1] # optimization res = optimize.minimize(nll,x0=theta0,method='Nelder-Mead',args=(X),tol=1e-6) res.x ,第一个条目是形状 theta,第二个是 c,第三个是 loc

scale

方法#2:曲线拟合

如果您有测量值对 [2.76583366,5.43214064,5.18267233] 和分布的函数形式,您可以使用测量值来拟合曲线。 Scipy 的优化模块还提供了一个 curve_fit 函数。

方法如下:

(x,p(x))

将估计以下参数:

# wrapper for the fisk distribution
def fisk(x,c,scale):
    return stats.fisk.pdf(x,scale)

# simulate (noisy) measurements and randomly sampled locations
X = stats.fisk.rvs(c,size=20)
p = stats.fisk.pdf(X,scale) + np.random.randn(len(X))*0.005

# curve fitting
popt,_ = optimize.curve_fit(fisk,X,p)
popt

最后是拟合分布与真实分布的比较:

fitted fisk vs. true fisk

[3.37757066,4.411966,6.53535827]

最后一点:测量不需要有噪音。在这种情况下,您将获得真正的参数值。但由于您的 plt.scatter(X,p,label='data',c='b') x = np.linspace(X.min(),X.max(),100) plt.plot(x,fisk(x,*popt),label='fitted curve',c='r') plt.plot(x,scale),'--',c='g',label='true cuve') plt.xlabel('x') plt.ylabel('p(x)') plt.legend() plt.show() 很可能来自直方图,我认为它们并非 100% 准确。