为什么scipy.optimize.curve_fit不能正确匹配数据?

时间:2013-10-11 09:11:02

标签: python numpy matplotlib curve-fitting data-fitting

我一直在尝试使用scipy.optimize.curve_fit将函数拟合到某些数据,但我确实遇到了困难。我真的看不出有什么理由不起作用。

# encoding: utf-8
from __future__ import (print_function,
                        division,
                        unicode_literals,
                        absolute_import,
                        with_statement)
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as mpl

x, y, e_y = np.loadtxt('data.txt', unpack=True)

def f(x, a, k):
    return (1/(np.sqrt(1 + a*((k-x)**2))))

popt, pcov = curve_fit(f, x, y, maxfev = 100000000)

mpl.plot(x, f(x, *popt), 'r-', label='Fit')
mpl.plot(x, y, 'rx', label='Original')
mpl.legend(loc='best')
mpl.savefig('curve.pdf')
print(popt)

# correct values which should be calculated
# a=0.003097
# k=35.4

这是由上层代码生成的情节图像: enter image description here

data.txt:
#x      y       e_y
4.4     0.79    0.13
19.7    4.9     0.8
23.5    7.3     1.2
29.7    17      2.79
30.7    21.5    3.52
34      81      13.28
34.6    145     23.77
35.4    610     100
36.3    115     18.85
38.1    38      6.23
43.7    14      2.3
56.2    6.2     1.02
64.7    4.6     0.75
79.9    3.2     0.52
210     0.98    0.16

2 个答案:

答案 0 :(得分:14)

首先尽量不要增加maxfev这么大,这通常是其他问题出现的迹象!在附近玩耍我可以通过以下添加得到合适的结果:

def f(x, b, a, k):
    return (b/(np.sqrt(1 + a*((k-x)**2))))

popt, pcov = curve_fit(f, x, y, p0=[20, 600.0, 35.0])

首先给出你给出的拟合函数最多为1,因为数据中的峰值为600,它永远不适合。所以我添加了一个整体因子b。其次,尝试帮助穷人的旧曲线。如果用眼睛看,它可以在x~35处看到峰值,然后通过p0告诉它。这需要一些关于函数如何工作的直觉,但如果你要使用曲线拟合函数则非常重要。

enter image description here

答案 1 :(得分:1)

我查看了X-Y散点图上的原始数据,拟合此数据的等式似乎需要非常尖锐,窄的峰值。您给出的等式不会产生峰值响应。在我看来,由于这个原因,这些数据与给定方程的拟合将不起作用。