简体   繁体   English

scipy curve_fit 效果不佳

[英]scipy curve_fit doesn't work well

I am trying to fit some data using the following code:我正在尝试使用以下代码拟合一些数据:

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()

Which makes this plot:这使得这个情节:

在此处输入图片说明

Any thoughts on what I am not understanding or doing wrong?关于我不理解或做错的任何想法?

First of all, curve fitting is not a magical device that creates a good curve for any given data set.首先,曲线拟合并不是为任何给定数据集创建良好曲线的神奇设备。 You can't fit an exponential curve well to a logarithmic data set.您无法将指数曲线很好地拟合到对数数据集。 If you look at your data, does it look like it is well described by the function you define?如果您查看您的数据,是否您定义的函数对其进行了很好的描述? Doesn't it rather look like an overlay of a linear and a sine function?是不是看起来更像是线性函数和正弦函数的叠加?
Then curve fitting is an iterative process, that is highly dependent on start values.那么曲线拟合是一个迭代过程,它高度依赖于起始值。 From the scipy manual :scipy 手册

p0 : None, scalar, or N-length sequence, optional Initial guess for the parameters. p0 :无、标量或 N 长度序列,可选参数的初始猜测。 If None, then the initial values will all be 1如果没有,那么初始值都将是 1

Why not provide a better guess for p0 ?为什么不为p0提供更好的猜测?
Last but not least, you get back two arrays.最后但并非最不重要的是,你会得到两个数组。 I would read out both, even if you only need one.我会读出两者,即使你只需要一个。 It simplifies your code.它简化了您的代码。 Try尝试

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)

and you get already a better fit.你已经更适合了。 在此处输入图片说明
You can improve the fit further, when you define a better fit function with当您定义更好的拟合函数时,您可以进一步改进拟合

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

在此处输入图片说明

Whether this function is useful, you have to decide.这个功能是否有用,你必须决定。 Just because it fits better the data set, doesn't mean it is the right descriptor in your situation.仅仅因为它更适合数据集,并不意味着它是适合您情况的正确描述符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM