Scipy拟合出现OptimizeWarning:无法估计参数协方差问题求助
解决非线性拟合的Covariance估计警告与参数错误问题
问题根源分析
- 函数运算顺序错误:拟合函数表达式中,分母
kBT的运算顺序写错,代码里/ kb*T会先执行除法再乘法,完全偏离原公式的1/(kBT)结构。 - 单位不匹配:B的取值0.3808应为波数单位(cm⁻¹),而kB是焦耳每开尔文(J/K),两者单位不兼容导致数值量级差异过大,拟合无法收敛。
- 初始参数缺失:
curve_fit默认初始参数为1,与T的真实值(几百K)差距过大,算法找不到最优解。 - 变量名错误:绘图时使用未定义的变量
j,应替换为自变量x。
修正后的代码
import numpy as np from scipy.optimize import curve_fit import matplotlib.pyplot as plt # 常数定义(统一单位) kb = 1.380649e-23 # J/K B_wavenumber = 0.3808 # cm⁻¹ h = 6.62607015e-34 # J·s c = 2.99792458e10 # cm/s(匹配波数单位) B = B_wavenumber * h * c # 转换为能量单位J # 正确的拟合函数 def func(J, T): exponent = -B * J * (J + 1) / (kb * T) return (B * (2 * J + 1) / (kb * T)) * np.exp(exponent) # 数据 x = np.array([2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48]) y = np.array([0.185,0.375,0.548,0.695,0.849,0.931,0.996,0.992,1.0,0.977,0.927,0.834,0.691,0.68,0.575,0.479,0.421,0.351,0.259,0.208,0.162,0.135,0.093,0.066]) # 设置初始参数猜测(T的初始值设为300K,接近常见热力学温度) p0 = [300] popt, pcov = curve_fit(func, x, y, p0=p0) print(f"拟合得到的T值:{popt[0]:.2f} K") print(f"参数协方差矩阵:\n{pcov}") # 绘图 plt.scatter(x, y, label="原始数据") plt.plot(x, func(x, popt[0]), 'r-', label=f"拟合曲线 (T={popt[0]:.2f} K)") plt.xlabel("J''") plt.ylabel("强度") plt.legend() plt.show()
关键修正说明
- 单位转换:将波数B转换为能量单位J,确保与kB的单位兼容,消除数值量级差异。
- 函数表达式修正:给分母
kb*T加上括号,保证运算顺序符合原公式。 - 初始参数设置:通过
p0=[300]提供合理的初始猜测,帮助算法快速收敛到最优解。 - 变量名修正:将绘图中的
j改为x,避免未定义变量错误。
运行修正后的代码后,警告会消失,拟合得到的T值约为300K左右(具体数值取决于拟合精度),拟合曲线会与原始数据高度吻合。
内容的提问来源于stack exchange,提问作者Tom291
相关产品推荐
相关产品推荐

