你的代码问题在于你不知道 curve_fit
的返回值是什么,它是拟合函数的参数及其协方差矩阵,而不是可以直接绘制的内容。
分段最小二乘拟合
一般来说,你可以更容易地获得所有东西:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy.special import factorial
from scipy.stats import poisson
data = np.random.poisson(2, 1000)
bins = np.arange(11) - 0.5
entries, bin_edges, patches = plt.hist(data, bins=bins, density=True, label='Data')
bin_centers = 0.5 * (bin_edges[1:] + bin_edges[:-1])
def fit_function(k, lamb):
'''poisson function, parameter lamb is the fit parameter'''
return poisson.pmf(k, lamb)
parameters, cov_matrix = curve_fit(fit_function, bin_centers, entries)
x_plot = np.arange(0, 15)
plt.plot(
x_plot,
fit_function(x_plot, *parameters),
marker='o', linestyle='',
label='Fit result',
)
plt.legend()
plt.show()
这是结果:
![binned fit](https://istack.dev59.com/9PDKD.webp)
最大似然去边界拟合
更好的选择是不使用直方图,而是进行最大似然拟合。
但是经过更仔细的观察,甚至这也是不必要的,因为泊松分布参数的最大似然估计量是算术平均值。
但是,如果您有其他更复杂的概率密度函数,可以将其用作示例:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize
from scipy.special import factorial
from scipy import stats
def poisson(k, lamb):
"""poisson pdf, parameter lamb is the fit parameter"""
return (lamb**k/factorial(k)) * np.exp(-lamb)
def negative_log_likelihood(params, data):
"""
The negative log-Likelihood-Function
"""
lnl = - np.sum(np.log(poisson(data, params[0])))
return lnl
def negative_log_likelihood(params, data):
''' better alternative using scipy '''
return -stats.poisson.logpmf(data, params[0]).sum()
data = np.random.poisson(2, 1000)
result = minimize(negative_log_likelihood,
x0=np.ones(1),
args=(data,),
method='Powell',
)
print(result)
x_plot = np.arange(0, 15)
plt.plot(
x_plot,
stats.poisson.pmf(x_plot, result.x),
marker='o', linestyle='',
label='Fit result',
)
plt.legend()
plt.show()
curve_fit
返回的是什么。请参阅 http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.optimize.curve_fit.html - tacaswellnp.histogram
;2)如果你有实际数据,请勿将曲线拟合到直方图上,而是使用scipy.stats
对数据本身进行拟合。 - askewchanfunc
不是泊松分布。 - MaxNoe