我在将曲线拟合到某些数据时遇到了一些麻烦,但无法弄清楚我哪里出错了。
在过去,我使用numpy.linalg.lstsq来完成指数函数,使用scipy.optimize.curve_fit来完成 sigmoid 函数。这一次,我希望创建一个脚本,让我指定各种函数、确定参数并测试它们与数据的匹配度。在执行此操作时,我注意到 Scipyleastsq
和 Numpylstsq
似乎为相同的数据集和相同的函数提供了不同的答案。该函数很简单y = e^(l*x)
,并且受到约束,使得y=1
在x=0
。
Excel 趋势线与 Numpylstsq
结果一致,但由于 Scipyleastsq
能够采用任何功能,因此最好找出问题所在。
import scipy.optimize as optimize
import numpy as np
import matplotlib.pyplot as plt
## Sampled data
x = np.array([0, 14, 37, 975, 2013, 2095, 2147])
y = np.array([1.0, 0.764317544, 0.647136491, 0.070803763, 0.003630962, 0.001485394, 0.000495131])
# function
fp = lambda p, x: np.exp(p*x)
# error function
e = lambda p, x, y: (fp(p, x) - y)
# using scipy least squares
l1, s = optimize.leastsq(e, -0.004, args=(x,y))
print l1
# [-0.0132281]
# using numpy least squares
l2 = np.linalg.lstsq(np.vstack([x, np.zeros(len(x))]).T,np.log(y))[0][0]
print l2
# -0.00313461628963 (same answer as Excel trend line)
# smooth x for plotting
x_ = np.arange(0, x[-1], 0.2)
plt.figure()
plt.plot(x, y, 'rx', x_, fp(l1, x_), 'b-', x_, fp(l2, x_), 'g-')
plt.show()
编辑 - 附加信息
上面的 MWE 包括数据集的一个小样本。拟合实际数据时,scipy.optimize.curve_fit曲线的 R^2 为 0.82,而与 Excel 计算的numpy.linalg.lstsq曲线的 R^2 为 0.41。