我认为您可以使用(文档)的功能curve_fit
。一个基本的用法示例:scipy.optimize
import numpy as np
from scipy.optimize import curve_fit
def func(x, a, b, c):
return a*x**2 + b*x + c
x = np.linspace(0,4,50)
y = func(x, 5, 3, 4)
yn = y + 0.2*np.random.normal(size=len(x))
popt, pcov = curve_fit(func, x, yn)
根据文档, pcov 给出:
popt 的估计协方差。对角线提供参数估计的方差。
因此,您可以通过这种方式计算系数的误差估计。要获得标准偏差,您可以取方差的平方根。
现在您对系数有一个错误,但它仅基于 ydata 和拟合之间的偏差。如果您还想解释 ydata 本身的错误,该curve_fit
函数提供sigma
参数:
sigma :无或 N 长度序列
如果不是 None,则表示 ydata 的标准差。如果给定,该向量将用作最小二乘问题中的权重。
一个完整的例子:
import numpy as np
from scipy.optimize import curve_fit
def func(x, a, b, c):
return a*x**2 + b*x + c
x = np.linspace(0,4,20)
y = func(x, 5, 3, 4)
# generate noisy ydata
yn = y + 0.2 * y * np.random.normal(size=len(x))
# generate error on ydata
y_sigma = 0.2 * y * np.random.normal(size=len(x))
popt, pcov = curve_fit(func, x, yn, sigma = y_sigma)
# plot
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.errorbar(x, yn, yerr = y_sigma, fmt = 'o')
ax.plot(x, np.polyval(popt, x), '-')
ax.text(0.5, 100, r"a = {0:.3f} +/- {1:.3f}".format(popt[0], pcov[0,0]**0.5))
ax.text(0.5, 90, r"b = {0:.3f} +/- {1:.3f}".format(popt[1], pcov[1,1]**0.5))
ax.text(0.5, 80, r"c = {0:.3f} +/- {1:.3f}".format(popt[2], pcov[2,2]**0.5))
ax.grid()
plt.show()
![结果](https://i.stack.imgur.com/Bh25R.png)
然后是其他的,关于使用 numpy 数组。使用 numpy 的主要优点之一是您可以避免 for 循环,因为数组上的操作按元素应用。因此,您示例中的 for 循环也可以按如下方式完成:
trendx = arange(datasetx[0], (datasetx[-1]+1))
trendy = trend[0]*trendx**2 + trend[1]*trendx + trend[2]
我在哪里使用arange
而不是范围,因为它返回一个 numpy 数组而不是列表。在这种情况下,您还可以使用 numpy 函数polyval
:
trendy = polyval(trend, trendx)