9 线性回归

9.1 Simple Linear Regression

Many shall be restored that now are fallen;

Many shall be fallen that now are in honor.

相关性是简单线性回归它爹,回归的概念来自于Francis Galton,他发现高个子男人生出来的儿子会比自己矮,而矮个子男人生出来的儿子会比自己高,并称这种现象为回归平庸(regression toward mediocrity),现在被称之为回归均值(regression to the mean),Galton有个学生叫Karl Pearson,他给出了相关性和回归的数学公式,这也是相关系数被命名为Pearson相关系数的原因,而相关系数的符号r则取自于回归(regression)一词。

简单线性回归名副其实,非常简单,在假定X和Y是线性关系,使用单变量X来预测Y。

\[ Y \approx \beta_0 + \beta_1 X \]

假设我们要用花萼长度来预测花瓣长度,

require(ggplot2)
data(iris)
attach(iris)
## The following objects are masked from iris (pos = 3):
## 
##     Petal.Length, Petal.Width, Sepal.Length, Sepal.Width, Species
p <- ggplot(iris, aes(Sepal.Length, Petal.Length))+
        geom_point(shape=1, color="red")
print(p)

我们需要拟合: \[ Petal \approx \beta_0 + \beta_1 Sepal \]

\(\beta_0\)\(\beta_1\) 代表线性模型的截距和斜率,这两个模型参数是未知的,需要通过训练数据估计 \(\hat{\beta_0}\)\(\hat{\beta_1}\)

使得直线 \[ \hat{y} = \hat{\beta_0} + \hat{\beta_1} x \] 与数据集中的点最接近,有多种方法来来计算“接近度“,最常用的是最小二乘法(least squares)。

最小二乘法通过计算残差平方和(RSS, residual sum of squares) \[ RSS = {e_1}^2 + {e_2}^2 + … + {e_n}^2 \] 其中 \(e_i = y_i - \hat{y_i}\) . 问题转换为找出 \(\hat{\beta_0}\)\(\hat{\beta_1}\) 使得RSS的值最小。 通过计算,可以得到: \[ \hat{\beta_1} = \frac{\sum_{i=1}^n (x_i - \bar{x})(y_i - \bar{y})}{\sum_{i=1}^n (x_i - \bar{x})^2} = r_{xy} (\frac{s_y}{s_x})\] \[ \hat{\beta_0} = \bar{y} - \hat{\beta_1}\bar{x} \]

b1 <- sum((Petal.Length-mean(Petal.Length)) * (Sepal.Length-mean(Sepal.Length)))/sum((Sepal.Length-mean(Sepal.Length))^2)
b0 <- mean(Petal.Length) - b1 * mean(Sepal.Length)
cat("Intersect:\t", b0, "\n", "Slope:\t", b1, "\n")
## Intersect:    -7.101443 
##  Slope:   1.858433

stats包中的lm()函数,用于拟合线性模型。

model <- lm(Petal.Length ~ Sepal.Length, data=iris)
model
## 
## Call:
## lm(formula = Petal.Length ~ Sepal.Length, data = iris)
## 
## Coefficients:
##  (Intercept)  Sepal.Length  
##       -7.101         1.858

9.1.1 评估参数准确性

打个比方,我们使用样本均值 \(\hat{\mu}\) 来估计总体均值 \(\mu\) ,对于任意一个样本的 \(\hat{\mu}\) 值,有可能会高估 \(\mu\) ,也有可能会低估,需要量化到底 \(\hat{\mu}\) 偏离 \(\mu\) 有多远,这个问题通过计算standard error of \(\hat{\mu}\) 来解决。

同样地,我们估计出来的参数 \(\hat{\beta_0}\)\(\hat{\beta_1}\) 和真实的参数到底偏离多远,需要通过计算参数的standard error来估计。 \[ SE(\hat{\beta_0})^2 = \sigma^2 [\frac{1}{n} + \frac{\bar{x}^2}{\sum_{i=1}^n (x_i-\bar{x})^2}] \] \[ SE(\hat{\beta_1})^2 = \frac{\sigma^2}{\sum_{i=1}^n (x_i-\bar{x})^2} \]

其中 \(\sigma^2 = Var(\epsilon)\) ,通常情况下是未知的,使用残差标准误 \(RSE=\sqrt{RSS/(n-2)}\) 来估计。

