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

使用Scipy curve_fit拟合指数函数结果偏差过大求排查

问题分析与修复方案

你的代码出现拟合结果量级偏差极大的问题,核心原因是模型函数的参数顺序不符合curve_fit的要求,另外还有两个次要问题影响拟合效果,我一步步给你拆解:

1. 核心问题:模型函数参数顺序错误

scipy.optimize.curve_fit要求模型函数的第一个参数必须是自变量(也就是你的时间序列range_thing),后续参数才是需要拟合的参数(A和c)。但你定义的函数把拟合参数A、c放在了自变量t的前面:

def simple_DE(A,c,t): return A*math.e**(c*t)

这会导致curve_fit错误地将输入的x值(range_thing)传递给参数A,而不是自变量t,直接导致拟合完全偏离预期。

2. 次要问题1:数组运算兼容性差

你使用了math.e**(c*t),虽然对于简单的标量运算没问题,但range_thing是numpy数组,更推荐使用numpy提供的np.exp()函数,它能更高效、安全地处理数组运算,避免潜在的类型错误。

3. 次要问题2:缺乏合理的初始参数猜测

指数函数的拟合对初始参数很敏感,curve_fit默认的初始值(全1)可能无法收敛到全局最优解。给一个接近真实值的初始猜测,能大幅提升拟合的准确性。


修正后的完整代码

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

cases_DE = [16,18,26,48,74,79,130,165,203,262,545,670,800,1040,1224,1565,1966,2745,3675,4599,5813, 7272, 9367, 12327]

# 修正参数顺序:自变量t放在第一位,拟合参数A、c在后
def simple_DE(t, A, c):
    return A * np.exp(c * t)

range_thing = np.array(range(len(cases_DE)))

# 提供合理的初始参数猜测:A取初始病例数,c根据数据增长粗略估算
p0 = [16, 0.3]
# 调整bounds:A不能为负数(病例数不可能是负的),c限制在0到1的合理增长范围内
popt, pcov = curve_fit(simple_DE, range_thing, cases_DE, p0=p0, bounds=((0, 0), (np.inf, 1)))

print("拟合参数A和c:", popt)
# 注意调用函数的顺序:自变量t放在最后
plt.scatter(range_thing, simple_DE(range_thing, *popt), label='拟合曲线', color='r')
plt.scatter(range_thing, cases_DE, label='原始数据')
print("第21天(索引20)的拟合值:", simple_DE(20, *popt))

plt.xlabel('天数索引')
plt.ylabel('病例数')
plt.legend()
plt.show()

验证效果

修正后,你会得到接近真实数据的拟合结果,比如拟合出的A应该在15左右(接近初始病例数16),c大概在0.25-0.3之间,对应合理的日增长速率。第20天的拟合值会和真实的5813非常接近。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 23:22:32