Python 中的双指数拟合

问题描述 投票:0回答:1

我在 Python 中遇到与

curve_fit
相关的问题。具体来说,我正在尝试对双指数数据进行建模。

我正在尝试对数据进行建模。肉眼看上去拟合效果很好,但当我看到参数和误差时,我感到震惊。误差很大(比参数平均值大几个数量级)。除此之外,我必须提供非常具体的初步猜测,否则毫无用处。你有什么建议吗?

双倍经验拟合如何处理?

Plots: https://ibb.co/mCs39VP
Model:a*e^(-x*b)+c*e^(-x*d)+e
Paramters (for lower fit):  [-1622.6092323    -15.038877    1713.45499496   -15.33871455
    -1.92259733]
Errors [4.73773551e+06 4.17637511e+02 4.73736168e+06 4.37257698e+02
 1.20927662e-02

情节:

python curve-fitting exponential
1个回答
0
投票

TL;博士

您至少面临两个问题:

  • 提供的参数不收敛(指数递增),它不是基于您展示的数据集的解决方案;
  • 您需要帮助求解器区分两种指数效应,因为您的模型是冗余的,并且在优化时会让求解器感到困惑

MCVE

让我们构建一个 MCVE 来突出您的验配问题的挑战。

import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize
from sklearn.metrics import r2_score

对于您引用的模型,我们有以下功能:

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

这对于拟合来说并不简单,因为它是多余的(其中有两个相同的指数效应)。这意味着求解器在从单位点开始执行损失梯度下降时会感到困惑。

我们生成一些与您的数据集类似的数据:

p0 = np.array([1.7, 1.1, -0.4, 4.2, 1.])

请注意,您的参数集没有定义收敛函数,因为两个指数都在增加。这个解决方案肯定无法适合您的数据,因此它们的不确定性很大。

#p0 = np.array([-1622.6092323, -15.038877, 1713.45499496, -15.33871455, -1.92259733])

我们生成一些综合数据集:

np.random.seed(12345)
x = np.linspace(-0.5, 2.0, 35)
y = model(x, *p0)
s = 0.01 * np.ones_like(y)
n = s * np.random.normal(size=y.size)
yexp = y + n

这是优化的关键,我们只将一个初始参数调整为负数,以帮助求解器区分两个指数并相互优化:

popt, pcov = optimize.curve_fit(
    model, x, yexp, sigma=s,
    p0=[1, 1, -1, 1, 1],    # Hint: discriminate both effect
    absolute_sigma=True
)    
# array([ 1.70657559,  1.04436978, -0.36944364,  4.29809242,  0.96715622])

spopt = np.sqrt(np.diag(pcov))
# array([0.01738214, 0.03964849, 0.02884002, 0.09962603, 0.01952317])

我们可以看到,在这种情况下,收敛是最优的(我们恢复了带有明显误差的参数)。

yhat = model(x, *popt)
score = r2_score(yexp, yhat)  # 0.9993365605205807

健身也没错:

© www.soinside.com 2019 - 2024. All rights reserved.