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

SciPy curve_fit参数协方差无法估计:Schott系数拟合求解

Schott色散函数拟合问题的解决思路

问题分析

用6个数据点拟合6参数的Schott逆函数时,出现协方差无法估计、参数全为inf的问题,核心原因有三个:

  • 数据点数量刚好等于参数数量,拟合问题数值病态,微小波动就会导致参数发散
  • 原函数包含开平方运算,拟合过程中内部多项式可能出现负值,引发nan进而让优化崩溃
  • 初始参数虽为Schott玻璃平均值,但可能和当前数据的最优解差距过大,优化器无法收敛

具体解决方法

1. 转换拟合形式,规避数值不稳定

把原函数两边平方,去掉开平方操作,转换成参数线性组合的形式:
原函数:$y = \sqrt{a0 + a1x² + a2x⁻² + a3x⁻⁴ + a4x⁻⁶ + a5x⁻⁸}$
平方后:$y² = a0 + a1x² + a2x⁻² + a3x⁻⁴ + a4x⁻⁶ + a5x⁻⁸$
这种形式可以用线性最小二乘法直接求解,也能避免开平方带来的数值问题。

代码示例:

import numpy as np
from scipy.optimize import curve_fit

# 转换后的无开平方拟合函数
def schott_squared(x, a0, a1, a2, a3, a4, a5):
    return a0 + a1 * x**2 + a2 * x**(-2) + a3 * x**(-4) + a4 * x**(-6) + a5 * x**(-8)

x_data = np.array([0.65627, 0.64385, 0.58756, 0.54607, 0.48613, 0.47999])
y_data = np.array([1.7844818, 1.7858616, 1.7867687, 1.7899, 1.798498, 1.80231785])
y_squared = y_data ** 2

# 方法一:线性最小二乘法(最稳定)
# 构造设计矩阵
X = np.column_stack([
    np.ones_like(x_data),
    x_data**2,
    x_data**(-2),
    x_data**(-4),
    x_data**(-6),
    x_data**(-8)
])
params_lstsq, _, _, _ = np.linalg.lstsq(X, y_squared, rcond=None)
print("线性拟合参数:", params_lstsq)

# 方法二:用curve_fit拟合平方后的函数
# 替换成你手头的2000种Schott玻璃平均初始参数
init_params = [2.8, 0.01, 0.01, 0.0001, 0.00001, 0.000001]
params_curvefit, _ = curve_fit(schott_squared, x_data, y_squared, p0=init_params)
print("非线性拟合参数:", params_curvefit)

# 验证拟合效果
y_fit = np.sqrt(schott_squared(x_data, *params_lstsq))
print("平均拟合误差:", np.mean((y_fit - y_data)**2))

2. 添加正则化约束

6个点拟合6参数是完全确定的,但数值上容易病态,加入L2正则化可以约束参数的量级,提升稳定性:

from scipy.optimize import minimize

def loss_with_reg(params, x, y):
    y_pred_sq = schott_squared(x, *params)
    mse = np.mean((y_pred_sq - y**2)**2)
    # 正则强度可根据实际情况调整,1e-6是参考值
    l2_reg = 1e-6 * np.sum(np.square(params))
    return mse + l2_reg

init_params = [2.8, 0.01, 0.01, 0.0001, 0.00001, 0.000001]
result = minimize(loss_with_reg, init_params, args=(x_data, y_data))
print("正则化拟合参数:", result.x)

3. 统一特征量级

原函数中各项的量级差异极大:x²在0.23-0.43之间,x⁻⁸却能达到470左右,这种量级差会让优化器难以收敛。可以对输入特征做归一化处理,比如把x缩放为x / np.mean(x),或者对每一项特征做标准化,让所有特征的均值接近、方差一致。

4. 减少参数数量(可选)

如果高阶项(比如a4、a5)对当前玻璃的色散影响极小,可以固定这些参数为Schott平均值,只拟合前4个参数,让数据点数量多于参数数量,拟合会更稳定。


内容的提问来源于stack exchange,提问作者Amarth Gûl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 21:14:55