Python 曲线拟合数据(I';m接近参数值,但曲线拟合表示未找到最佳参数)

Python 曲线拟合数据(I';m接近参数值,但曲线拟合表示未找到最佳参数),python,scipy,curve-fitting,Python,Scipy,Curve Fitting,我正试图用Python中的scipy中的curve\u fit来拟合数据。该文件包含温度与时间的数据点(以摄氏度和毫秒为单位)。我将它们转换为开尔文和秒: thefile = open("aluminio_33920um_aire.txt", "r") data = np.loadtxt(thefile, delimiter='\t', skiprows=1) Temp = data[:, 0] + 273.15 #kelvin Time = data[:, 1]*1e-3 #secs th

我正试图用Python中的scipy中的
curve\u fit
来拟合数据。该文件包含温度与时间的数据点(以摄氏度和毫秒为单位)。我将它们转换为开尔文和秒:

thefile = open("aluminio_33920um_aire.txt", "r")
data = np.loadtxt(thefile, delimiter='\t', skiprows=1)
Temp = data[:, 0] + 273.15  #kelvin
Time = data[:, 1]*1e-3  #secs
thefile.close()
我定义了两个要安装的功能:

def newton(t, a, b, tau):
    return a + b * np.exp(-t/tau)

def dulong(t, ta, dift, f, n):
    return ta + (dift + (n-1)*t/f)**(1/(1-n))
牛顿的装置工作得很好。但都龙没有。我已经为duolong的参数绘制了几个值,以查看哪些值绘制了一条或多或少符合数据的线,我发现这里给出的值:

poptd, pcovd = curve_fit(dulong, Time, Temp, p0=[295, 0.155, 6000, 1.38], sigma=[1]*len(Temp), absolute_sigma=True)
但是,将这些值
p0
传递到曲线拟合没有帮助,因为我得到了错误

RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 1000.

我不知道如何改进,因为我的参数的初始猜测是一个非常好的猜测。非常感谢您的帮助。

您的dulong函数对n的变化非常敏感,因为它依赖于
n^n
。如果这对你来说足够好的话,你可能想要为它设定界限,甚至保持它为常数

此外,如果你处理足够小的时间尺度,你可以考虑使用近似函数。如果没有,尝试取临时数据的对数,并拟合dulong函数的对数。如果算法在变量n时步数过大,这可能很有用

出于调试的目的,您可以在函数中添加一行,打印传递的参数,这样您就可以看到哪个参数的变化幅度有多大,并且可以从中进行操作。
作为另一项措施,您可以查看scipy.optimize中的最小化函数,在那里,您可以指定更多选项,如求解算法和步长,还可以传递雅可比矩阵以进一步提高效率。

当我使用
dulong
函数调用
curve\u fit
时,我得到以下警告:

RuntimeWarning:电源中遇到无效值

这表明,
曲线拟合
测试各种参数值时,
独龙
的评估需要计算形式为
(负实数)**(实数)
,这会导致复数。因此,优化过程失败

一种方法是限制参数的搜索空间,以避免出现此问题。在不知道参数的物理意义的情况下,我可以看出,只要
n
大于
1
并且所有其他参数都是非负的,
dulong
将只返回实数

如上所述,使用
bounds
选项调用
curve\u fit
,可以找到最佳参数

poptd, pcovd = curve_fit(dulong, Time, Temp, p0=[295, 0.155, 6000, 1.38], sigma=[1]*len(Temp), absolute_sigma=True,
                        bounds = ([0,0,0,1],[1000,1,10000,10]))

print(poptd)
[304.5965 0.0857 9999.1743 1.5099]

这是拟合的曲线图


由于我还不能发表评论,我将发布另一个答案作为对您评论的回复:第三个参数的大错误可能是由于算法不允许将其赋值超过10000。调整你的界限,它就会起作用。

正如温泽尔所说,
n
参数是这里的问题。如果将其固定为1.38,则
曲线拟合
函数将返回拟合:
3.11e+02 1.64e-01 5.03e+03
用于
ta、dift、f
。您好,我发现这非常有用。但是有一个问题,对应于f=9999的第三个参数与之相关联的是一个巨大的错误:sqrt(pcovd[2:2])。你知道如何减少这个错误吗?@VladimirVargas我真的不知道该如何解释这个“错误”(即,一个大的值是否意味着一个“不好的”匹配?),更不用说减少它了。但是,我也注意到,如果我们限制了搜索空间<<代码> f>代码>,使优化结果的值接近初始猜测(<代码> 6000 < /代码>),你认为它是“好”的,相应的错误也很大。如果我将sigma参数改变为0.01,然后我得到的误差比f的值小得多。I使用
param_bounds=np.数组([[250350],[0.12,0.13],[6000,80000],[1.3,1.5])。T
使用
poptd,pcovd=曲线拟合(dulong,Time,Temp,p0=[295,0.125,6000,1.38],sigma=[1]*len(Temp),绝对σ=True,bounds=param_bounds)
仍然会得到一个巨大的错误。超过100%,f为7.00099861e+03,sqrt(pcovd[2,2])为1.06431341e+04。我注意到,如果我在sigma中输入一个更低的值,例如0.01,那么误差会变为1.06431902e+02,这是可以接受的。