编程语言
首页 > 编程语言> > python – 曲线拟合失败,指数但zunzun正确

python – 曲线拟合失败,指数但zunzun正确

作者:互联网

我正在尝试计算两种形式的指数对某些x,y数据的最佳拟合(数据文件可以从here下载)

这是代码:

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

对于popt,第一个指数给出与zunzun.com(PDF here)完全相同的值:

[  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 here):

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

我尝试将列表数组作为推荐在这里Strange result with python’s (scipy) curve fitting,但这没有帮助.我在这做错了什么?

加1

我猜这个问题与缺少初始值有关我正在提供我的功能(如下所述:gaussian fit with scipy.optimize.curve_fit in python with wrong results)

如果我将估计从第一个指数提供给第二个指数(如此)(使新参数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]

所以现在问题改为:如何自动为我的第二个函数提供更合理的参数?

解决方法:

请注意,zunzun和第一个模型的估算中a = 0.所以他们只是估计一个常数.因此,在第一种情况下b和在第二种情况下b和c是无关紧要的并且未被识别.

Zunzun也使用差分进化作为全局求解器,这是我最后一次看到它. Scipy现在将流水作为全局优化器看起来相当不错,在可能的局部最小值的情况下值得一试.

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

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

最后一部分打印(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

与Zunzun不同的参数为b和c,但残差平方和相同.

加成

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未单独标识.因此,使用衍生信息的优化器也会遇到问题,因为如果我正确地看到这个,Jacobian在某些方向上是单数的.

标签:python,scipy,curve-fitting
来源: https://codeday.me/bug/20191007/1863798.html