如何利用scipy.curve_fit的pcov估计回归函数的预测误差传播?
用SciPy curve_fit的协方差矩阵计算新预测点的误差方差
完全可以通过pcov直接计算新预测数据点的误差方差,这是将拟合参数的不确定性传递到预测值的标准方法,具体细节如下:
核心原理
curve_fit返回的pcov是拟合参数的协方差矩阵:对角线元素对应各参数的方差,非对角线元素对应参数间的协方差。预测值的误差方差由参数协方差和拟合函数对各参数的偏导数共同决定,公式为:var_pred = J @ pcov @ J.T
其中J是拟合函数在最优参数处对每个参数的偏导数组成的行向量(雅可比向量)。
具体操作步骤
- 推导偏导数:假设你的拟合函数是
f(x, p0, p1, p2),对每个参数求偏导得到df/dp0、df/dp1、df/dp2,这些偏导数值由新预测点的x值决定。 - 构建雅可比向量:将上述偏导数值按参数顺序组成行向量
J。 - 计算预测方差:用向量
J和协方差矩阵pcov执行矩阵运算,得到该预测点的误差方差,标准差则是方差的平方根。
代码示例
import numpy as np from scipy.optimize import curve_fit # 定义含三个参数的拟合函数 def model(x, a, b, c): return a * np.exp(-b * x) + c # 模拟实验数据 xdata = np.linspace(0, 5, 30) ydata = model(xdata, 2.5, 1.3, 0.5) + np.random.normal(0, 0.2, len(xdata)) # 拟合得到参数与协方差矩阵 popt, pcov = curve_fit(model, xdata, ydata) # 待预测的新数据点 x_new = 6.0 # 计算雅可比向量(对每个参数的偏导数) df_da = np.exp(-popt[1] * x_new) df_db = -popt[0] * x_new * np.exp(-popt[1] * x_new) df_dc = 1.0 J = np.array([df_da, df_db, df_dc]) # 计算预测值的方差与标准差 var_pred = J @ pcov @ J.T std_pred = np.sqrt(var_pred) # 输出结果 pred_val = model(x_new, *popt) print(f"新点预测值: {pred_val:.3f}") print(f"预测误差标准差: {std_pred:.3f}")
关键注意事项
- 如果拟合时未指定
sigma参数(即未给出数据点的误差权重),pcov的缩放可能不准确,需要用残差平方和修正:
用修正后的ss_res = np.sum((ydata - model(xdata, *popt))**2) dof = len(xdata) - len(popt) # 自由度 pcov_corrected = pcov * (ss_res / dof)pcov_corrected计算预测方差更准确。 - 上述方法仅考虑参数不确定性带来的预测误差。如果需要包含数据本身的噪声误差,需将残差的均方误差(
ss_res/dof)加到预测方差中,得到总误差方差:var_total = var_pred + (ss_res / dof)
内容的提问来源于stack exchange,提问作者Cesar
相关产品推荐
相关产品推荐

