You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

双指数拟合与数据不匹配的问题排查及解决求助

双指数函数拟合优化方案

问题背景

我有一组数据,尝试用双指数函数拟合,但代码运行后拟合效果差,参数出现负值,且不符合已知约束条件(振幅和为1,衰减时间量级为10⁻¹或10⁻²)。修正绘图参数后线条平滑,但仍与数据不匹配。

原代码如下:

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import csv
from pylab import genfromtxt
import scipy

twofifty = genfromtxt("t vs delta E (250C).txt");

t = twofifty[:, 0]
de = twofifty[:, 1]*10e3

def func(t, f_1, tau_1, f_2, tau_2):
    return f_1*np.exp(-t/tau_1)+f_2*np.exp(-t/tau_2)

guess = (0.7, 100, 0.3, 200)

popt, pcov = curve_fit(func, t, de, guess)
print(popt)
plt.plot(t, de, label="data")
plt.plot(t, func(de, *popt), label="fit")
plt.legend()
plt.show()

优化步骤

1. 利用已知约束减少参数自由度

已知f_1 + f_2 = 1,将f_2 = 1 - f_1代入拟合函数,减少一个参数,避免无意义的负值振幅,同时降低拟合难度:

def func(t, f_1, tau_1, tau_2):
    f_2 = 1 - f_1
    return f_1*np.exp(-t/tau_1) + f_2*np.exp(-t/tau_2)

对应的初始猜测值需调整为(0.7, 0.1, 0.01)(匹配预期的振幅和衰减时间量级)。

2. 修正初始猜测值的量级

原猜测中tau的量级(100/200)与实际预期(10⁻¹/10⁻²)完全相反,这是拟合失败的核心原因之一。必须将初始猜测调整到合理范围内:

guess = (0.7, 0.1, 0.01)  # f1=0.7, tau1=0.1, tau2=0.01

3. 添加参数边界约束

使用curve_fit的bounds参数,强制tau为正(衰减时间不能为负),同时限制f_1在0到1之间(保证f_2=1-f_1也在合理范围内):

# 边界格式:(下限元组, 上限元组)
bounds = ((0, 1e-3, 1e-3), (1, 1, 1))
popt, pcov = curve_fit(func, t, de, p0=guess, bounds=bounds)

4. 数据预处理与量级验证

检查t的单位是否与tau匹配:如果t是毫秒级,需先转换为秒,避免指数值过大导致数值溢出;同时用10**4替代10e3,保证y轴缩放的准确性。

5. 保留正确的拟合曲线调用

确保拟合曲线使用t作为输入,而非de:

plt.plot(t, func(t, *popt), label="fit")

完整优化代码

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from pylab import genfromtxt

# 读取数据
twofifty = genfromtxt("t vs delta E (250C).txt")
t = twofifty[:, 0]
de = twofifty[:, 1] * 10**4  # 准确匹配原数据10^4量级

# 带约束的双指数函数
def func(t, f_1, tau_1, tau_2):
    f_2 = 1 - f_1
    return f_1 * np.exp(-t / tau_1) + f_2 * np.exp(-t / tau_2)

# 合理的初始猜测
guess = (0.7, 0.1, 0.01)
# 参数边界:f1∈[0,1], tau1/tau2∈[0.001,1]
bounds = ((0, 1e-3, 1e-3), (1, 1, 1))

# 执行拟合
popt, pcov = curve_fit(func, t, de, p0=guess, bounds=bounds)
f1_fit, tau1_fit, tau2_fit = popt
f2_fit = 1 - f1_fit

print(f"拟合结果:f1={f1_fit:.4f}, f2={f2_fit:.4f}, tau1={tau1_fit:.4f}, tau2={tau2_fit:.4f}")

# 绘图
plt.plot(t, de, label="原始数据")
plt.plot(t, func(t, *popt), label="拟合曲线", linestyle="--")
plt.xlabel("时间t")
plt.ylabel("ΔE")
plt.legend()
plt.show()

内容的提问来源于stack exchange,提问作者jbl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 08:35:08