Scipy的曲线拟合无法找到最佳参数
我现在正在用scipy的curve_fit工具给一些LED的数据文件做高斯拟合。我对前3个LED使用的方法效果不错,但最后两个LED却出现了类似的错误。
我还附上了一张图,展示了其中一个图表的样子(就是那两个用curve_fit似乎不成功的其中一个),还有我尝试拟合的代码部分。
error472 = data472y ** 0.5
error505 = data505y ** 0.5
error525 = data525y ** 0.5
error588 = data588y ** 0.5
error611 = data611y ** 0.5
def GausFunc(x,a,b,c,d,f):
return(a*np.exp(-(x-b)**2 / (2*c**2))+(d*x)+f)
popt472, pcov472 = curve_fit(GausFunc, data472x, data472y, [0.8,470,50,-10,6], error472, True)
popt505, pcov505 = curve_fit(GausFunc, data505x, data505y, [0.8,470,50,-10,6], error505, True)
popt525, pcov525 = curve_fit(GausFunc, data525x, data525y, [0.8,470,50,-10,6], error525, True)
popt588, pcov588 = curve_fit(GausFunc, data588x, data588y, [0.387,589,5,1,1], error588, True)
#popt611, pcov611 = curve_fit(GausFunc, data611x, data611y, [0.8,470,50,-10,6], error611, True)
我收到的错误信息是:
RuntimeError Traceback (most recent call last)
Cell In[91], line 13
11 popt505, pcov505 = curve_fit(GausFunc, data505x, data505y, [0.8,470,50,-10,6], error505, True)
12 popt525, pcov525 = curve_fit(GausFunc, data525x, data525y, [0.8,470,50,-10,6], error525, True)
---> 13 popt588, pcov588 = curve_fit(GausFunc, data588x, data588y, [0.387,589,5,1,1], error588, True)
File ~\anaconda3\Lib\site-packages\scipy\optimize\_minpack_py.py:864, in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, full_output, **kwargs)
862 cost = np.sum(infodict['fvec'] ** 2)
863 if ier not in [1, 2, 3, 4]:
--> 864 raise RuntimeError("Optimal parameters not found: " + errmsg)
865 else:
866 # Rename maxfev (leastsq) to max_nfev (least_squares), if specified.
867 if 'max_nfev' not in kwargs:
RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 1200.
我尝试调整初始猜测的值,尽量找出有效的参数,但都没有成功(而且前3个LED的初始猜测值用起来就很好)。我还尝试把maxfev的值调高很多,但每次还是出现同样的错误。看起来就是588 nm和611 nm的LED数据导致了这个错误。
我还尝试去掉函数中与“d”和“f”相关的部分,使用一个基础的高斯函数,但结果还是出现了“RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 1200.”的错误。
这是我在这里的第一次发帖,如果我遗漏了什么信息,真是抱歉;请随时问我需要的其他信息。
1 个回答
0
下面这个简单的例子可以在没有错误的情况下对你所有的文件进行回归分析:
import pathlib
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import optimize, stats
def model(x, loc, scale, height):
law = stats.norm(loc=loc, scale=scale)
return height * law.pdf(x) / law.pdf(loc)
files = list(pathlib.Path("led").glob("*.txt"))
for file in files:
data = pd.read_csv(file, sep="\t", header=None, names=["x", "y"])
popt, pcov = optimize.curve_fit(model, data.x, data.y, p0=[600., 20., 0.8])
fig, axe = plt.subplots()
axe.plot(data.x, data.y)
axe.plot(data.x, model(data.x, *popt))
axe.grid()
它使用了 x
和 y
以及一个合理的初始猜测。不过,拟合效果不好,因为你的数据与正常分布相差很大。