拟合曲线

用于拟合曲线的例程是 scipy.optimize 模块和 scipy.optimize.curve_fit() .因此,首先必须导入所述模块。

>>> import scipy.optimize

必须使用 x 值作为第一个参数,所有参数作为后续参数。

>>> def parabola(x, a, b, c):
...     return a*x**2 + b*x + c
...

出于测试目的,数据是使用具有已知参数的所述函数生成的。

>>> params = [-0.1, 0.5, 1.2]
>>> x = np.linspace(-5, 5, 31)
>>> y = parabola(x, params[0], params[1], params[2])
>>> plt.plot(x, y, label='analytical')  
[<matplotlib.lines.Line2D object at ...>]
>>> plt.legend(loc='lower right')  
<matplotlib.legend.Legend object at ...>
>>> plt.show()
../_images/fitting_curves-3.png

然后引入了一些小偏差,将函数拟合到由它自己生成的数据中是一种无聊的做法。

>>> r = np.random.RandomState(42)
>>> y_with_errors = y + r.uniform(-1, 1, y.size)
>>> plt.plot(x, y_with_errors, label='sample')  
[<matplotlib.lines.Line2D object at ...>]
>>> plt.legend(loc='lower right')  
<matplotlib.legend.Legend object at ...>
>>> plt.show()
../_images/fitting_curves-4.png

现在可以调用拟合例程。

>>> fit_params, pcov = scipy.optimize.curve_fit(parabola, x, y_with_errors)

它返回两个结果,即拟合产生的参数以及协方差矩阵,可用于计算拟合的某种形式的质量尺度。拟合的实际数据可与实际参数进行比较:

>>> for param, fit_param in zip(params, fit_params):
...     print(param, fit_param)
...
-0.1 -0.0906682795944
0.5 0.472361903203
1.2 1.00514576223
>>> y_fit = parabola(x, *fit_params)
>>> plt.plot(x, y_fit, label='fit')  
[<matplotlib.lines.Line2D object at ...>]
>>> plt.legend(loc='lower right')  
<matplotlib.legend.Legend object at ...>
>>> plt.show()
../_images/fitting_curves-6.png

如您所见,第三个参数的拟合相当不合适。 c .查看协方差矩阵也可以看到:

>>> print(pcov)
[[  1.64209005e-04   1.75357845e-12  -1.45963560e-03]
 [  1.75357845e-12   1.16405938e-03  -1.73642112e-11]
 [ -1.45963560e-03  -1.73642112e-11   2.33217333e-02]]

但为了获得更具意义的拟合质量,文件建议如下:

>>> print(np.sqrt(np.diag(pcov)))
[ 0.01281441  0.03411831  0.15271455]

所以适合 a 很好,但是质量 c 是所有参数中最差的。

注解

这个程序通过迭代改变参数并检查拟合是否变好或变差来工作。为了帮助程序找到最佳的适合性,最好给它一个好的起点。可以使用 p0 的参数 curve_fit() .在某些情况下,这甚至是必要的。

练习