p+geom_smooth(method="lm", se=TRUE, level=0.95)

上图中,阴影部分就是参数的95%置信区间。

有了标准误,还可以用统计检验来检测X和Y是否具有相关性。 在这里,可以使用t检验,计算t统计量: \[ t = \frac{\hat{\beta_1} - 0}{SE(\hat{\beta_1})} \]

这些统计量,lm()函数都会计算。

summary(model)
## 
## Call:
## lm(formula = Petal.Length ~ Sepal.Length, data = iris)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -2.47747 -0.59072 -0.00668  0.60484  2.49512 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -7.10144    0.50666  -14.02   <2e-16 ***
## Sepal.Length  1.85843    0.08586   21.65   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.8678 on 148 degrees of freedom
## Multiple R-squared:   0.76,  Adjusted R-squared:  0.7583 
## F-statistic: 468.6 on 1 and 148 DF,  p-value: < 2.2e-16

9.1.2 评估模型准确性

9.1.2.1 残差标准误(RSE, residual standard error)

iris$fitted <- predict(model)
p %+% iris +  aes(x=fitted, y=Petal.Length-fitted) + geom_linerange(aes(ymin = 0, ymax = Petal.Length - fitted), colour = "purple") + geom_hline(aes(yintercept = 0)) + ggtitle("Residual Distribution")+ylab("Residual")

RSE是Y值和回归直线偏离值均值: \[ RSE = \sqrt{\frac{RSS}{n-2}} = \sqrt{\frac{\sum_{i=1}^n (y_i-\hat{y_i})^2}{n-2}} \]

rse <- with(iris, sqrt(sum((fitted - Petal.Length)^2)/(length(Petal.Length)-2)))
print(rse)
## [1] 0.8678147

通过RSE,可以计算模型预测值和真实值平均水平偏离多少。偏离量大不大,可以用 \(RSE/\bar{y}\) 来估计。

with(iris, rse/mean(Petal.Length))
## [1] 0.2309246

RSE度量的是失拟(lack of fit),如果RSE很小,则 \(\hat{y_i}\)\(y_i\) 很接近,模型对数据的拟合非常好,如果RSE很大,则表明模型对数据的拟合很差。

9.1.2.2 \(R^2\) 统计量

RSE是绝对值,不够清晰,用 \(RSE/\bar{y}\) 相对值会好一些。 \(R^2\) 提供另外一种度量方式: \[ R^2 = \frac{TSS - RSS}{TSS} = 1 - \frac{RSS}{TSS}\]

其中 \(TSS=\sum(y_i - \bar{y})^2\) ,TSS度量Y的方差,也就是拟合前总的方差;而RSS度量的是残差的方差,也就是拟合后无法解释的方差;TSS-RSS度量的是能够由拟合模型解释的方差;继而, \(R^2\) 统计量度量的是Y的方差能由X来解释的比例。

\(R^2\) 接近1,表明回归能解释Y的方差,回归模型拟合得好。而接近0的话,则表明无法解释Y的大部分方差,拟合模型很差,甚至可能是错的。

tss <- with(iris, sum((Petal.Length - mean(Petal.Length))^2))
rss <- with(iris, sum((fitted-Petal.Length)^2))
rr <- 1 - rss/tss
rr
## [1] 0.7599546

\(R^2\) 统计量度量的是X和Y的线性相关性,我们知道相关系数r定义为: \[ Cor(X, Y) = \frac{\sum_{i=1}^n (x_i - \bar{x}) (y_i - \bar{y})}{\sqrt{\sum_{i=1}^n (x_i - \bar{x})^2)}\sqrt{\sum_{i=1}^n (y_i - \bar{y})^2)}}\]

同样我们可以用相关系数r来评估模型,事实上 \(R^2 = r^2\) ,可以说 \(R^2\)\(r^2\) 的通用形式,相关系数只能用于单变量,如果要用多变量做线性回归的话,就没法用,从这个角度来看,也可以说 \(R^2\)\(r^2\) 的扩展形式。

9.1.3 方差分析

如前所述,Y的方差TSS,由两部分组成,残差方差(RSS)和回归方差(TSS-RSS),继而我们可以进行方差分析,TSS的自由度是n-1, 回归方差是1(简单线性回归是单变量),残差方差的自由度是n-2 (TSS的df - 回归方差df),将方差除以自由度,得到平均方差。

