Python三次回归拟合异常:为何拟合曲线形态怪异?
三次回归曲线形态异常的解决方法
问题描述
尝试用三次模型拟合回归曲线,通过矩阵计算回归系数,但绘制出的曲线形态怪异。x4和y均为包含500个数值的数组,实现代码如下:
x4 = np.array(x4) x4_cubed = x4 * x4 * x4 x4_squared = x4 * x4 x_mat_x4 = np.vstack((np.ones(len(x4)), x4, x4_squared, x4_cubed)).T x_mat_x4[0:5,] beta_hat_x4 = np.linalg.inv(x_mat_x4.T.dot(x_mat_x4)).dot(x_mat_x4.T).dot(y) y_line_x4 = beta_hat_x4[0] + x4 * beta_hat_x4[1] + x4_squared * beta_hat_x4[2] + x4_cubed * beta_hat_x4[3] plt.scatter(x4, y, c='yellow') plt.plot(x4, y_line_x4, c='purple', label='Regression Fit') plt.xlabel('X4 Values') plt.ylabel('Y Values') plt.title('Y Values vs X4 Predictor Values') plt.show()
核心解决步骤
1. 对x排序后绘制曲线
曲线形态怪异最常见的原因是x4数组未排序,plt.plot会按输入顺序依次连接点,导致曲线来回交叉。解决方法是先对x4排序,同步调整拟合值的顺序:
# 获取x4排序后的索引 sorted_indices = np.argsort(x4) # 生成排序后的x和拟合值 x_sorted = x4[sorted_indices] y_line_sorted = y_line_x4[sorted_indices] # 替换原plot代码 plt.scatter(x4, y, c='yellow') plt.plot(x_sorted, y_line_sorted, c='purple', label='Regression Fit')
2. 解决多重共线性问题
三次项、二次项与一次项高度相关,会导致矩阵求逆不稳定,系数估计偏差。可以通过两种方式处理:
- 标准化特征:将
x4标准化为均值0、方差1,缓解数值尺度差异带来的影响:# 标准化x4 x4_scaled = (x4 - np.mean(x4)) / np.std(x4) # 计算标准化后的幂次项 x4_squared_scaled = x4_scaled ** 2 x4_cubed_scaled = x4_scaled ** 3 # 重建特征矩阵 x_mat_x4 = np.vstack((np.ones(len(x4_scaled)), x4_scaled, x4_squared_scaled, x4_cubed_scaled)).T # 后续系数计算和拟合值生成保持不变 - 使用正则化回归:比如岭回归,避免普通最小二乘的矩阵求逆问题:
from sklearn.linear_model import Ridge # 构建特征矩阵(无需手动加截距,Ridge支持自动添加) X = np.vstack((x4, x4**2, x4**3)).T # 初始化岭回归模型,alpha为正则化强度,可调整 ridge_model = Ridge(alpha=0.5, fit_intercept=True) ridge_model.fit(X, y) # 生成拟合值 y_line_x4 = ridge_model.predict(X) # 同样需要排序后绘制 sorted_indices = np.argsort(x4) plt.plot(x4[sorted_indices], y_line_x4[sorted_indices], c='purple', label='Ridge Regression Fit')
3. 检查并处理异常值
如果x4或y中存在极端异常值,会干扰回归系数估计。可以通过绘制箱线图或统计量排查:
# 查看x4的统计信息 print(pd.Series(x4).describe()) # 绘制箱线图 plt.boxplot(x4) plt.show()
若存在异常值,可考虑移除或用中位数等统计量替换。
内容的提问来源于stack exchange,提问作者Ricky Osgood
相关产品推荐
相关产品推荐

