曲线拟合因指数而失败,但zunzun正确 [英] Curve fit fails with exponential but zunzun gets it right

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

问题描述

我正在尝试计算两种形式的指数与某些 x,y 数据的最佳拟合(可以从此处



代码如下:

  from scipy.optimize import curve_fit 
import numpy as np

#获取x,y数据
数据= np.loadtxt('data.txt',unpack = True)
xdata,ydata = data [0],data [1]

#定义第一个指数函数
def func (x,a,b,c):
返回a * np.exp(b * x)+ c

#获取参数估计值
popt,pcov = curve_fit(func ,xdata,ydata)

print popt

#定义第二个指数函数(一个以上的参数)
def func2(x,a,b,c,d) :
返回a * np.exp(b * x + c)+ d

#获取参数估计
popt2,pcov2 = curve_fit(func2,xdata,ydata)

print popt2

第一个指数给出的值完全相同es as zunzun.com(在此处使用PDF ),价格为 popt

  [7.67760545e-15 1.52175476e + 00 2.15705939e-02] 

,但是第二个给出的值显然对于 popt2 是错误的:

  [-1.26136676e + 02 -8.13233297e-01 -6.66772692e + 01 3.63133641e-02] 

这是zunzun.com的值(在此处单击PDF )以获取相同的第二个功能:

  a = 6.2426224704624871E-15 
b = 1.5217697532005228E + 00
c = 2.0660424037614489E-01
d = 2.1570805929514186E-02

我尝试按照此处推荐的方法制作列表数组 Python(scipy的奇怪结果)曲线合适,但这无济于事。我在这里做什么错了?






加1



我猜想问题与缺少初始值有关(我在喂我的函数(如此处所述:



如果我像这样将第一个指数的估计值馈入第二个指数(使新参数 d 最初为零):

  popt2,pcov2 = curve_fit(func2,xdata,ydata,p0 = [popt [0],popt [1],popt [2] ,0])

与zunzun.com相比,我得到的结果很合理,但仍然不正确:

  [1.22560853e-14 1.52176160e + 00 -4.67859961e-01 2.15706930e-02] 

现在问题变成了:我该如何为第二个函数提供更多的原因

解决方案

请注意,估算中的 a = 0 在您的第一个模型中。因此,他们只是在估计一个常数。因此,在第一种情况下, b b c



在我上次查看它时,Zunzun还使用差分进化作为全局求解器。 Scipy现在已经成为了看起来不错的全局优化器,这在可能出现局部最小值的情况下值得尝试。



我的便宜方式,因为参数不在您的示例中没有很大的范围:尝试随机起始值

  np.random.seed(1)
err_last = 20
最佳=无

对于范围(10)中的i:
开始= np.random.uniform(-10,10,size = 4)
#获取参数估计
尝试:
popt2,pcov2 = curve_fit(func2,xdata,ydata,p0 = start)
,除了RuntimeError:
Continue
err =( (ydata-func2(xdata,* popt2))** 2).sum()
如果err< err_last:
err_last =错误
打印err
最佳= popt2


za = 6.2426224704624871E-15
zb = 1.5217697532005228E + 00
zc = 2.0660424037614489E-01
zd = 2.1570805929514186E-02

zz = np.array([za,zb,zc,zd])
打印' zz',zz
print'cf',最佳

print'zz',((ydata-func2(xdata,* zz))** 2).sum()
打印'cf',err_last

最后一部分打印(zz是zunzun,cf是curve_fit)

  zz [6.24262247e-15 1.52176975e + 00 2.06604240e-01 2.15708059e-02] 
cf [1.24791299e -16 1.52176944e + 00 4.11911831e + 00 2.15708019e-02]
zz 9.52135153898
cf 9.52135153904

b c 的参数与Zunzun不同,但残差平方和相同。 / p>

加法



a * np.exp(b * x + c)+ d = np.exp(b * x +(c + np.log(a)))+ d





a * np.exp(b * x + c)+ d =(a * np .exp(c))* np.exp(b * x)+ d



第二个功能与第一个功能并没有什么不同功能。 a c 没有单独标识。因此,使用派生信息的优化器也会遇到问题,因为如果我正确看到的话,雅可比行列在某些方向上是奇异的。


I'm trying to compute the best fit of two forms of an exponential to some x, y data (the data file can be downloaded from here)

Here's the code:

from scipy.optimize import curve_fit
import numpy as np

# Get x,y data
data = np.loadtxt('data.txt', unpack=True)
xdata, ydata = data[0], data[1]

# Define first exponential function
def func(x, a, b, c):
    return a * np.exp(b * x) + c

# Get parameters estimate
popt, pcov = curve_fit(func, xdata, ydata)

print popt

# Define second exponential function (one more parameter)
def func2(x, a, b, c, d):
    return a * np.exp(b * x + c) + d

# Get parameters estimate
popt2, pcov2 = curve_fit(func2, xdata, ydata)

print popt2

The first exponential gives the exact same values as zunzun.com (PDF here) for popt:

[  7.67760545e-15   1.52175476e+00   2.15705939e-02]

but the second gives values that are clearly wrong for popt2:

[ -1.26136676e+02  -8.13233297e-01  -6.66772692e+01   3.63133641e-02]

This are zunzun.com values (PDF here) for that same second function:

a = 6.2426224704624871E-15
b = 1.5217697532005228E+00
c = 2.0660424037614489E-01
d = 2.1570805929514186E-02

I tried making the lists arrays as reccomended here Strange result with python's (scipy) curve fitting, but that didn't help. What am I doing wrong here?


Add 1

I'm guessing the problem has to do with the lack of initial values I'm feeding my function (as explained here: gaussian fit with scipy.optimize.curve_fit in python with wrong results)

If I feed the estimates from the first exponential to the second one like so (making the new parameter d be initially zero):

popt2, pcov2 = curve_fit(func2, xdata, ydata, p0 = [popt[0], popt[1], popt[2], 0]) 

I get results that are much reasonable but still wrong compared to zunzun.com:

[  1.22560853e-14   1.52176160e+00  -4.67859961e-01   2.15706930e-02]

So now the question changes to: how can I feed my second function more reasonable parameters automatically?

解决方案

Note that a=0 in the estimate by zunzun and in your first model. So they are just estimating a constant. So, b in the first case and b and c in the second case are irrelevant and not identified.

Zunzun also uses differential evolution as a global solver, the last time I looked at it. Scipy now has basinhopping as global optimizer that looks pretty good, that is worth a try in cases where local minima are possible.

My "cheap" way, since the parameters don't have a huge range in your example: try random starting values

np.random.seed(1)
err_last = 20
best = None

for i in range(10):
    start = np.random.uniform(-10, 10, size=4)
    # Get parameters estimate
    try:
        popt2, pcov2 = curve_fit(func2, xdata, ydata, p0=start)
    except RuntimeError:
        continue
    err = ((ydata - func2(xdata, *popt2))**2).sum()
    if err < err_last:
        err_last = err
        print err
        best = popt2


za = 6.2426224704624871E-15
zb = 1.5217697532005228E+00
zc = 2.0660424037614489E-01
zd = 2.1570805929514186E-02

zz = np.array([za,zb,zc,zd])
print 'zz', zz
print 'cf', best

print 'zz', ((ydata - func2(xdata, *zz))**2).sum()
print 'cf', err_last

The last part prints (zz is zunzun, cf is curve_fit)

zz [  6.24262247e-15   1.52176975e+00   2.06604240e-01   2.15708059e-02]
cf [  1.24791299e-16   1.52176944e+00   4.11911831e+00   2.15708019e-02]
zz 9.52135153898
cf 9.52135153904

Different parameters than Zunzun for b and c, but the same residual sum of squares.

Addition

a * np.exp(b * x + c) + d = np.exp(b * x + (c + np.log(a))) + d

or

a * np.exp(b * x + c) + d = (a * np.exp(c)) * np.exp(b * x) + d

The second function isn't really different from the first function. a and c are not separately identified. So optimizers, that use the derivative information, will also have problems because the Jacobian is singular in some directions, if I see this correctly.

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

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