如果不存在线性关系,那么回归平均方差和残差平均方差大致相等。可以使用F统计量来检验是否存在线性关系。 \[ F = \frac{regression\; mean\; square}{residual\; mean\; square} = \frac{TSS-RSS}{RSS/(n-2)}\]

F统计量服从1和n-2自由度的F分析,继而可以计算出p值,当然可以直接扔给anova函数,进行统计计算。

n <- nrow(iris)
fstat <- (tss-rss)/(rss/(n-2))
print(fstat)
## [1] 468.5502
pf(fstat, 1, n-2, lower.tail=F)
## [1] 1.038667e-47
anova(model)
## Analysis of Variance Table
## 
## Response: Petal.Length
##               Df Sum Sq Mean Sq F value    Pr(>F)    
## Sepal.Length   1 352.87  352.87  468.55 < 2.2e-16 ***
## Residuals    148 111.46    0.75                      
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

9.1.4 可视化辅助诊断模型

评估模型最重要的指标是残差,R提供了函数可视化残差,残差 vs 拟合值, 残差开方 vs 拟合值, 残差的QQ图,标准化残差 vs Leverage, leverage度量的是数据点对回归线的影响

par(mfrow=c(2,2))
plot(model)

9.2 Multiple Linear Regression

在简单线性回归中,我们使用花萼长度来预测花瓣长度,在iris数据集里,还有花萼宽度、花瓣宽度的数据,如果我们想探索花萼宽度和花瓣宽度与花瓣长度的关系,可以分别做简单线性回归,这样子每一个简单线性回归,都忽略了其它两个因素的影响。事实上,一个现象常常与多个因素相联系,由多个变量组合共同来预测因变量,会更加有效。

多元线性回归模型和简单线性回归一样,每个变量需要一个斜率参数: \[ Y = \beta_0 + \beta_1 X_1 + \beta_2 X_2 + \cdot\cdot\cdot + \beta_p X_p + \epsilon \]

假设这里有p个变量, \(X_j\) 代表第j个变量, \(\beta_j\) 代表 \(X_j\) 每升高一个单位对Y的平均影响。

真实的参数是未知的,我们需要估计 \(\hat{\beta}_0,\hat{\beta}_1,...,\hat{\beta}_p\) 来估计回归参数 \(\beta_0,\beta_1,...,\beta_p\) ,于是回归模型就变成:

\[ \hat{y} = \hat{\beta}_0 + \hat{\beta}_1 x_1 + \hat{\beta}_2 x_2 + \cdot\cdot\cdot + \hat{\beta}_p x_p\]

参数估计依然使用最小二乘法,找出参数 \(\hat{\beta}_0,\hat{\beta}_1,...,\hat{\beta}_p\) 使得RSS最小。 \[ RSS= \sum_{i=1}^n (y_i - \hat{y}_i)^2 \\ = \sum_{i=1}^n (y_i - \hat{\beta}_0 - \hat{\beta}_1 x_1 - \hat{\beta}_2 x_2 - \cdot\cdot\cdot - \hat{\beta}_p x_p)^2 \]

从数值计算上看,这是个优化问题,使用矩阵运算还是比较容易的,具体请戳这里

在R里,依然可以使用lm函数来做多元线性回归:

data(iris)
lm.fit <- lm(Petal.Length ~ Petal.Width+Sepal.Length+Sepal.Width, data=iris)
lm.fit
## 
## Call:
## lm(formula = Petal.Length ~ Petal.Width + Sepal.Length + Sepal.Width, 
##     data = iris)
## 
## Coefficients:
##  (Intercept)   Petal.Width  Sepal.Length   Sepal.Width  
##      -0.2627        1.4468        0.7291       -0.6460

9.2.1 相关问题

进行多元线性回归,我们需要回答以下一些重要的问题: + X和Y是否存在关系? + 所有自变量都有助于解释Y吗?或者说是否只有一部分自变量对Y的预测是有用的? + 模型对数据的拟合有多好? + 预测的准确性有多好?

9.2.1.1 X和Y是否存在关系?

对于这个问题,可以使用在简单线性回归中提到的RSE和 \(R^2\) 来评估。

