回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p><a href="https://i.stack.imgur.com/P9CpR.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/P9CpR.png" alt="enter image description here"/></a>我试图用负对数似然极小化来拟合指数衰减函数,但即使有好的初始参数<code>x0</code>作为最小值,我似乎也无法使其收敛。为什么?我写错了吗?在</p>
<p><em>编辑以包括传统的二进制似然,即“曲线”拟合</em></p>
<pre><code>import numpy as np
from scipy.optimize import minimize, curve_fit
import matplotlib.pyplot as plt
np.random.seed(1)
def exp_fit(x, N, L):
return N * np.exp(- L * x)
def negloglik(args, func, data):
"""Negative log likelihood"""
return - np.sum(np.log(func(data, *args)))
def histpoints_w_err(X, bins):
counts, bin_edges = np.histogram(X, bins = bins, normed = False)
bin_centers = (bin_edges[1:] + bin_edges[:-1]) / 2
bin_err = np.sqrt(counts)
# Generate fitting points
x = bin_centers[counts > 0] # filter along counts, to remove any value in the same position as an empty bin
y = counts[counts > 0]
sy = bin_err[counts > 0]
return x, y, sy
data = np.random.exponential(0.5, 1000)
bins = np.arange(0, 3, 0.1)
x, y, sy = histpoints_w_err(data, bins)
popt, pcov = curve_fit(exp_fit, x, y, sigma = sy)
xpts = np.linspace(0, 3, 100)
# All variables must be positive
bnds = ((0, None),
(0, None))
result = minimize(negloglik,
args = (exp_fit, data),
x0 = (popt[0], popt[1]), # Give it the parameters of the fit that worked
method = "SLSQP",
bounds = bnds)
jac = result.get("jac")
plt.hist(data, bins = bins)
plt.plot(xpts, exp_fit(xpts, *popt), label = "Binned fit: {:.2f}exp(-{:.2f}x)".format(*popt))
plt.plot(xpts, exp_fit(xpts, *jac), label = "Unbinned fit: {:.2f}exp(-{:.2f}x)".format(*jac))
plt.text(s = result, x = 0.8, y = popt[0]*0.2)
plt.legend()
plt.show()
</code></pre>