lm() 中不一致的 R 平方值
inconsistent R-squared values in lm()
我以两种不同的方式拟合同一个线性模型,导致参数估计值相同但 R 平方值不同。差异从何而来?这是R中的错误吗?这是我的代码:
m1 <- lm(stack.loss ~ ., data = stackloss)
summary(m1)
X <- model.matrix(m1)
y <- stackloss$stack.loss
m2 <- lm(y ~ 0 + X)
summary(m2)
m1
的输出如下(略有缩短):
Estimate Std. Error t value Pr(>|t|)
(Intercept) -39.9197 11.8960 -3.356 0.00375 **
Air.Flow 0.7156 0.1349 5.307 5.8e-05 ***
Water.Temp 1.2953 0.3680 3.520 0.00263 **
Acid.Conc. -0.1521 0.1563 -0.973 0.34405
Residual standard error: 3.243 on 17 degrees of freedom
Multiple R-squared: 0.9136, Adjusted R-squared: 0.8983
F-statistic: 59.9 on 3 and 17 DF, p-value: 3.016e-09
m2
的输出具有相同的系数估计值和残差标准误差,但 R 平方值和 F 统计量不同:
Estimate Std. Error t value Pr(>|t|)
X(Intercept) -39.9197 11.8960 -3.356 0.00375 **
XAir.Flow 0.7156 0.1349 5.307 5.8e-05 ***
XWater.Temp 1.2953 0.3680 3.520 0.00263 **
XAcid.Conc. -0.1521 0.1563 -0.973 0.34405
Residual standard error: 3.243 on 17 degrees of freedom
Multiple R-squared: 0.979, Adjusted R-squared: 0.9741
F-statistic: 198.2 on 4 and 17 DF, p-value: 5.098e-14
为什么 R 平方值不同?
笨狼给了你答案。您正在估计两个不同的回归模型。
因为您的第二个模型规格 m2 <- lm(y ~ 0 + X)。您不是在估计截距,而是有一个额外的变量变量 X(intercept)。
要获得相同的 R^2 只需更正模型
m1 <- lm(stack.loss ~ ., data = stackloss)
summary(m1)
X <- model.matrix(m1)
y <- stackloss$stack.loss
m2 <- lm(y ~ X)
summary(m2)
给你相同的 R^2,因为你回归相同的模型。
this post and also this. Here's a break down of what is happening in the lm() 源代码中对此进行了讨论。相关部分:
r <- z$residuals
f <- z$fitted.values
w <- z$weights
if (is.null(w)) {
mss <- if (attr(z$terms, "intercept"))
sum((f - mean(f))^2) else sum(f^2)
rss <- sum(r^2)
}
虽然你包含了截距,但是terms的属性没有设置为包含截距,对比一下:
attr(m1$terms,"intercept")
[1] 1
attr(m2$terms,"intercept")
[1] 0
我不建议这样做,因为你可以很容易地使用公式接口来拟合模型,而无需自己提供模型矩阵。但是你可以看到通过改变属性,你可以得到 summary.lm
使用正确的 rss 并得到正确的 r-squared:
attr(m2$terms,"intercept") = 1
Call:
lm(formula = y ~ 0 + X)
Residuals:
Min 1Q Median 3Q Max
-7.2377 -1.7117 -0.4551 2.3614 5.6978
Coefficients:
Estimate Std. Error t value Pr(>|t|)
X(Intercept) -39.9197 11.8960 -3.356 0.00375 **
XAir.Flow 0.7156 0.1349 5.307 5.8e-05 ***
XWater.Temp 1.2953 0.3680 3.520 0.00263 **
XAcid.Conc. -0.1521 0.1563 -0.973 0.34405
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 3.243 on 17 degrees of freedom
Multiple R-squared: 0.9136, Adjusted R-squared: 0.8983
F-statistic: 59.9 on 3 and 17 DF, p-value: 3.016e-09
我以两种不同的方式拟合同一个线性模型,导致参数估计值相同但 R 平方值不同。差异从何而来?这是R中的错误吗?这是我的代码:
m1 <- lm(stack.loss ~ ., data = stackloss)
summary(m1)
X <- model.matrix(m1)
y <- stackloss$stack.loss
m2 <- lm(y ~ 0 + X)
summary(m2)
m1
的输出如下(略有缩短):
Estimate Std. Error t value Pr(>|t|)
(Intercept) -39.9197 11.8960 -3.356 0.00375 **
Air.Flow 0.7156 0.1349 5.307 5.8e-05 ***
Water.Temp 1.2953 0.3680 3.520 0.00263 **
Acid.Conc. -0.1521 0.1563 -0.973 0.34405
Residual standard error: 3.243 on 17 degrees of freedom
Multiple R-squared: 0.9136, Adjusted R-squared: 0.8983
F-statistic: 59.9 on 3 and 17 DF, p-value: 3.016e-09
m2
的输出具有相同的系数估计值和残差标准误差,但 R 平方值和 F 统计量不同:
Estimate Std. Error t value Pr(>|t|)
X(Intercept) -39.9197 11.8960 -3.356 0.00375 **
XAir.Flow 0.7156 0.1349 5.307 5.8e-05 ***
XWater.Temp 1.2953 0.3680 3.520 0.00263 **
XAcid.Conc. -0.1521 0.1563 -0.973 0.34405
Residual standard error: 3.243 on 17 degrees of freedom
Multiple R-squared: 0.979, Adjusted R-squared: 0.9741
F-statistic: 198.2 on 4 and 17 DF, p-value: 5.098e-14
为什么 R 平方值不同?
笨狼给了你答案。您正在估计两个不同的回归模型。
因为您的第二个模型规格 m2 <- lm(y ~ 0 + X)。您不是在估计截距,而是有一个额外的变量变量 X(intercept)。
要获得相同的 R^2 只需更正模型
m1 <- lm(stack.loss ~ ., data = stackloss)
summary(m1)
X <- model.matrix(m1)
y <- stackloss$stack.loss
m2 <- lm(y ~ X)
summary(m2)
给你相同的 R^2,因为你回归相同的模型。
this post and also this. Here's a break down of what is happening in the lm() 源代码中对此进行了讨论。相关部分:
r <- z$residuals
f <- z$fitted.values
w <- z$weights
if (is.null(w)) {
mss <- if (attr(z$terms, "intercept"))
sum((f - mean(f))^2) else sum(f^2)
rss <- sum(r^2)
}
虽然你包含了截距,但是terms的属性没有设置为包含截距,对比一下:
attr(m1$terms,"intercept")
[1] 1
attr(m2$terms,"intercept")
[1] 0
我不建议这样做,因为你可以很容易地使用公式接口来拟合模型,而无需自己提供模型矩阵。但是你可以看到通过改变属性,你可以得到 summary.lm
使用正确的 rss 并得到正确的 r-squared:
attr(m2$terms,"intercept") = 1
Call:
lm(formula = y ~ 0 + X)
Residuals:
Min 1Q Median 3Q Max
-7.2377 -1.7117 -0.4551 2.3614 5.6978
Coefficients:
Estimate Std. Error t value Pr(>|t|)
X(Intercept) -39.9197 11.8960 -3.356 0.00375 **
XAir.Flow 0.7156 0.1349 5.307 5.8e-05 ***
XWater.Temp 1.2953 0.3680 3.520 0.00263 **
XAcid.Conc. -0.1521 0.1563 -0.973 0.34405
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 3.243 on 17 degrees of freedom
Multiple R-squared: 0.9136, Adjusted R-squared: 0.8983
F-statistic: 59.9 on 3 and 17 DF, p-value: 3.016e-09