## TSS
tss <- with(iris, sum((Petal.Length - mean(Petal.Length))^2))
## if calculate prediction values manually, use the following command:
## b <- lm.fit$coefficients
## iris$"(Intercept)" <- 1
## d <- as.matrix(iris[, names(b)])
## iris$fitted <- d %*% as.matrix(b, ncol=1)
## RSS
iris$fitted <- predict(lm.fit)
rss <- with(iris, sum((fitted-Petal.Length)^2))
b <- lm.fit$coefficients
p <- length(b) - 1
n <- nrow(iris)
df <- n - p -1

## RSE
rse <- sqrt( rss/df )
print(rse)
## [1] 0.3189554
## R-squared
rr <- 1 - rss/tss
print(rr)
## [1] 0.9680118

\(R^2\) 是很高的,证明X和Y确实是存在关系的。 另一方面,可以做统计检验,如果X和Y没有关系,那么参数 \(\beta_1 = \beta_2 = \cdot\cdot\cdot = \beta_p = 0\) ,我们可以检验零假设: \[ H_{0}: \beta_1 = \beta_2 =... = \beta_p = 0\] \[H_{a}: at\; least\; one\; \beta_j\; is\; non-zero.\]

这个假设检验通过计算F统计量: \[ F = \frac{(TSS-RSS)/p}{RSS/(n-p-1)}\]

其中 \(TSS=\sum(y_i - \bar{y})^2\)\(RSS=\sum(y_i - \hat{y}_i)^2\) ,如果线性模型是正确的,那么: \[E\{RSS/(n-p-1)\} = \sigma^2\] 如果 \(H_0\) 是对的,则 \[E\{(TSS - RSS)/p\} = \sigma^2\]

因此如果 \(H_0\) 是对的,那么F统计量的值因为接近于1,如果 \(H_a\) 是对的,则 \(E\{(TSS - RSS)/p\} > \sigma^2\) ,F统计量要大于1。

## F-statistic
fstat <- ((tss-rss)/p) / (rss/df)
print(fstat)
## [1] 1472.726

F统计量服从F分布,可以根据F分布来计算p值,以决定是否reject \(H_0\)

pf(fstat, p, n-p-1, lower.tail=F)
## [1] 6.976868e-109

上面计算的这些统计量,lm函数都有计算。

summary(lm.fit)
## 
## Call:
## lm(formula = Petal.Length ~ Petal.Width + Sepal.Length + Sepal.Width, 
##     data = iris)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.99333 -0.17656 -0.01004  0.18558  1.06909 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -0.26271    0.29741  -0.883    0.379    
## Petal.Width   1.44679    0.06761  21.399   <2e-16 ***
## Sepal.Length  0.72914    0.05832  12.502   <2e-16 ***
## Sepal.Width  -0.64601    0.06850  -9.431   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.319 on 146 degrees of freedom
## Multiple R-squared:  0.968,  Adjusted R-squared:  0.9674 
## F-statistic:  1473 on 3 and 146 DF,  p-value: < 2.2e-16

而且还对每个变量计算了p值,这些p值给出了每一个 \(x_j\) 和y是否相关的信息。

9.2.1.2 变量选择

通过上面输出中每个参数的p值,可以看出每个变量对y的贡献是不一样的,很多情况下,y只和其中某一部分 \(x_j\) 有关,这就涉及到变量选择问题。

针对这个问题有三种方法: + Forward selection:从空模型(只包含截距)开始,对p个变量分别做简单线性回归,对产生最小RSS的变量加入到模型中,继而做两变量拟合,把产生最小RSS的第二个变量,再加入到模型中,不断迭代直到停止条件产生。 + Backward selection:所有变量一起拟合,然后移除p值最大的变量,再对(p-1)个变量重新拟合,再移除最大p值的变量,不断迭代,直到停止条件出现。 + Mixed selection:这是Forward和Backward selection的组合,从空模型开始,按照Forward selection来做,变量一个个地加入,在这个过程中,某些变量的p值是有可能升高的,如果p值高于某个阈值,移除这个变量。不断地进行forward和backward步骤,直到模型中的所有变量p值都足够小,而模型外的变量,如果加入到模型中,会产生比较大的p值。

Backward selection不能应用于 p > n的情况下,而Forward selection则可以,Forward selection是贪婪方法,开始加入的变量到了后面可能变成冗余,而Mixed selection可以弥补这一点。

9.2.1.3 模型拟合

