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

含4个参数的复杂函数曲线拟合遇RuntimeError问题求助

解决scipy.curve_fit拟合复杂函数时的maxfev超限问题

问题概述

使用scipy.optimize.curve_fit拟合自定义复杂函数时,出现以下错误:

RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 10000.

即使增大maxfev到10000000或移除对数项,问题依然存在。原代码中的拟合函数包含多个指数项与对数运算,目标是拟合参数a、b、c、d。

核心原因分析

  1. 数值合理性错误:原函数中1 - np.exp(2*38.94336875*x)项会导致分子为负数——当x在1.861.96区间时,`2*38.94*x`约为144152,np.exp(144)是约1e62的极大值,1 - exp(...)近似为-1e62,最终对数内的表达式为负数,计算时会产生NaN,直接导致拟合算法失效。
  2. 初始参数不合理:curve_fit默认初始参数全为1,但该复杂函数的参数空间非凸,默认初始值可能离最优解极远,导致迭代无法收敛。
  3. 重复计算与数值溢出:原函数中大量重复计算指数项,不仅降低效率,还容易引发数值溢出/下溢问题,干扰拟合过程。

解决方案

1. 修正函数的符号错误

根据实验数据y为负数的特征,对数内的表达式必须是0~1之间的正数。因此需修正分子中的符号,将1 - exp(2kx)改为exp(2kx) - 1(或根据物理模型调整为1 - exp(-2kx),确保分子为正),保证对数运算的有效性。

2. 简化函数表达式,优化数值稳定性

预计算常数项、提取重复的指数项,减少计算量与数值误差:

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

x = np.array([1.8652, 1.8966, 1.9125, 1.9230, 1.9313, 1.9359, 1.9435, 1.9523, 1.9585, 1.9649])
y = np.array([-0.0597, -0.0596, -0.0607, -0.0617, -0.0628, -0.0637, -0.0646, -0.0658, -0.0668, -0.0677])

# 可视化原始数据
plt.scatter(x, y, c='k')
plt.xlabel('x')
plt.ylabel('y')
plt.grid(True)
plt.show()

# 修正并简化拟合函数
def f(x, a, b, c, d):
    k = 38.94336875
    # 预计算常数项,减少重复计算
    C = 2 * 96485 / 0.000035
    # 提取重复的指数项
    exp_half_kx_neg = np.exp(-0.5 * k * x)
    exp_2kx = np.exp(2 * k * x)
    exp_kx = np.exp(k * x)
    # 修正符号,确保分子为正
    numerator = a * b * exp_half_kx_neg * (exp_2kx - 1)
    denominator = (a + b) + (c + d) * exp_kx
    inner = numerator / denominator
    return np.log10(C * inner)

3. 提供合理的初始参数猜测

根据物理意义或数据趋势,给出接近最优解的初始参数(例如假设参数非负且在0.1~10范围内),避免算法从离群点开始迭代:

# 初始参数猜测,可根据实际模型调整
p0 = [0.1, 0.1, 0.1, 0.1]
# 设置参数边界,限制参数范围(这里假设参数非负)
args, pcov = curve_fit(f, x, y, p0=p0, maxfev=100000, bounds=(0, [10, 10, 10, 10]))

print('拟合参数(a, b, c, d):', args)

4. 验证拟合结果

计算拟合曲线并绘图对比:

y_fit = f(x, *args)

plt.scatter(x, y, c='b', label="实验数据")
plt.plot(x, y_fit, 'r-', label="拟合曲线")
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc='best')
plt.grid(True)
plt.show()

额外优化建议

  • 如果参数之间存在相关性,可尝试减少参数数量(例如假设a=c、b=d,根据物理模型简化)。
  • 对参数或变量进行缩放,例如将x减去均值,或对参数取对数,优化参数空间的平滑性。
  • 若仍不收敛,可尝试使用scipy.optimize.least_squares替代curve_fit,它支持更多优化算法与约束条件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 21:24:53