为何两个等效线性模型的R-squared值存在差异?
为什么两个看似等效的线性模型R-squared值差异巨大?
我构建了两个本应等效的线性模型,其中第二个模型用分类变量z的一个水平替代截距项,但得到的R-squared值却不同。这是程序bug还是我遗漏了某些要点?
对应的R代码
set.seed(42) N=100 # intercepts iA = 3 iB = 3.5 # slopes sA = 1.5 sB = 0.5 # xs xA = runif(0,1, n=N) xB = runif(0,1, n=N) # ys yA = sA*xA + iA + rnorm(n=N)/10 yB = sB*xB + iB + rnorm(n=N)/10 data = data.frame(x=c(xA, xB), y=c(yA, yB), z=c(rep("A", times=N), rep("B", times=N))) lm1 = lm(data=data, formula = y ~ x + z) lm2 = lm(data=data, formula = y ~ x + z -1) coef(lm1) coef(lm2) summary(lm1)$r.squared summary(lm2)$r.squared
代码输出结果
> coef(lm1) (Intercept) x zB 3.23590275 1.03353472 -0.01435266 > coef(lm2) x zA zB 1.033535 3.235903 3.221550 > > summary(lm1)$r.squared [1] 0.7552991 > summary(lm2)$r.squared [1] 0.9979477
原因解析:不是bug,是R²计算逻辑的差异
这完全不是程序bug,问题出在R计算R-squared(R²)的总平方和(TSS)基准不同:
两个模型的拟合能力完全等效
lm1(带截距模型y ~ x + z):截距代表分类z=A时的基准值,zB是z=B相对于z=A的偏移量,x的系数是全局统一的斜率。lm2(无截距模型y ~ x + z -1):直接拟合z=A和z=B各自的基准截距,x的系数和lm1完全一致,拟合的残差平方和(RSS)和lm1几乎相等——你可以运行sum(resid(lm1)^2)和sum(resid(lm2)^2)验证这一点。
R²计算的核心差异
R²的计算公式是:R² = 1 - (残差平方和RSS)/(总平方和TSS),但TSS的计算逻辑在带截距和无截距模型中完全不同:- 带截距模型(lm1):TSS是y与y的均值的平方和,即
sum((y - mean(y))^2),这是统计学中R²的标准计算方式。 - 无截距模型(lm2):TSS是y与0的平方和,即
sum(y^2),这个分母远大于lm1的TSS,所以即使RSS和lm1差不多,1 - RSS/TSS的结果会非常接近1,导致R²看起来极高。
- 带截距模型(lm1):TSS是y与y的均值的平方和,即
结论
两个模型的拟合能力完全一致,R²的差异只是计算时的基准不同,并非模型本身的问题。如果要评估无截距模型的拟合效果,建议直接看残差平方和,而非默认的R²;若一定要用R²,需要手动用标准方式(基于y的均值)计算,而不是依赖summary()给出的结果。
内容的提问来源于stack exchange,提问作者mspices
相关产品推荐
相关产品推荐

