注意 本来是用r markdown写的所有代码放到Rstudio里面都可以运行,无奈csdn不支持这种东西
所谓理论不过简单理解,并没有什么强力的证明
验证集方法,在Andrew的课里面涉及到过,就是将样本一部分作为训练集,一部分作为测试集,这种方法有两个缺点
这种方法用伪代码描述就是
for i = 1:n
将第i项作为测试集
将剩余的作为训练集训练,计算均方误差
这种方法训练的均方误差就是
这种方法只是LOOCV的简单扩展,就是吧数据分为k组,然后每次选一组作为测试集,其余作为验证集即可,一般令k=5或10不会产生较大的方差偏差权衡问题,感觉这种和min-batch有异曲同工之妙.
自助法就是有放回的重数据集中抽取数据组成样本,然后在样本上训练,取均值作为输出的统计量,一般来说设概率是均匀的。
训练集
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)
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)
运行发现这种方法非常慢
可以同样的使用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