【问题标题】:scipy.optimize.curve_fit failing to fit curvescipy.optimize.curve_fit 无法拟合曲线
【发布时间】:2016-04-25 23:02:29
【问题描述】:

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

xdata = [0.03447378,  0.06894757,  0.10342136,  0.13789514,  0.17236893,
    0.20684271,  0.24131649,  0.27579028,  0.31026407,  0.34473785,
    0.37921163,  0.41368542,  0.44815921,  0.48263299]

ydata = [ 2.5844 ,  2.87449,  3.01929,  3.10584,  3.18305,  3.24166,
    3.28897,  3.32979,  3.35957,  3.39193,  3.41662,  3.43956,
    3.45644,  3.47135]

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
def func(x, a, b, c, d):
    return a + b*x - c*np.exp(-d*x)

popt, pcov = curve_fit(func, xdata, ydata))
plt.figure()
plt.plot(xdata, ydata, 'ko', label="Original Noised Data")
plt.plot(xdata, func(xdata, *popt), 'r-', label="Fitted Curve")
plt.legend()
plt.show()

曲线没有被拟合:

Data fit with straight line - should be curve

我应该怎么做才能正确拟合数据?

【问题讨论】:

  • poptpcov 的哪些值被 curve_fit() 返回?

标签: python optimization scipy curve


【解决方案1】:

看起来优化器陷入了局部最小值,或者可能只是目标函数的一个非常平坦的区域。通过调整curve_fit 使用的参数的初始猜测,可以找到更好的拟合。例如,我得到了与p0=[1, 1, 1, 2.0] 的合理匹配(默认为 [1, 1, 1, 1]):

这是我使用的脚本的修改版本:

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


def func(x, a, b, c, d):
    return a + b*x - c*np.exp(-d*x)


xdata = np.array([0.03447378,  0.06894757,  0.10342136,  0.13789514,  0.17236893,
    0.20684271,  0.24131649,  0.27579028,  0.31026407,  0.34473785,
    0.37921163,  0.41368542,  0.44815921,  0.48263299])

ydata = np.array([ 2.5844 ,  2.87449,  3.01929,  3.10584,  3.18305,  3.24166,
    3.28897,  3.32979,  3.35957,  3.39193,  3.41662,  3.43956,
    3.45644,  3.47135])

p0 = [1, 1, 1, 2.0]

popt, pcov = curve_fit(func, xdata, ydata, p0=p0)
print(popt)

plt.figure()
plt.plot(xdata, ydata, 'ko', label="Original Noised Data")
plt.plot(xdata, func(xdata, *popt), 'r-', label="Fitted Curve")
plt.legend(loc='best')
plt.show()

打印输出为:

[  3.13903988   0.71827903   0.97047248  15.40936232]

【讨论】:

  • 遇到了与操作类似的问题。大多数时候 p0 值是错误的。可以补充一点,对于每个标量值,可能有两个方向;)
【解决方案2】:

请尝试更具体地说明您遇到的问题。

我注意到有两件事会阻止您的代码按原样工作:

  • 第 15 行(curve_fit() 调用),行尾有一个额外的右括号
  • xdata 是一个 python 列表,所以一旦你尝试将它与 func 中的参数相乘,这将不起作用,即将它变成一个 numpy 数组 xdata = np.array(xdata)

如果你解决了这两个问题,那么合适的应该会起作用。

编辑:沃伦当然是对的 - 解决上述问题仍然会让你从错误的最低限度开始。

【讨论】:

    猜你喜欢
    • 2014-01-02
    • 2019-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-29
    • 1970-01-01
    • 1970-01-01
    • 2021-01-19
    相关资源
    最近更新 更多