使用 lm() 进行线性回归 - 对结果感到惊讶

Posted

技术标签:

【中文标题】使用 lm() 进行线性回归 - 对结果感到惊讶【英文标题】:linear regression using lm() - surprised by the result 【发布时间】:2015-10-30 00:21:54 【问题描述】:

我使用lm 函数对我拥有的数据进行了线性回归。一切正常(没有错误消息),但我对结果感到惊讶:我的印象是 R “错过”了一组点,即截距和斜率不是最合适的。例如,我指的是坐标 x=15-25,y=0-20 处的点组。

我的问题:

是否有一个函数可以将拟合与“预期”系数和“lm 计算”系数进行比较? 我在编码时犯了一个愚蠢的错误,导致lm 这样做 那个?

以下一些答案:关于 x 和 y 的附加信息

x 和 y 都是疾病症状的视觉估计。两者都有同样的不确定性。

数据和代码在这里:

x1=c(24.0,23.9,23.6,21.6,21.0,20.8,22.4,22.6,
     21.6,21.2,19.0,19.4,21.1,21.5,21.5,20.1,20.1,
     20.1,17.2,18.6,21.5,18.2,23.2,20.4,19.2,22.4,
     18.8,17.9,19.1,17.9,19.6,18.1,17.6,17.4,17.5,
     17.5,25.2,24.4,25.6,24.3,24.6,24.3,29.4,29.4,
     29.1,28.5,27.2,27.9,31.5,31.5,31.5,27.8,31.2,
     27.4,28.8,27.9,27.6,26.9,28.0,28.0,33.0,32.0,
     34.2,34.0,32.6,30.8)

y1=c(100.0,95.5,93.5,100.0,98.5,99.5,34.8,
     45.8,47.5,17.4,42.6,63.0,6.9,12.1,30.5,
     10.5,14.3,41.1, 2.2,20.0,9.8,3.5,0.5,3.5,5.7,
     3.1,19.2,6.4, 1.2, 4.5, 5.7, 3.1,19.2, 6.4,
     1.2,4.5,81.5,70.5,91.5,75.0,59.5,73.3,66.5,
     47.0,60.5,47.5,33.0,62.5,87.0,86.0,77.0,
     86.0,83.0,78.5,83.0,83.5,73.0,69.5,82.5,78.5,
     84.0,93.5,83.5,96.5,96.0,97.5)   



## x11()
plot(x1,y1,xlim=c(0,35),ylim=c(0,100))

# linear regression
reg_lin=lm(y1 ~ x1)
abline(reg_lin,lty="solid", col="royalblue")
text(12.5,25,labels="R result",col="royalblue", cex=0.85)
text(12.5,20,labels=bquote(y== .(5.26)*x - .(76)),col="royalblue", cex=0.85)

# result I would have imagined
abline(a=-150,b=8,lty="dashed", col="red")
text(27.5,25,labels="What I think is better",col="red", cex=0.85)
text(27.5,20,labels=bquote(y== .(8)*x - .(150)),col="red", cex=0.85)

【问题讨论】:

只需计算与您假定的最佳拟合以及lm 生成的残差平方和。 你怎么能说截距和斜率不是最合适的呢?如果不是,在哪种模型下它们是线性的、黄土的、广义的等等? 你的红线看起来可能是你从总最小二乘法中得到的(最小化两个方向的距离) 关于“你认为更好”:意识到,我们的大脑是强大的可视化者。 “看起来”更好的可能是所有点在 x 和 y 中更接近的线。最小二乘法只查看 in y 的错误。如果您想考虑两个维度的错误,也许可以查看Total Least Squares 或类似的东西。 好问题,好答案(对于 CrossValidated 来说可能稍微好一点......) 【参考方案1】:

试试这个:

reg_lin_int <- reg_lin$coefficients[1]
reg_lin_slp <- reg_lin$coefficients[2]

sum((y1 - (reg_lin_int + reg_lin_slp*x1)) ^ 2)
# [1] 39486.33
sum((y1 - (-150 + 8 * x1)) ^ 2)
# [1] 55583.18

lm 拟合线下的残差平方和较低。这是意料之中的,因为reg_lin_intreg_lin_slp 保证产生最小的总平方误差。

直观地说,我们知道平方损失函数下的估计器对异常值很敏感。它“丢失”了底部的组,因为它离左上角的组更近了,而且距离更远——平方距离赋予了这些点更多的权重。

实际上,如果我们使用Least Absolute Deviations 回归(即指定绝对损失函数而不是平方),结果会更接近您的猜测:

library(quantreg)
lad_reg <- rq(y1 ~ x1)

(专业提示:使用lwd 使您的图表更加更具可读性)

@nongkrong 和@MikeWilliamson 提到的更接近您的想法的是Total Least Squares。以下是 TLS 对您的样本的结果:

v <- prcomp(cbind(x1, y1))$rotation
bbeta <- v[-ncol(v), ncol(v)] / v[1, 1]
inter <- mean(y1) - bbeta * mean(x1)

【讨论】:

好吧,代码就这么简单。非常感谢。坦率地说,我很困惑:当回归线缺少一组点(再次,底部的组)时,如何最小化平方和?惩罚(就平方和而言)应该很难补偿。 @NOTM 查看更新。这是关于你的直觉选择的损失函数。 好的,再次感谢!我正在阅读有关 Total Least Squares 的页面并输入代码以在同一图形上显示 OLS、LAD 和 TLS 的结果。看起来你做的更快。再次感谢。 @NOTM 请记住:2^2 - 1^2 = 3 但 50^2 - 49^2 = 99。因此,当使用最小二乘法时,在划线时受到打击通常是有益的更接近“异常值”以将预测值和观察值之间的巨大差异减少一点,因为它会比试图将线拟合得更接近它已经很好地拟合的点来减少平方误差。因此,请查看您的最佳拟合版本(就垂直误差而言)与最适合 x=20、y=100 附近的“异常值”的最小二乘法相比。【参考方案2】:

你已经得到了一个很好的答案,但也许这也有帮助:

如您所知,OLS 将 y 方向的误差平方和最小化。这意味着您的 x 值的不确定性可以忽略不计,这通常是这种情况。但您的数据可能并非如此。如果我们假设 x 和 y 的不确定性相等并进行 Deming 回归,我们得到的拟合更类似于您的预期。

library(MethComp)
dem_reg <- Deming(x1, y1)
abline(dem_reg[1:2], col = "green")

您没有提供有关您的数据的详细信息。因此,这可能有用也可能没用。

【讨论】:

罗兰,@MikeWilliamson:你是对的。我做 OLS 是因为那是我知道的回归技术,而不是我应该使用的。在我的数据中,x 和 y 都是疾病症状的视觉估计:换句话说,x 和 y 的不确定性是相同的。所以是的,TLS 更合适。谢谢你们。 那与你无关,但我还是要提一下:戴明回归允许你指定 x 和 y 的不确定性比率(以防它们不相等)。 好的,谢谢,我也去找找!今天学到了很多东西。 这是对戴明的一个很好的解释。有没有一种简单的方法可以用绝对损失函数进行戴明?

以上是关于使用 lm() 进行线性回归 - 对结果感到惊讶的主要内容,如果未能解决你的问题,请参考以下文章

线性回归中的截距

多元线性回归模型用r语言怎么来实现

R语言基本回归分析

R使用lm构建多变量线性回归模型

R语言使用lm函数拟合回归模型(简单线性回归一元回归simple regression)并解读拟合模型

R语言使用lm函数拟合回归模型(简单线性回归一元回归simple regression)并解读拟合模型