R语言--回归分析2(异常值处理、全子集回归、交叉验证)


1 异常观测值

states<-as.data.frame(state.x77[,c("Murder",

           "Population","Illiteracy","Income","Frost")])

fit<-lm(Murder~Population+Illiteracy+Income+Frost,data=states)  #回归分析

summary(fit)

 

1.1 离群值 (y,模型做出来之后,预测的特别不准的值)

library(car)

outlierTest(fit)

 

 

1.2 高杠杆值(只看xx值比较突出)

hat.plot<-function(fit){

  p<-length(coefficients(fit))#返回各相关系数的长度

 

 

  n<-length(fitted(fit))  #fitted是一个通用函数,用于从建模函数返回的对象中提取拟合值

  plot(hatvalues(fit),main="Index Plot of Hat Values")

  abline(h=c(2,3)*p/n,col="red",lty=3)  #画参考线,红色的

  identify(1:n,hatvalues(fit),names(hatvalues(fit)))  #标出几个高杠杆点的名字

}

hat.plot(fit)  

 

结果分析:看到图的左上角有这句话

,依次点击高杠杆点(第一条红线上方的点),然后按键盘Esc,就会出现上图所示的5个点的名字,

 

1.3 强影响点(如果把强影响点去掉,回归模型会发生巨大的变化,对参数估计产生强影响)

cutoff<-4/(nrow(states)-length(fit$coefficients)-2)

plot(fit,which=4,cook,levels=cutoff)

abline(h=cutoff,lty=3,col="red")

 

 

 

1.4 综合给出离群值,高杠杆值、强影响点

library(car)

influencePlot(fit,id=list(method="identity"))  #为什么我的不是互动图

 

结果分析:在纵轴(y轴)上超过虚线2的就认为是离群点,在横轴(x轴)认为超过第二根虚线的就是高杠杆点,气泡很大的点认为是强影响点

 

2 改进措施

states<-as.data.frame(state.x77[,c("Murder",

           "Population","Illiteracy","Income","Frost")])

fit<-lm(Murder~Population+Illiteracy+Income+Frost,data=states)  #回归分析

 

2.1 删除观测点

states2<-subset(states,row.names(states)!="Nevada")  #删除Nevada州这个记录

 

2.2 变量变换

方式一:y变换

library(car)

summary(powerTransform((states$Murder)))

 

结果分析:Est Power这个表明了是y的期待值,下方的 0.6055y0.6055次方;lambda = (0)这个0代表logy,做了假设检验,这里 pval=0.017297P值小于0.05,即不合理;lambda = (1)这里的1代表y的一次方,(如果括号里面是-1,则代表y-1次方),此时统计检验的结果 pval=0.14512P值大于0.05,这个时候不能拒绝,我们会继续用y=kx做回归,这个时候就不会考虑上方的期待值Est Power

 

方式二:对x变换

boxTidwell(Murder~Population+Illiteracy,data=states)

 

结果分析:这里给出了Murder= Population0.86939 次方 + Illiteracy1.35812次方,并且Pr(>|z|) 都大于0.05,不能拒绝,所以我们会保留y = k0 + k1x + k2x 这种形式

 

2.3 增加或删除变量

states2<-subset(states,row.names(states)!="Nevada",select=c(-Income,-Frost))

解释:这里删除了州Nevada所在行的记录,并且删除了两列IncomeFrost

 

 

  

3 选择最佳的回归模型

states<-as.data.frame(state.x77[,c("Murder",

           "Population","Illiteracy","Income","Frost")])

fit1<-lm(Murder~Population+Illiteracy+Income+Frost,data=states)  #回归分析

fit2<-lm(Murder~Population+Illiteracy,data=states)  #回归分析

 

3.1 模型比较

1anova(fit1,fit2)

 

结果分析:Pr(>F)=0.9939大于0.05,所以不能拒绝原假设,即我们的两个模型fit1fit2没什么差别

2AIC(fit1,fit2)

 

结果分析:AIC是对模型精度和简洁的权衡,越小越好,所以我们更倾向于选择fit2(即两变量PopulationIlliteracy 模型)

 

3.2 变量选择

library(MASS)

stepAIC(fit1,direction="backward")

 

 

结果分析:首先给出AIC的值,即AIC=97.75,之后通过一个个删除变量,每次计算AIC的值,若删除某变量能使AIC的值变小,就给删除,因此最后得出了最佳的模型,即lm(formula = Murder ~ Population + Illiteracy, data = states),并且给出了各变量的系数

 

 

 

 3.3  全子集回归

上节中的轮流删除会存在争议,没有排列组合,所以用此来做排列组合确定精度更佳

library(leaps)

leaps<-regsubsets(Murder~Population+Illiteracy+Income+Frost,data=states,nbest = 4)

plot(leaps,scale="adjr2")

 

结果分析:纵轴是我们需要看的,最上面的是最优拟合的

 

4 深层次分析

states<-as.data.frame(state.x77[,c("Murder",

           "Population","Illiteracy","Income","Frost")])

fit1<-lm(Murder~Population+Illiteracy+Income+Frost,data=states)  #回归分析

fit2<-lm(Murder~Population+Illiteracy,data=states)  #回归分析

 

4.1 交叉验证

install.packages("bootstrap")  #下载包

shrinkage<-function(fit,k=10){   #自定义函数,定义形参

  require(bootstrap)  #类似与library(),加载包的功能

  

  theta.fit<-function(x,y){lsfit(x,y)} #lsfit是最小二乘法拟合,theta.fit是线性模型

  theta.predict<-function(fit,x){cbind(1,x)%%fit$coef}  

  #cbind(1,x)x多增加一列,这一列全部是1fit$coef是回归系数, theta.predict是线性模型的预测

  x<-fit$model[,2:ncol(fit$model)]  #x是所有行,并且是第2列到最后一列

  y<-fit$model[,1]   #yfit1表的第一列中的内容

  

  resules<-crossval(x,y,theta.fit,theta.predict,ngroup=k) #传递参数,做k重交叉验证

  

  r2<-cor(y,fit$fitted.values)^2  #求原始的R平方

  r2cv<-cor(y,resules$cv.fit)^2  #求交叉验证之后的R平方

  

  cat("Original R-square=",r2,"\n")  #cat()函数是把字符串连接起来的功能,把结果输出到屏幕上

  cat(k,"Fold Cross-Validated R-square=",r2cv,"\n")

  cat("Chage=",r2-r2cv,"\n")

}

 

 结果分析:经过10重验证之后,即设置k=10R-square改变了很多,其中改变值 Chage= 0.5635281 ,改变值比较大,说明模型不稳定

 

结果分析:经过10重验证之后,即设置k=10R-square改变很小,其中改变值 Chage= 0.1983639  ,改变值很小,说明模型稳定

 

4.2 相对重要性

states<-as.data.frame(state.x77[,c("Murder",

                                   "Population","Illiteracy","Income","Frost")])

fit<-lm(Murder~Population+Illiteracy+Income+Frost,data=states)

zstates<-as.data.frame(scale(states))  #对每列数据标准化

zfit<-lm(Murder~Population+Illiteracy+Income+Frost,data=zstates)  #做回归分析

coef(zfit) #求回归系数

 

结果分析:文盲率Illiteracy每增加1个点,谋杀率Murder会增加6.8


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM