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

Scipy curve_fit拟合效果差,Python有哪些更稳定的曲线拟合库?

问题原因

你遇到的报错和拟合效果差的问题是操作疏漏导致的,和scipy curve_fit本身的稳定性无关。
curve_fit默认使用非线性最小二乘算法做拟合,这类算法对参数初始值非常敏感,如果你不指定初始值,curve_fit会默认给所有参数赋值为1作为迭代起点:

  • 你真实参数a=823.5,和默认初始值1差距过大
  • 你真实参数c=8.2,对应$e^{-8.2x}$在x>0.5之后就已经衰减到接近0,算法用初始值1迭代时,很难捕捉到这么快的衰减特征,很容易陷入梯度为0的局部最优,导致参数无法收敛,自然无法估算协方差,抛出你看到的警告。
修复方法

只需要在调用curve_fit时传入和真实参数接近的初始值列表p0即可,修改后的代码如下:

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

def func(x, a, b, c):
    return a - b*np.exp(-c*x)

xdata = np.linspace(0, 4, 50)
y = func(xdata, 823.5, 5.3, 8.2)
rng = np.random.default_rng()
y_noise = 0.2 * rng.normal(size=xdata.size)
ydata = y + y_noise
plt.plot(xdata, ydata, 'b-', label='data')

# 新增p0参数指定初始值
popt, pcov = curve_fit(func, xdata, ydata, p0=[800, 5, 8])
plt.plot(xdata, func(xdata, *popt), 'r-', label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))

plt.plot(xdata, y, 'g--', label='Original')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()

修改后运行不会再抛出警告,拟合参数和原始参数误差会控制在0.2的噪声范围内,拟合效果完全正常。如果不清楚参数的大致范围,也可以给curve_fit传入bounds参数限定参数的上下界,同样可以大幅提升收敛概率。

更稳定的Python曲线拟合库推荐
  • lmfit:基于scipy的优化接口封装,专门面向曲线拟合场景,支持给参数设置默认值、边界、固定参数值、参数别名等功能,接口比原生curve_fit更友好,收敛性表现更好,是目前最常用的Python非线性拟合库之一。
  • symfit:符号化拟合工具,基于sympy和scipy开发,不需要手动写残差函数,直接通过符号表达式定义拟合函数即可,语法对新手更友好,内置了多种收敛优化策略。
  • 对于指数、幂律这类可以做变量转换的函数,也可以先通过numpy.polynomial做线性拟合估算初始参数,再代入非线性拟合,稳定性远高于直接调用默认参数的非线性拟合。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 01:33:02