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

scipy.optimize curve_fit拟合高斯曲线不收敛问题求助

解决scipy curve_fit拟合高斯曲线无法收敛的问题

核心问题分析

拟合失败主要源于两个关键原因:

  1. 参数尺度差异极大:目标参数a(4.8e6)、b(-154)、c(~30)的数量级跨度超过5个数量级,curve_fit默认的Levenberg-Marquardt算法对这种参数尺度不匹配的情况鲁棒性很差,步长更新无法同时适配所有参数。
  2. 数据点分布特殊:三个x值均为正数,而高斯峰位于x=-154(数据点右侧的单调衰减区域),此时函数形态和指数衰减高度相似,优化器容易陷入局部最优,无法定位到正确的高斯参数空间。

解决方案

方案1:对数转换+线性回归获取精准初始参数

利用高斯函数的对数形式可转换为二次函数的特性,先通过线性回归得到准确初始值,再用curve_fit微调:

import numpy as np
from scipy.optimize import curve_fit
from sklearn.linear_model import LinearRegression

def gauss_func(x, a, b, c):
    return a * np.exp(-(x-b)**2/(2*c**2))

# 原始数据
x_main = np.array([19.748, 39.611, 59.465])
y_main = np.array([0.438160379, 0.008706677, 0.000160106])

# 对y取自然对数,将高斯模型转换为二次线性模型
ln_y = np.log(y_main)
# 构造二次特征矩阵:x, x²
X = np.vstack([x_main, x_main**2]).T

# 线性回归拟合二次模型
reg = LinearRegression(fit_intercept=True)
reg.fit(X, ln_y)
A = reg.intercept_
B, C = reg.coef_

# 从线性参数反推高斯参数
c = np.sqrt(-1/(2*C))
b = -B * c**2
a = np.exp(A + (b**2)/(2*c**2))

print("线性回归初始参数:")
print(f"a={a:.3f}, b={b:.3f}, c={c:.3f}")

# 用初始参数执行curve_fit微调
popt, pcov = curve_fit(gauss_func, x_main, y_main, p0=(a, b, c))
print("\ncurve_fit微调后参数:")
print(f"a={popt[0]:.3f}, b={popt[1]:.3f}, c={popt[2]:.3f}")

方案2:改用least_squares优化器

scipy.optimize.least_squares对参数尺度的鲁棒性更强,还能设置参数边界(比如强制c为正):

import numpy as np
from scipy.optimize import least_squares

def gauss_func(x, a, b, c):
    return a * np.exp(-(x-b)**2/(2*c**2))

# 定义残差函数
def residual(params, x, y):
    return y - gauss_func(x, *params)

x_main = np.array([19.748, 39.611, 59.465])
y_main = np.array([0.438160379, 0.008706677, 0.000160106])

# 初始猜测可直接用在线工具结果,或方案1的线性回归结果
initial_guess = [4821416, -154.0293, 30.51661]
# 设置参数边界:a>0, b无限制, c>0
bounds = ([0, -np.inf, 1e-3], [np.inf, np.inf, np.inf])

result = least_squares(residual, initial_guess, args=(x_main, y_main), bounds=bounds)
print("least_squares拟合结果:")
print(f"a={result.x[0]:.3f}, b={result.x[1]:.3f}, c={result.x[2]:.3f}")

关键注意点

  • 当高斯峰不在数据点覆盖范围内时,不要依赖随机初始值,必须通过数学变换或已知结果提供精准初始参数。
  • 参数尺度差异大时,优先用线性变换将非线性问题转换为线性问题,或选择对尺度不敏感的优化器。

内容的提问来源于stack exchange,提问作者Leonardo de la Roca

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 11:10:47