我在拟合某些数据的曲线时遇到了一些麻烦,但无法计算出我要出错的地方。指数衰减曲线拟合在numpy和scipy中
在过去我曾与numpy.linalg.lstsq的指数函数和乙状结肠功能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包括数据集的一小部分。当拟合实际数据时,曲线呈现0.82的R^2,而与Excel计算的曲线相同的曲线具有0.41的R^2曲线,其曲线的R^2为0.41 。
谢谢@Jaime - 伟大的答案!不幸的是,我的数学知识不是很好,是一个写还是错的[也见上面的编辑],还是只是根本上不同......?例如,如果我想测试Sigmoid或Gompertz曲线对相同数据的拟合程度,对其他函数有什么影响? – StacyR
@StacyR我没有足够的知识来正确回答你的问题,但我相当确定,像'np.linalg.lstsq'那样拟合指数是一种快速的'不'计算技巧错误正确。这里有一些讨论(很难让我跟随):http://mathworld.wolfram.com/LeastSquaresFittingExponential.html如果你不想深入研究这些东西,我会用scipy的方法来处理所有事情:应该给予更好的配合,并且您的结果将对所有功能保持一致。 – Jaime
再次感谢!我已经做了一些更多的研究,正如你所提到的那样,发现'np.linalg.lstsq'方法在低x值时过度地加权y-错误。你分享的链接以及我发现的其他一些资源,使我得到了另外一种分析方法(使问题变得棘手的是约束 - 所有书籍都描述了y = a * e^b * x的方法)比y = e^b * x),但是,这也会产生比迭代式的'scipy.optimize.leastsq'更糟的拟合曲线。 – StacyR