这是我根据Applied Econometrics with R(springer)一书中线性回归(第三章)有关内容整理成的学习笔记,对书中的一些代码进行了解读,也根据我学到的回归知识添加了部分内容。笔记中的例子凡是书上给出过输出结果的,在这里一律省略,没给出结果的,附上结果及函数解读。这个并不是书内容的翻译,与原书有一定的出入。
Chapter 3:线性模型
需要加载函数包: AER
章节目录
3.1 简单线性模型
3.2 多变量线性模型
3.3 半线性模型
3.4 因子、交互作用、加权最小二乘
3.5 时间序列的回归
3.6 面板数据的回归
3.7 线性方程组
3.1 简单线性模型
例1:一元线性模型
数据集: journals
模型 log(subs)=β1+β2*log(citeprice)+ e
使用代码:
1) 了解数据集的基本情况
library(AER) data("Journals") journals <- Journals[, c("subs","price")] journals$citeprice <- Journals$price/Journals$citations#定义新变量citeprice summary(journals)
对数据进行基本的了解,在Hmisc,psych包中的describe函数提供了诸如离差,极差,峰度,偏度,数据量,缺失数等诸多统计量的统计结果,运行以下代码:
library(psych) describe(journals)
输出结果:
判断数据是否具有一定的线性性,我们可以使用最直观的办法画图来做初步判断,代码如下:
plot(log(subs) ~ log(citeprice),data = journals) jour_lm <- lm(log(subs) ~log(citeprice), data = journals) abline(jour_lm)
可以得到图3.1,据此可初步判断数据间具有相关性,当然cor.test()也可以做到这一点,运行cor.test(journals$subs,journals$citeprice),有以下结果:
Pearson'sproduct-moment correlation
data: journals$subs and journals$citeprice
t = -6.1661, df = 178 , p-value = 4.57e-09
alternative hypothesis: truecorrelation is not equal to 0
95 percent confidenceinterval: -0.5330837 -0.2911326
sample estimates: cor : -0.4195314
2) 线性回归模型建立
jour_lm <-lm(log(subs) ~ log(citeprice), data = journals)
回归模型的大部分结果都可以通过summary函数进行查看,运行summary(jour_lm)即可,也有一些函数供你查看模型的特定部分
函数 |
描述 |
Summary |
标准回归结果输出 |
Coef |
提取回归系数 |
Residuals |
提取回归残差 |
Fitted |
提取拟合数据 |
Anova |
与参考模型(nested model)进行对比 |
Predict |
对新数据进行预测 |
Plot |
诊断图 |
Confint |
回归系数置信区间 |
Deviance |
残差平方和 |
Vcov |
同方差假定下的协方差阵。注:异方差下使用car包的hccm函数 |
logLik |
正态假设下的最大似然值 |
AIC |
AIC |
3) 系数显著性检验
anova(jour_lm)
对于单变量回归来说,方差分析仅对系数的显著性做了检验,返回值为回归模型输出里的F统计量,但输出格式还是更接近方差分析的标准
4) 系数的区间估计
confint(jour_lm, level = 0.95)
5) 预测
predict(jour_lm, newdata =data.frame(citeprice = 2.11),interval = "confidence") predict(jour_lm, newdata =data.frame(citeprice = 2.11),interval = "prediction")
对于prediction中interval参数,在之前的博文《R 语言与简单的回归分析》中已有说明,运行下列代码可以使你更好地理解他们:
lciteprice <- seq(from = -6, to= 4, by = 0.25) jour_pred <- predict(jour_lm,interval = "prediction", +newdata = data.frame(citeprice =exp(lciteprice))) jour_pred1<- predict(jour_lm,interval = "confidence", +newdata = data.frame(citeprice =exp(lciteprice))) plot(log(subs) ~ log(citeprice),data = journals) lines(jour_pred[, 1] ~ lciteprice,col = 1) lines(jour_pred[, 2] ~ lciteprice,col = 1, lty = 2) lines(jour_pred[, 3] ~ lciteprice,col = 1, lty = 2) lines(jour_pred1[, 1] ~ lciteprice,col = 2) lines(jour_pred1[, 2] ~ lciteprice,col = 2, lty = 3) lines(jour_pred1[, 3] ~ lciteprice,col = 2, lty = 3)
输出图像略。
6) 回归效果检测图
plot(jour_lm)即可,如果只需要四幅图中的一幅,which参数可以帮你指定
7) 系数的假设检验
比如我们想检测log(citeprice)回归系数是否为0.5,运行代码:
linearHypothesis(jour_lm,"log(citeprice) = -0.5")
函数的进一步说明:例如,如果我们有一个包括常数项的五个参数的模型,并且我们的零假设如下:
β1=0 且 β3+β4=1
我们可以用如下的命令加以实现
unrestricted<-lm(y~x1+x2+x3+x4)
rhs<-c(0,1)
hm<-rbind<-(c(1,0,0,0,0),c(0,0,1,1,0))
linear.hypothesis(unrestricted,hm,rhs)
注意:如果unrestricted是由lm得到的,默认状态下将会进行F检验。如果是由glm得到的,取而代之的将是Kai方检验。检验的类型可以通过type进行修改。
同样,如果我们想利用异方差或自相关稳健标准误进行检验,我们既可以通过设定white.adjust=TRUE来使用white标准误,也可以利用vcov计算我们自己的协方差矩阵。例如,如果我们想使用上述的Newey-West修正协方差矩阵,我们可以进行如下的设定:
linearHypothesis(unrestricted, hm, rhs,vcov=NeweyWest(unrestricted))
注意:设定white.adjust=TRUE将会通过提高white估计量的精度来修正异方差;如果要使用经典的white估计量,我们可以设定white.adjust="hc0"
3.2 多变量线性模型
例2:多个自变量的一元回归模型
数据集:CPS1998
模型:log(wage)=β1+β2*experience+β3*experience2+β4*education+β5*ethnicity+e
参照模型:log(wage)=β1+β2*experience+β3*experience2+β4*education +e
使用代码:
1)我们还是先来看看数据
data("CPS1988") summary(CPS1988)
2) 建立模型
cps_lm <- lm(log(wage) ~ experience + I(experience^2)+education + ethnicity, data = CPS1988)
需要说明的是函数I(),它保证I中的表达式进行了规定的代数运算,而不是模型的运算。对于模型中的运算符含义,我们简介如下:(书上表3.2有部分内容)
假定y,x,x0,x1,x2,...是数值变量,X是一个矩阵,A,B,C,...是因子。下面左侧的公式定义了右侧描述的模型。
模型 |
说明 |
y~x y~1+x |
二者指定的模型是相同的,即y对x的简单线性模型。第一个公式的截距项是隐含的。第二个的截距项是明确给定的。 |
y~0+x y~-1+x y~x-1 |
y对x过原点的简单线性回归模型(无截距项)
|
y~poly(x,2) y~1+x+I(x^2) |
y对x的二次多项式回归。第一种形式使用正交多项式。 |
y~X+poly(x,2) |
y的多重回归。模型矩阵包含矩阵X和x的二次多项式项 |
y~A*B y~A+B+A:B y~B%in%A y~A/B |
y对A和B的两因素非可加(non-additive)模型。前两个指定了相同的交叉分类(crossed classication),后面的两个指定了相同的嵌套分类(nested classication)。抽象一点儿讲,这四个公式指定了相同的模型子空间。 |
y~(A+B+C)^2 |
三因素试验,模型包含主效应和两因素之间的交互作用。两个公式指定的是相同的模型。 |
y~A*x y~A/x y~A/(1+x)-1 |
y对x在A水平单独的简单线性回归模型,几种形式的编码不同。最后一种形式产生与A中水平数一样多的截距和斜率估计值。 |
对于不会引起误会的函数运算,我们没必要加I(),但是加上也未尝不可。
3) 虚拟变量与对照组
在上述回归模型中,我们可以看到回归结果中ethnicity项变为了ethnicityafm,这个改变是说明在回归中我们把cauc作为对照组,afm作为实验组。
对虚拟变量而言,我们都得注意考虑共线性的问题,所以我们把ethnicity这个虚拟变量中cauc记为0,afm记为1,并且以这两个数据作为回归数据,当然如果反过来,我们仅仅需要把ethnicityafm替换为1-ethnicitycauc即可得到等价的回归方程,在R中,函数contrasts(),告诉你R是如何做这个变量选择的,尝试运行: contrasts(CPS1988$ethnicity),输出为:
afam
cauc 0
afam 1
关于R中的虚拟变量选择,在R Development Core Team编写的R语言简介中有更详细的说明,现摘录如下:
对于模型公式如何指定模型矩阵的列,我们至少还要有些概念。如果我们拥有连续变量,事情就比较简单。每个变量就向模型矩阵提供一列(如果模型中包含截距,它将向模型矩阵提供一列1)。
但是对于一个k水平的因子A,答案就会因为因子是有序的还是无序的而有差别。对无序因子,对应因子的第2,……,k水平将生成k -1列(因此默认的参数化也就是将各个水平的响应值和初值进行对比)。而对有序因子,k-1则是对1,……,k的正交多项式,忽略常数项。
尽管这个答案已经挺复杂了,不过还不是全部。首先,如果在一个含有因子项的模型中省略常数项,那么第一个这样的项就会被编码为k列,对应所有的水平。此外,通过更改contrasts的选项(options),可以改变处理的方式。
在R中默认的设置是options(contrasts= c("contr.treatment", "contr.poly"))
提到这点主要是因为R和S在处理无序因子的时候使用不同的默认设置,S使用Helmert Contrasts。因此,如果你需要将你用R得到的结果与使用S-Plus的论文或教材得到的结果作比较的话,你需要设置options(contrasts = c("contr.helmert","contr.poly"))
这是一个谨慎的差别,因为treatmentcontrast(R的默认值)被认为对新手来说比较容易理解。
到这里仍然没有结束,因为通过函数contrasts和C还可以对模型中的每一项设定对比的方式。而且我们还没有考虑交互项:由他们的组件引用,生成列的积。
细节比较复杂,事实上R的模型公式一般都会生成一个统计专家所期望的那个公式,提供这种扩展是为了以防万一。比如拟合一个有交互作用但是没有对应的主效应的模型,一般结果会比较出人意料,这仅仅是为专家准备的。
4) 变量的选择
cps_noeth<- lm(log(wage) ~ experience + I(experience^2) +education, data = CPS1988) anova(cps_noeth, cps_lm)
对于任意两个嵌套模型,我们要比较两个模型的差异,可以使用函数anova。在上例中,我们想知道ethnicity对被解释变量wage的关联性,即对于两类人(afm与cauc)是否存在工资的差异。
我们想更新一个模型,比如说模型某项系数显著为0,可以使用update函数,如我们想去掉ethnicity一项,模型更新为参照模型,使用代码:
cps_noeth <- update(cps_lm, formula = . ~ . -ethnicity)
上面的“.”表示对原模型变量不作改动,“-”表示去除项“+ “表示加入项。
AER包中提供wald检验,上面使用anova的例子等价为waldtest(cps_lm, . ~ . - ethnicity)。Wald检验可以处理异方差时的模型比对问题,比anova用法要广一些。
另外,比较两个模型的回归好坏程度我们还可以使用AIC准则,使用AIC(cps_noeth, cps_lm),得到结果:
df AIC
cps_noeth 5 49965.43
cps_lm 6 49614.68
这里倒不是说两个模型有无显著差异,而是指综合变量个数与解释程度两者来看,原模型好些罢了。
我们也可以使用step函数对模型做逐步回归,以期在AIC准则下找到最优模型,运行代码:
step(cps_lm)
得到结果:
Start: AIC=-30287.75
log(wage) ~ experience + I(experience^2) + education + ethnicity
Df Sum of Sq RSS AIC
<none> 9598.6 -30288
- ethnicity 1 121.02 9719.6 -29937
- education 1 1546.38 11145.0 -26084
- I(experience^2) 1 1638.14 11236.8 -25853
- experience 1 2642.55 12241.2 -23443
Call:
lm(formula = log(wage) ~ experience + I(experience^2) +education +
ethnicity, data =CPS1988)
Coefficients:
(Intercept) experience I(experience^2) education ethnicityafam
4.321395 0.077473 -0.001316 0.085673 -0.243364
也就表明原模型不错,按aic标准而言无需改进,MASS包中stepAIC函数与其输出相同。
3.3 半线性模型
例2续:
模型:log(wage)=β1+g(experience) +β2*education+β3*ethnicity+e
说明:这里g(.)是一个待估函数,由伯恩斯坦定理知,我们总可以用多项式逼近一条曲线,我们通常使用条样回归来解决它。而B样条曲线在计算上较为方便,R中提供函数bs()来处理它,而且bs()结果可以直接用于回归模型,所以拟合理想的模型仅仅需要以下代码:
cps_plm <- lm(log(wage) ~ bs(experience,df = 5) +education + ethnicity, data = CPS1988)
其标准输出为:
Call:
lm(formula = log(wage) ~ bs(experience, df = 5)+education + ethnicity, data = CPS1988)
Residuals:
Min 1Q Median 3Q Max
-2.9315 -0.3079 0.0565 0.3672 3.9945
Coefficients:
Estimate Std.Error t value Pr(>|t|)
(Intercept) 2.775582 0.056081 49.49 <2e-16 ***
bs(experience, df = 5)1 1.891673 0.075814 24.95 <2e-16 ***
bs(experience, df = 5)2 2.259468 0.046474 48.62 <2e-16 ***
bs(experience, df = 5)3 2.824582 0.070773 39.91 <2e-16 ***
bs(experience, df = 5)4 2.373082 0.065205 36.39 <2e-16 ***
bs(experience, df = 5)5 1.739341 0.119691 14.53 <2e-16 ***
education 0.088181 0.001258 70.07 <2e-16 ***
ethnicityafam -0.248202 0.012725 -19.50 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’1
Residual standard error: 0.5747 on 28147degrees of freedom
Multiple R-squared: 0.3557, Adjusted R-squared: 0.3555
F-statistic: 2220 on 7 and 28147 DF, p-value: < 2.2e-16
书上省略了输出结果,因为作者认为条样回归的系数是不好解释的,仅仅需要注意到在这样的情况下,教育的回报率为8.82%每年。对于使用bs()函数有以下几种方式:
1、 指定分段多项式的阶数(degree),缺省时记为3和手动给出k个顶点(knot)
2、 提供参数df,其余的让机器自动选择
上面使用的表达式bs(experience,df = 5)表示使用分段三次多项式评估有关的观测experience,隐含5−3 = 2个结点间隔均匀的分布在33.33%和66.67%分位数上。
df的选择是基于模型的BIC准则,下面的代码考虑了从3到10的取值,建议使用df=5作为最佳渐进曲线的取值:
cps_bs<- lapply(3:10, function(i) lm(log(wage) ~bs(experience, df = i) + education+ ethnicity,data = CPS1988)) structure(sapply(cps_bs,AIC, k = log(nrow(CPS1988))),.Names = 3:10)
为了更好地理解条样回归与二次函数回归的差别,书利用控制变量的办法给出了图3.4(关注两条线的曲率变化)书图3.4的作图程序如下:
cps <-data.frame(experience = -2:60, education = with(CPS1988,mean(education[ethnicity == "cauc"])),ethnicity = "cauc") cps$yhat1<- predict(cps_lm, newdata = cps) cps$yhat2<- predict(cps_plm, newdata = cps) plot(log(wage)~ jitter(experience, factor = 1), pch = 19,col = rgb(0.5, 0.5, 0.5, alpha =0.02), data = CPS1988) lines(yhat1~ experience, data = cps, lty = 2) lines(yhat2~ experience, data = cps) legend("topleft",c("quadratic", "spline"), lty = c(2,1),bty = "n")
注:
1、 cps数据中,仅experience项有变化,教育与种族两项数据是一致的
2、 jitter()对数据做一定的抖动,试运行以下代码:
x <-rbinom(1000, 10, 0.25) y <-rbinom(1000, 10, 0.25) plot(x,y)#抖动前 plot(jitter(x),jitter(y))#抖动后
3、 rgb()给出了具体的颜色,返回结果的解读可参见如果rgb代码,alpha设定透明度
4、 图3.4表明,两个模型对于20 - 40年的经验范围没有太大的差别。总的来说,experience<8年时的条样回归曲率低些。然而,最明显的特征似乎低于7年的experience的条样回归曲率明显的小。另一个可供选择的方法是使用核的方法,在np包中你可以找到相应的执行函数。
3.4因子、交互作用、加权最小二乘
3.5时间序列的回归
3.6面板数据的回归
3.7线性方程组
(待续)