简体   繁体   English

scipy.optimize.curve_fit() 未能拟合指数函数

[英]scipy.optimize.curve_fit() failed to fit a exponential function

I'm trying to fit a exponential function by using scipy.optimize.curve_fit() (The example data and code as following).我试图通过使用scipy.optimize.curve_fit() (示例数据和代码如下)来拟合指数函数。 But it always shows a RuntimeError like this: RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 5000. I'm not sure where I'm going wrong.但它总是显示这样的RuntimeErrorRuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 5000.我不确定我哪里出错了。

import numpy as np
from scipy.optimize import curve_fit

x = np.arange(-1, 1, .01)
param1 = [-1, 2, 10, 100]
fit_func = lambda x, a, b, c, d: a * np.exp(b * x + c) + d
y = fit_func(x, *param1)
popt, _ = curve_fit(fit_func, x, y, maxfev=5000)

This is almost certainly due to the initial guess for the parameters.这几乎可以肯定是由于对参数的初始猜测。

You don't pass an initial guess to curve_fit , which means it defaults to a value of 1 for every parameter.您没有将初始猜测传递给curve_fit ,这意味着它默认为每个参数的值1 Unfortunately, this is a terrible guess in your case.不幸的是,在您的情况下,这是一个糟糕的猜测。 The function of interest is an exponential, one property of which is that the derivative is also an exponential.感兴趣的函数是指数函数,其一个特性是导数也是指数函数。 So all derivatives (first-order, second-order, etc) will be not just wrong, but have the wrong sign .所以所有的导数(一阶、二阶等)不仅是错误的,而且有错误的符号 This means the optimizer will have a very difficult time making progress.这意味着优化器将很难取得进展。

You can solve this by giving the optimizer just a smidge of help.您可以通过给优化器只是一个帮助微幅下挫解决这个问题。 Since you know all your data is negative, you could just pass -1 as an initial guess for the first parameter (the scale or amplitude of the function).由于您知道所有数据都是负数,因此您可以将-1作为第一个参数(函数的比例或幅度)的初始猜测值传递。 This alone is enough to for the optimizer to arrive at a reasonable guess.仅此一项就足以让优化器得出合理的猜测。

p0 = (-1, 1, 1, 1)
popt, _ = curve_fit(x, y, p0=p0, maxfev=5000)
fig, ax = plt.subplots()
ax.plot(x, y, label="Data", color="k")
ax.plot(x, fit_func(x, *popt), color="r", linewidth=3.0, linestyle=":", label="Fitted")
fig.tight_layout()

You should see something like this:您应该会看到如下内容: 在此处输入图片说明

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

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