python - 指数曲线拟合不适合

标签 python scipy curve-fitting

尝试绘制一组数据的指数曲线时:

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

x = np.array([30,40,50,60])
y = np.array([0.027679854,0.055639098,0.114814815,0.240740741])

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

popt, pcov = curve_fit(exponenial_func, x, y, p0=(1, 1e-6, 1))

xx = np.linspace(10,60,1000)
yy = exponenial_func(xx, *popt)

plt.plot(x,y,'o', xx, yy)
pylab.title('Exponential Fit')
ax = plt.gca()
fig = plt.gcf()

plt.xlabel(r'Temperature, C')
plt.ylabel(r'1/Time, $s^-$$^1$')

plt.show()

上面代码的图表:

Exponential curve fitting the data points. Click to enlarge.

但是,当我添加数据点 20 (x) 和 0.015162344 (y) 时:

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

x = np.array([20,30,40,50,60])
y = np.array([0.015162344,0.027679854,0.055639098,0.114814815,0.240740741])

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

popt, pcov = curve_fit(exponenial_func, x, y, p0=(1, 1e-6, 1))

xx = np.linspace(20,60,1000)
yy = exponenial_func(xx, *popt)

plt.plot(x,y,'o', xx, yy)
pylab.title('Exponential Fit')
ax = plt.gca()
fig = plt.gcf()

plt.xlabel(r'Temperature, C')
plt.ylabel(r'1/Time, $s^-$$^1$')

plt.show()

上面的代码产生了错误

'RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 800.'

如果 maxfev 设置为 maxfev = 1300

popt, pcov = curve_fit(exponenial_func, x, y, p0=(1, 1e-6, 1),maxfev=1300)

图形已绘制但未正确拟合曲线。上面代码更改的图表,maxfev = 1300:

Exponential curve not fitting the data points. Click to enlarge.

我认为这是因为点 20 和 30 a 太靠近了?为了比较,excel 绘制数据如下:

Exponential curve fitting the data points. Click to enlarge.

如何正确绘制这条曲线?

最佳答案

根据您的数据,很明显您需要一个正指数,因此,b 在您使用 a*np.exp(-b*x) + c< 时需要为负 作为底层模型。但是,您从 b 的正初始值开始,这很可能会导致问题。

如果你改变

popt, pcov = curve_fit(exponenial_func, x, y, p0=(1, 1e-6, 1))

popt, pcov = curve_fit(exponenial_func, x, y, p0=(1, -1e-6, 1))

它工作正常并给出了预期的结果。

enter image description here

或者,您也可以将等式更改为

return a*np.exp(b*x) + c

并以与您相同的初始值开始。

完整代码如下:

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


def exponenial_func(x, a, b, c):
    return a*np.exp(b*x)+c


x = np.array([20, 30, 40, 50, 60])
y = np.array([0.015162344, 0.027679854, 0.055639098, 0.114814815, 0.240740741])


popt, pcov = curve_fit(exponenial_func, x, y, p0=(1, 1e-6, 1))

xx = np.linspace(20, 60, 1000)
yy = exponenial_func(xx, *popt)

# please check whether that is correct
r2 = 1. - sum((exponenial_func(x, *popt) - y) ** 2) / sum((y - np.mean(y)) ** 2)

plt.plot(x, y, 'o', xx, yy)
plt.title('Exponential Fit')
plt.xlabel(r'Temperature, C')
plt.ylabel(r'1/Time, $s^-$$^1$')
plt.text(30, 0.15, "equation:\n{:.4f} exp({:.4f} x) + {:.4f}".format(*popt))
plt.text(30, 0.1, "R^2:\n {}".format(r2))

plt.show()

关于python - 指数曲线拟合不适合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48099026/

相关文章:

python - 使用具有向后依赖性的 scipy 进行曲线拟合

matlab - 从曲线外部用户给定的点查找曲线上的切点

math - 曲线拟合 : Find the smoothest function that satisfies a list of constraints

Python - Pandas - 对特定子集的 dropna 调用期间出现关键错误

python - `pipenv install` 和 `pipenv lock` 有什么区别?

python - 使用 in1d 函数测试数组之间的相等性

python - 使用 numpy 和 scipy 将数组转换为标量

Python - 创建 aws lambda 部署包

python - 如何去掉小数中无用的零位?

python - Pandas 系列 - 仅当指数月份位于 [1,2,3] 时才保留值(value)