scipy curve_fit不能很好地工作

时间:2017-12-26 12:03:37

标签: python-3.x scipy curve-fitting

我正在尝试使用以下代码填充一些数据:

import numpy as np
import scipy.optimize
import matplotlib.pyplot as plt

def fseries(x, a0, a1, b1, w):
    f = a0 + (a1 * np.cos(w * x)) + (b1 * np.sin(w * x))
    return f

x = np.arange(0, 10)
y = [-45.0, -17.0, -33.0,  50.0, 48.0,  -3.0,  -1.0,   2.0,  84.0, 71.0]

res = scipy.optimize.curve_fit(fseries, x, y, maxfev=10000)

xt = np.linspace(0, 10, 100)
yt = fseries(xt, res[0][0], res[0][1], res[0][2], res[0][3])

plt.plot(x,y)
plt.plot(xt, yt, 'r')
plt.show()

这使得这个情节:

enter image description here

对我不理解或做错的任何想法?

1 个答案:

答案 0 :(得分:1)

首先,曲线拟合不是一个为任何给定数据集创建良好曲线的神奇设备。您不能很好地将指数曲线拟合到对数数据集。如果你查看你的数据,它看起来好像是你定义的函数描述的吗?它看起来不像是线性和正弦函数的叠加吗? 然后曲线拟合是一个迭代过程,它高度依赖于起始值。来自this

  

p0:无,标量或N长度序列,可选       初步猜测参数。如果为None,那么初始值将全部为1

为什么不为p0提供更好的猜测? 最后但并非最不重要的是,你得到了两个数组。我会读出两个,即使你只需要一个。它简化了您的代码。 试试

p0 = (10, 20, 20, 1.5)
res, _popcv = scipy.optimize.curve_fit(fseries, x, y, p0, maxfev=10000)
xt = np.linspace(0, 10, 100)
yt = fseries(xt, *res)

你已经更适合了。 scipy manual
当您使用

定义更好的拟合函数时,可以进一步提高拟合度
def fseries(x, a0, a1, b1, w):
    f = a0 * x + (a1 * np.cos(w * x)) + (b1 * np.sin(w * x))
    return f

enter image description here

此功能是否有用,您必须自行决定。仅仅因为它更适合数据集,并不意味着它适合您的情况。