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

Python中基于QR分解处理共线特征的线性回归实现方法

Python复刻R语言lm共线性处理效果的实现方案

现成可用方案

Python标准库没有自带和Rlm行为完全匹配的线性回归实现,不过第三方库statsmodels的OLS接口只要参数配置正确,可以直接复现你要的效果:存在完全共线性的冗余变量时,自动将对应系数、标准误、t值、p值填充为NaN,和你贴出的R输出逻辑完全对齐。

  • 调用时需要手动添加截距项,标记矩阵包含常数项,同时指定用QR分解求解、设置和R一致的秩检测容差,模型会按输入列的先后顺序保留线性无关变量,把后出现的、可被其他变量线性表示的变量标记为未定义,变量选择规则和R完全一致。
  • 要复现你贴的方差分析表,直接调用statsmodels的I型(序贯)平方和方差分析接口即可,R的anova.lm默认输出的就是I型平方和结果。

参考代码:

import numpy as np
import pandas as pd
import statsmodels.api as sm

# 假设dataset为pandas DataFrame,y列是因变量,其余列是自变量
X = dataset.drop(columns=["y"])
# 手动添加截距项,和R的y ~ . 公式逻辑一致
X = sm.add_constant(X)
# 初始化模型,指定QR分解求解
model = sm.OLS(endog=dataset["y"], exog=X, hasconst=True)
# 拟合时设置和R一致的秩检测容差,避免变量筛选结果不一致
fit_result = model.fit(method="qr", rcond=np.finfo(float).eps * max(X.shape))
# 输出和R格式类似的回归结果
print(fit_result.summary())
# 提取系数,共线性冗余变量会自动返回NaN
coefficients = fit_result.params
# 生成和R一致的I型方差分析表
anova_table = sm.stats.anova_lm(fit_result, typ=1)
print(anova_table)

手动实现方法(完全对齐R底层逻辑)

如果不想依赖statsmodels,也可以手动复现Rlm的全部计算逻辑,核心步骤如下:

  • 构建设计矩阵:在自变量矩阵最左侧拼接全1列作为截距项,和R的默认处理一致。
  • 执行带列选主元的QR分解:R的lm底层调用LINPACK的dqrdc算法做选主元QR分解,会优先保留对因变量解释力强、输入顺序靠前的线性无关列,重排列顺序。
  • 判定矩阵有效秩:用R默认的容差规则max(设计矩阵行数, 设计矩阵列数) * 双精度浮点数精度 * R矩阵对角线元素绝对值的最大值作为阈值,R矩阵对角线元素小于该阈值的列,就是存在完全共线性的冗余列。
  • 求解系数:仅保留满秩部分的R子矩阵做回代求解非冗余变量的系数,冗余变量的所有统计量(系数、标准误、t值、p值)全部填充为NaN。
  • 还原列顺序:将选主元过程中打乱的列顺序还原为原输入自变量的顺序,保证系数和输入变量一一对应。
  • 计算后续统计量:残差、R方、调整R方、F统计量、方差分析表都仅基于保留的非冗余变量计算,结果和R的输出差异会在双精度浮点误差范围内。

注意:scikit-learn的LinearRegression不会返回NaN的核心原因是它默认用SVD求解,会对奇异值做软截断,给所有变量返回一个正则化后的数值解,不会显式标记共线性冗余变量,和Rlm的设计逻辑有本质区别。

结果对齐注意事项

  • 秩检测的容差阈值必须和R保持一致,否则会出现保留/丢弃的变量数量、编号和R结果不匹配的问题,不要使用算法默认的宽松阈值。
  • 如果要复现你贴出的方差分析结果,必须使用I型(序贯)平方和计算,不要用II型、III型平方和,R默认输出的方差分析表就是序贯检验结果。
  • 截距项必须放在设计矩阵的第一列,否则选主元过程中可能误将截距项判定为冗余变量,导致结果和R不一致。

内容的提问来源于stack exchange,提问作者Ilyass Elamri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 15:00:50