指数曲线拟合不适合 [英] Exponential curve fit will not fit

查看:186
本文介绍了指数曲线拟合不适合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When attempting to plot an exponential curve to a set of data:

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

上述代码的图形:

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

However when I add the data point 20 (x) and 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:找不到最佳参数:
函数的调用次数已达到maxfev = 800。'

'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

The graph is plotted but does not fit the curve correctly. Graph from above code change, maxfev = 1300:

我认为这是因为点20和30 a彼此之间太近了吗?为了进行比较,excel会像这样绘制数据:

I think this is because points 20 and 30 a too close to each other? For comparison, excel plots the data like this:

如何正确绘制此曲线?

推荐答案

从您的数据中可以明显看出需要一个正指数,因此,当您使用 a * np.exp(-b * x)+ c b 需要为负c $ c>作为基础模型。但是,您以 b 的正初始值开头,这很可能会引起问题。

From your data it is obvious that you need a positive exponent, therefore, b needs to be negative as you use a*np.exp(-b*x) + c as the underlying model. However, you start with a positive initial value for b which most likely causes the issues.

如果更改

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

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

it works fine and gives the expected outcome.

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

Alternatively, you could also change your equation to

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

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

and start with the same initial values as you had.

这是完整的代码:

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

这篇关于指数曲线拟合不适合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