Scipy curvefit运行时错误:未找到最佳参数:函数的调用次数已达到maxfev = 1000

51

我想做一个对数拟合,但是我一直遇到运行时错误:

未找到最佳参数: 调用函数的次数已达到 maxfev = 1000

我使用下面的脚本。有人能告诉我哪里出了问题吗?我使用Spyder,并且还是初学者。

import math
import matplotlib as mpl
from scipy.optimize import curve_fit
import numpy as np

#data
F1=[735.0,696.0,690.0,683.0,680.0,678.0,679.0,675.0,671.0,669.0,668.0,664.0,664.0]
t1=[1,90000.0,178200.0,421200.0,505800.0,592200.0,768600.0,1036800.0,1371600.0,1630800.0,1715400.0,2345400.0,2409012.0]

F1n=np.array(F1)
t1n=np.array(t1)

plt.plot(t1,F1,'ro',label="original data")

# curvefit
def func(t,a,b):
    return a+b*np.log(t)

t=np.linspace(0,3600*24*28,13)

popt, pcov = curve_fit(func, t, F1n, maxfev=1000)    

plt.plot(t, func(t, *popt), label="Fitted Curve")

plt.legend(loc='upper left')
plt.show()

你也可以查看这个答案:使用SciPy曲线拟合库处理大数据集时出现RuntimeError - Fateme Pasandide
4个回答

41
Scipy的
     curve_fit() 

使用迭代来寻找最佳参数。如果迭代次数超过默认的 800 次,但仍然无法找到最佳参数,则会引发此错误。

    Optimal parameters not found: Number of calls to function has reached maxfev = 800
你可以为curve_fit()提供一些初始猜测参数,然后再尝试。或者,你可以增加允许的迭代次数。或者两者都做!
这里是一个例子:
    popt, pcov = curve_fit(exponenial_func, x, y, p0=[1,0,1], maxfev=5000)

p0是猜测值。

maxfev是最大迭代次数。

您还可以尝试设置边界,这将帮助函数找到解决方案。 但是,您不能同时设置边界和max_nfev。

    popt, pcov = curve_fit(exponenial_func, x, y, p0=[1,0,1], bounds=(1,3))

来源1:https://github.com/scipy/scipy/issues/6340

来源2:经过我的测试,发现关于Github的内容并不完全准确。

此外,不使用0作为“x”值的建议也是好建议。请从1开始定义您的“x”数组以避免除以零错误。


同时,这个问题已经被修复,现在两者可以同时设置。 - kjyv

24

您的原始数据是 t1F1。因此,curve_fit 应该将 t1 作为其第二个参数传入,而不是 t

popt, pcov = curve_fit(func, t1, F1, maxfev=1000)

现在,一旦你获得了拟合参数popt,你可以在t点评估func,以获得拟合曲线:

t = np.linspace(1, 3600 * 24 * 28, 13)
plt.plot(t, func(t, *popt), label="Fitted Curve")

我从 StuGrey 的回答中删除了 t 中的零,以避免出现 Warning: divide by zero encountered in log 警告。


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

# data
F1 = np.array([
    735.0, 696.0, 690.0, 683.0, 680.0, 678.0, 679.0, 675.0, 671.0, 669.0, 668.0,
    664.0, 664.0])
t1 = np.array([
    1, 90000.0, 178200.0, 421200.0, 505800.0, 592200.0, 768600.0, 1036800.0,
    1371600.0, 1630800.0, 1715400.0, 2345400.0, 2409012.0])

plt.plot(t1, F1, 'ro', label="original data")

# curvefit

def func(t, a, b):
    return a + b * np.log(t)

popt, pcov = optimize.curve_fit(func, t1, F1, maxfev=1000)
t = np.linspace(1, 3600 * 24 * 28, 13)
plt.plot(t, func(t, *popt), label="Fitted Curve")
plt.legend(loc='upper left')
plt.show()

enter image description here


当尝试使用非线性最小二乘回归来找到指数函数的最佳拟合时,为什么拟合图会呈现线性? - bonCodigo

3

curve_fit() 使用迭代搜索最优参数。如果迭代次数超过设置的1000次,但仍未找到最优参数,则会引发此错误。您可以提供一些初始猜测参数给 curve_fit(),然后再尝试。


2

在修复您的导入语句后:

#import matplotlib as mpl
import matplotlib.pyplot as plt

你的代码产生了以下错误:

RuntimeWarning: divide by zero encountered in log

更改:

#t=np.linspace(0,3600*24*28,13)
t=np.linspace(1,3600*24*28,13)

生成了以下输出:

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接