SciPy 中的指数曲线拟合 [英] Exponential curve fitting in SciPy

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

问题描述

我有两个 NumPy 数组 xy.当我尝试使用指数函数和 curve_fit (SciPy) 与这个简单的代码

I have two NumPy arrays x and y. When I try to fit my data using exponential function and curve_fit (SciPy) with this simple code

#!/usr/bin/env python
from pylab import *
from scipy.optimize import curve_fit

x = np.array([399.75, 989.25, 1578.75, 2168.25, 2757.75, 3347.25, 3936.75, 4526.25, 5115.75, 5705.25])
y = np.array([109,62,39,13,10,4,2,0,1,2])

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

popt, pcov = curve_fit(func, x, y)

我得到了错误的系数 popt

[a,b,c,d] = [1., 1., 1., 24.19999988]

有什么问题?

推荐答案

第一条评论:因为 a*exp(b - c*x) = (a*exp(b))*exp(-c*x) = A*exp(-c*x)ab 是多余的.我将删除 b 并使用:

First comment: since a*exp(b - c*x) = (a*exp(b))*exp(-c*x) = A*exp(-c*x), a or b is redundant. I'll drop b and use:

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

这不是主要问题.问题很简单,当您使用默认的初始猜测(全为 1)时,curve_fit 无法收敛到此问题的解决方案.检查pcov;你会看到它是inf.这并不奇怪,因为如果 c 为 1,exp(-c*x) 的大部分值下溢为 0:

That isn't the main issue. The problem is simply that curve_fit fails to converge to a solution to this problem when you use the default initial guess (which is all 1s). Check pcov; you'll see that it is inf. This is not surprising, because if c is 1, most of the values of exp(-c*x) underflow to 0:

In [32]: np.exp(-x)
Out[32]: 
array([  2.45912644e-174,   0.00000000e+000,   0.00000000e+000,
         0.00000000e+000,   0.00000000e+000,   0.00000000e+000,
         0.00000000e+000,   0.00000000e+000,   0.00000000e+000,
         0.00000000e+000])

这表明 c 应该很小.例如,更好的初始猜测是 p0 = (1, 1e-6, 1).然后我得到:

This suggests that c should be small. A better initial guess is, say, p0 = (1, 1e-6, 1). Then I get:

In [36]: popt, pcov = curve_fit(func, x, y, p0=(1, 1e-6, 1))

In [37]: popt
Out[37]: array([  1.63561656e+02,   9.71142196e-04,  -1.16854450e+00])

这看起来很合理:

In [42]: xx = np.linspace(300, 6000, 1000)

In [43]: yy = func(xx, *popt)

In [44]: plot(x, y, 'ko')
Out[44]: [<matplotlib.lines.Line2D at 0x41c5ad0>]

In [45]: plot(xx, yy)
Out[45]: [<matplotlib.lines.Line2D at 0x41c5c10>]

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

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