【发布时间】:2014-03-23 21:47:53
【问题描述】:
至少乍一看,我有一个简单的x,y 数据集适合。问题是scipy.optimize.curve_fit 为拟合的参数之一返回了一个 very 大的值,我不知道这在数学上是否正确,或者我拟合数据的方式是否有问题.
下图以蓝色显示了数据点和获得的最佳拟合。使用的曲线(下面MWE 中的func)有四个参数a, b, c, d 正在拟合:
-
a大约给出了曲线达到一半最大值时的x值。 -
b表示曲线稳定处的x值。这个func值由d参数给出,即:func(b) = d -
c与曲线在原点的最大值有关:func(0) = c*constant + d -
d是曲线稳定的地方(图中黑线)。
b 参数是我遇到的问题(见问题结尾),它也是我最有兴趣分配合理值的参数。
MWE 显示正在拟合的函数和结果:
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
# Function to be fitted.
def func(x, a, b, c, d):
return c * (1 / np.sqrt(1 + (np.asarray(x) / a) ** 2) -
1 / np.sqrt(1 + (b / a) ** 2)) ** 2 + d
# Define x,y data.
x_list = [12.5, 37.5, 62.5, 87.5, 112.5, 137.5, 162.5, 187.5, 212.5, 237.5,
262.5, 287.5, 312.5, 337.5, 362.5, 387.5, 412.5, 437.5, 462.5, 487.5,
512.5]
y_list = [0.008, 0.0048, 0.0032, 0.00327, 0.0023, 0.00212, 0.00187,
0.00086, 0.00070, 0.00100, 0.00056, 0.00076, 0.00052, 0.00077, 0.00067,
0.00048, 0.00078, 0.00067, 0.00069, 0.00061, 0.00047]
# Initial guess for the 4 parameters.
guess = (50., 200., 80. / 10000., 6. / 10000.)
# Fit curve to x,y data.
f_prof, f_err = curve_fit(func, x_list, y_list, guess)
# Values for the a,b,c,d fitted parameters.
print f_prof
# Errors (standard deviations) for the fitted parameters.
print np.sqrt(f_err[0][0]), np.sqrt(f_err[1][1]), np.sqrt(f_err[2][2]),\
np.sqrt(f_err[3][3])
# Generate plot.
plt.scatter(x_list, y_list)
plt.plot(x_list, func(x_list, f_prof[0], f_prof[1], f_prof[2], f_prof[3]))
plt.hlines(y=f_prof[3], xmin=0., xmax=max(x_list))
plt.show()
我得到的结果是:
# a, b, c, d
52.74, 2.52e+09, 7.46e-03, 5.69e-04
# errors
11.52, 1.53e+16, 0.0028, 0.00042
b 参数值很大,错误也很大。通过查看图中绘制的数据,可以通过肉眼估计b 的值(即:数据集稳定的x 值)应该在x=300 附近。为什么b 和它的错误值这么大?
【问题讨论】:
-
恐怕问题出在您正在拟合的数据(或函数)上。首先,您的错误中有一个错字(应该是 f_err[1][1])。我已经使用全局求解器检查了您的示例,它在其他参数中给出了相同的结果,但我什至得到 b = 3.56564242e+18。但毫不奇怪,点 x = 300 附近的导数是一个真正的蜗牛——它接近最小值但非常慢。您可以手动检查 - 通过参数对数据计算偏导数,并尝试求解 4 个非线性方程组。
-
@Martin 感谢您指出错字,我已经修复它(虽然值很好)
-
我知道。我已经检查过了。
标签: python numpy scipy curve-fitting curve