numpy和scipy中的指数衰减曲线拟合

numpy和scipy中的指数衰减曲线拟合,numpy,scipy,curve-fitting,least-squares,exponential,Numpy,Scipy,Curve Fitting,Least Squares,Exponential,我在将曲线拟合到某些数据时遇到了一些问题,但无法找出哪里出了问题 在过去,我对指数函数使用了numpy.linalg.lstsq,对sigmoid函数使用了scipy.optimize.curve_fit。这次我希望创建一个脚本,让我可以指定各种函数、确定参数并根据数据测试它们的适合性。在这样做时,我注意到Scipyleastsq和Numpylstsq似乎为相同的数据集和相同的函数提供了不同的答案。该函数只是y=e^(l*x),并且受到约束,使得y=1处于x=0 Excel趋势线与Numpyls

我在将曲线拟合到某些数据时遇到了一些问题,但无法找出哪里出了问题

在过去,我对指数函数使用了numpy.linalg.lstsq,对sigmoid函数使用了scipy.optimize.curve_fit。这次我希望创建一个脚本,让我可以指定各种函数、确定参数并根据数据测试它们的适合性。在这样做时,我注意到Scipy
leastsq
和Numpy
lstsq
似乎为相同的数据集和相同的函数提供了不同的答案。该函数只是
y=e^(l*x)
,并且受到约束,使得
y=1
处于
x=0

Excel趋势线与Numpy
lstsq
结果一致,但由于Scipy
leastsq
能够执行任何功能,因此最好找出问题所在

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,而numpy.linalg.lstsq曲线的R^2为0.41,与Excel计算的曲线相同。

您正在最小化不同的误差函数

使用
numpy.linalg.lstsq
时,将最小化错误函数

np.sum((np.log(y) - p * x)**2)
scipy.optimize.leastsq
将函数最小化

np.sum((y - np.exp(p * x))**2)
第一种情况要求因变量和自变量之间存在线性依赖关系,但解决方案在分析中是已知的,而第二种情况可以处理任何依赖关系,但依赖于迭代方法

另一方面,我现在无法对其进行测试,但在使用
numpy.linalg.lstsq
时,您不需要
vstack
一行零,以下操作也可以:

l2 = np.linalg.lstsq(x[:, None], np.log(y))[0][0]

为了阐明Jaime的观点,数据的任何非线性变换都会导致不同的误差函数,从而导致不同的解决方案。这将导致拟合参数的置信区间不同。所以你有三个可能的标准来做决定:你想最小化哪一个误差,你想对哪一个参数更有信心,最后,如果你使用拟合来预测某个值,哪一种方法在有趣的预测值中产生的误差更小。在Excel中进行分析表明,数据中不同类型的噪声(例如,如果噪声函数缩放振幅、影响时间常数或是相加的)会导致不同的解决方案选择


我还要补充一点,虽然这个技巧对指数衰减为0“有效”,但它不能用于更一般(和常见)的情况,即阻尼指数(上升或下降)的值不能假定为0。

谢谢@Jaime-很好的答案!不幸的是,我的数学知识不是那么好;是一篇文章写错了(也请参见上面的编辑),还是它们根本不同。。。?例如,如果我想测试Sigmoid或Gompertz曲线与相同数据的拟合度,那么对其他函数有什么影响?@StacyR我不知道如何正确回答你的问题,但是我很确定,像你用
np.linalg.lstsq
那样拟合一个指数只是一个快速、肮脏的把戏,不能正确地计算错误。这里有一些讨论(我很难理解):如果你不想深入研究这个问题,我会选择scipy的方法:它应该提供更好的拟合,并且你的结果对于所有函数都是一致的。再次感谢!我在这方面做了更多的研究,正如您所提到的,我发现
np.linalg.lstsq
方法在低x值时对y误差的权重过高。您共享的链接,以及我找到的其他一些资源,允许我推导出另一种分析方法(让它变得棘手的是约束——所有的书都描述了y=ae^bx而不是y=e^b*x的方法),但是,这也会产生比迭代的
scipy.optimize.leastsq
更糟糕的拟合曲线。