《ISLR》交叉验证与自助法

注意 本来是用r markdown写的所有代码放到Rstudio里面都可以运行,无奈csdn不支持这种东西

理论

所谓理论不过简单理解,并没有什么强力的证明

验证集方法

验证集方法,在Andrew的课里面涉及到过,就是将样本一部分作为训练集,一部分作为测试集,这种方法有两个缺点

  1. 受训练集的影响波动性很大
  2. 由于被训练的观测很少,统计方法表现不好

留-交叉验证(LOOCV)

这种方法用伪代码描述就是

for i = 1:n
  将第i项作为测试集
  将剩余的作为训练集训练,计算均方误差

这种方法训练的均方误差就是

CV(n)=1nΣni=1MSEi

这种方法的计算时间比较长,不过《ISLR》中说在用最小二乘法时可以用如下公式将时间缩短(函数cv.glm)并没有用这种方法
CVn=1nΣni=1(yiyi^1hi)2

其中 hi 是杠杆值

K折交叉法

这种方法只是LOOCV的简单扩展,就是吧数据分为k组,然后每次选一组作为测试集,其余作为验证集即可,一般令k=5或10不会产生较大的方差偏差权衡问题,感觉这种和min-batch有异曲同工之妙.

自助法bootstrap

自助法就是有放回的重数据集中抽取数据组成样本,然后在样本上训练,取均值作为输出的统计量,一般来说设概率是均匀的。

验证集方法

训练集

library(ISLR)
set.seed(1)
train = sample(392,196)

拟合线性模型

lm.fit = lm(mpg~horsepower,data=Auto,subset = train)

残差计算

attach(Auto)
rss = mean((mpg[-train]-predict(lm.fit,Auto[-train,]))^2)

高次多项式拟合

rss = rep(0,time=10)
for(i in 1:10){
  lm.tmp<-lm(mpg~poly(horsepower,i),data = Auto,subset = train)
  rss[i] <- mean((mpg[-train]-predict(lm.tmp,Auto[-train,]))^2)
}
plot(rss)

留-交叉验证法(LOOCV)

library(boot)
cv.err = rep(0,5)
for( i in 1:5){
  glm.fit = glm(mpg~poly(horsepower,i),data = Auto)
  cv.err[i] = cv.glm(Auto,glm.fit)$delta[1]
}
plot(cv.err)

运行发现这种方法非常慢

k折交叉验证法

可以同样的使用cv.glm() 来做k折交叉验证,只需将k设定一个值,返回值delta[1]是标准估计,而第二个数值是偏差矫正后的结果

cv.err <- rep(0,10)
for(i in 1:10){
  glm.fit <- glm(mpg~poly(horsepower,i),data = Auto)
  cv.err[i] = cv.glm(Auto,glm.fit,K=10)$delta[1]
}
plot(cv.err)

自助法

r 中的包boot中的方法boot可以用来执行自助法,使用boot需要提供一个计算统计量的函数,第一个参数默认为数据,第二个参数接受index

alpha.fn <- function(data,index){
  X= data$X[index]
  Y=data$Y[index]
  return((var(Y)-cov(X,Y))/(var(X)+var(Y)-2*cov(X,Y)))
}
#自助法模拟
boot(Portfolio,alpha.fn,R=1000)#数据,统计量函数,次数

将boot作为变量返回,我们会发现很多东西,

boo = boot(Portfolio,alpha.fn,R=1000)
boo$t0 #统计量结果
boo$t #每次计算值
boo$weights #每一项所占权值

自助法估计线性回归模型精度

boot.fn <- function(data,index){
  return(coef(lm(mpg~horsepower,data=data,subset = index)))
}
boot.fn(Auto,1:392)
boot(Auto,boot.fn,1000)
#与summary的结果比较
summary(lm(mpg~horsepower,data = Auto))$coef

你可能感兴趣的:(数据分析)