模型对数据的拟合度有多好,可以使用之前计算过的RSE和 \(R^2\) 来评估。 简单线性回归给出的RSE公式,是针对简单线性回归的简化形式,其通过形式为: \[ RSE = \sqrt{\frac{RSS}{n-p-1}} \]

在简单线性回归中 \(R^2\) 是X和Y的相关系数的平方,在多元线性回归中,它等于Y和 \(\hat(Y)\) 的相关系数的平方。事实上拟合后的模型,除了RSS最小之外, \(R^2\) 是最大的。

with(iris, cor(fitted, Petal.Length)^2)
## [1] 0.9680118

按相关系数计算的 \(R^2\) 和之前使用 \(1 - \frac{RSS}{TSS}\) 计算的是一样的。

9.2.1.4 模型预测

参数预测本身是有误差的,即使我们知道真实的参数,也不可能完美地预测数据,因为模型中包含有随机误差 \(\epsilon\) ,在预测的时候,最好使用置信区间,这样把uncertainty的信息也包括在内。

xx <- predict(lm.fit, se.fit=TRUE, interval="confidence", level=0.95)
xx <- as.data.frame(xx$fit)
xx$y <- iris$Petal.Length
head(xx)
##        fit      lwr      upr   y
## 1 1.484210 1.393923 1.574497 1.4
## 2 1.661389 1.569631 1.753146 1.4
## 3 1.386358 1.296915 1.475802 1.3
## 4 1.378046 1.284284 1.471808 1.5
## 5 1.346695 1.251095 1.442294 1.4
## 6 1.733905 1.619998 1.847812 1.7
mean(with(xx, y> lwr & y < upr))
## [1] 0.3266667

这个模型的 \(R^2\) 是0.968,拟合得如此好的模型,预测起来,偏差还是有那么些,真实值落在预测的95%置信区间里,只占了35%不到。

yy <- predict(lm.fit, se.fit=TRUE, interval="prediction", level=0.95)$fit
## Warning in predict.lm(lm.fit, se.fit = TRUE, interval = "prediction", level = 0.95): predictions on current data refer to _future_ responses
colnames(yy) <- c("fitpred", "lwrpred", "uprpred")
xx <- cbind(xx, yy)
head(xx)
##        fit      lwr      upr   y  fitpred   lwrpred  uprpred
## 1 1.484210 1.393923 1.574497 1.4 1.484210 0.8474110 2.121009
## 2 1.661389 1.569631 1.753146 1.4 1.661389 1.0243794 2.298398
## 3 1.386358 1.296915 1.475802 1.3 1.386358 0.7496783 2.023038
## 4 1.378046 1.284284 1.471808 1.5 1.378046 0.7407447 2.015347
## 5 1.346695 1.251095 1.442294 1.4 1.346695 0.7091209 1.984269
## 6 1.733905 1.619998 1.847812 1.7 1.733905 1.0933304 2.374480
mean(with(xx, y> lwrpred & y < uprpred))
## [1] 0.9733333

显然用prediction方法,给出的预测值置信区间要靠谱得多。

ggplot(xx, aes(fit, y))+geom_point() + geom_line(aes(y=fit)) + geom_line(aes(y=lwr), color="red") +  geom_line(aes(y=upr), color="red") +  geom_line(aes(y=lwrpred), color="blue") +  geom_line(aes(y=uprpred), color="blue")

9.2.2 数值运算

参考以前的博文 \[ B = (X^TX)^{-1}(X^TY)\]

X=iris[,c("Petal.Width", "Sepal.Length", "Sepal.Width")]
X=as.matrix(X)
X=cbind(x0=1, X)
Y=as.matrix(iris[, "Petal.Length"])
solve(t(X) %*% X) %*% t(X) %*% Y
##                    [,1]
## x0           -0.2627112
## Petal.Width   1.4467934
## Sepal.Length  0.7291384
## Sepal.Width  -0.6460124
lm.fit
## 
## Call:
## lm(formula = Petal.Length ~ Petal.Width + Sepal.Length + Sepal.Width, 
##     data = iris)
## 
## Coefficients:
##  (Intercept)   Petal.Width  Sepal.Length   Sepal.Width  
##      -0.2627        1.4468        0.7291       -0.6460

按照公式计算出来,和lm.fit的结果是一样的。