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

使用WLS时statsmodels与自定义计算的R²值存在显著差异的问题

解决WLS模型下statsmodels与自定义R²差异的问题

嘿,这个问题我之前踩过坑!核心原因是statsmodels中WLS模型的R²计算采用了加权逻辑,而你的自定义函数大概率沿用了OLS的无权重公式,这就是两者结果差异极大的根源。

为什么会有差异?

  • OLS的R²逻辑:我们常用的公式是 1 - (SS_res / SS_tot),其中SS_res是普通残差平方和,SS_tot是总离均差平方和(以样本均值为基准)。这时候自定义函数和statsmodels的计算逻辑完全一致,结果自然相同。
  • WLS的R²逻辑:statsmodels默认计算的是加权版本的R²,它会用你指定的权重分别对残差和总平方和进行加权:
    • 加权残差平方和:sum(w * (y - y_pred)²)
    • 加权总平方和:sum(w * (y - y_mean_weighted)²),这里的y_mean_weighted是加权均值,计算公式为 sum(w*y)/sum(w)
  • 如果你自定义的函数还是直接计算无权重的1 - (sum((y-y_pred)²)/sum((y-y_mean)²)),结果肯定和statsmodels的加权R²差很多。

修正自定义函数的示例代码

下面是一段可以和statsmodels结果对齐的自定义加权R²计算代码:

import statsmodels.api as sm
import numpy as np

# 模拟测试数据
np.random.seed(42)
x = np.random.rand(100)
y = 2*x + np.random.randn(100)*0.5
weights = np.random.rand(100)*2 + 0.5  # 生成随机权重

# 拟合WLS模型
X = sm.add_constant(x)
wls_model = sm.WLS(y, X, weights=weights).fit()
print("statsmodels WLS R²:", wls_model.rsquared)

# 自定义加权R²计算函数
def weighted_r2(y_true, y_pred, weights):
    # 计算加权均值
    y_weighted_mean = np.sum(weights * y_true) / np.sum(weights)
    # 加权残差平方和
    ss_res_weighted = np.sum(weights * (y_true - y_pred)**2)
    # 加权总平方和
    ss_tot_weighted = np.sum(weights * (y_true - y_weighted_mean)**2)
    return 1 - (ss_res_weighted / ss_tot_weighted)

# 验证自定义结果
y_pred_wls = wls_model.predict(X)
custom_r2 = weighted_r2(y, y_pred_wls, weights)
print("自定义加权R²:", custom_r2)

运行这段代码后,你会发现两个R²结果完全一致。

额外注意事项

  • statsmodels的WLS结果中还提供了rsquared_adj(调整后加权R²),计算逻辑也是基于加权平方和的。
  • 如果你非要计算无权重的R²,可以手动用OLS的公式,但这违背了加权回归的初衷——加权回归就是为了让权重高的样本对模型拟合产生更大影响,对应的R²也应该采用加权逻辑才有意义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:23:01