scipy curve_fit效果不佳

问题描述 投票:1回答:1

我试图使用以下代码拟合一些数据:

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

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

python-3.x scipy curve-fitting
1个回答
1
投票

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

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)

而且你已经更适合了。 enter image description here 当您定义更好的拟合函数时,可以进一步提高拟合度

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

无论此功能是否有用,您都必须做出决定。仅仅因为它更适合数据集,并不意味着它在您的情况下是正确的描述符。

© www.soinside.com 2019 - 2024. All rights reserved.