本章有两个重要的内容,一个是交叉验证,一个是bootsrtap。本文主要介绍交叉验证。
交叉验证的基本思想见书。直接来看7.10.2节。错误的使用交叉验证。
该节的内容代码如下:
CV.sample.x<- matrix(rnorm(50*5000),50,5000)#生成样本集
CV.sample.y <- c(rep(0,25),rep(1,25))#生成类标签
CV.sample <- cbind(CV.sample.x,CV.sample.y)#生成类
CV.cor <- c()
for(i in 1:5000)#计算每个预测变量和类标签的相关度
{
CV.cor <- c(CV.cor,abs(cor(CV.sample.x[,i],CV.sample.y)))
}
top.100 <- order(CV.cor, decreasing = TRUE)[1:100]#取出前一百个最相关的
library(class)
#然后用交叉验证的方法来预测错误率。fold=10, k=1
vknn = function(v,data,cl,k){
# 分割原始数据,先是水平划分,然后用采样的方法打乱顺序。
grps = cut(1:nrow(data),v,labels=FALSE)[sample(1:nrow(data))]
# 对每份数据分别运行KNN函数
pred = lapply(1:v,function(i,data,cl,k){
omit = which(grps == i)
pcl = knn(data[-omit,],data[omit,],cl[-omit],k=k)
},data,cl,k)
# 整合预测结果
wh = unlist(pred)
table(wh,cl[order(grps)])
}
vknn(10,CV.sample.x[,top.100],CV.sample.y,1)
结果证明,交叉验证的预测错误率非常低。fold=10时,错误率为0。fold=5时,约为2%。
修改一下代码。
#按照书上的方法,采用正确的方法来进行交叉验证。
CV.top.100 <-function(x,y)
{
CV.cor <- c()
for(i in 1:5000)
{
CV.cor <- c(CV.cor,abs(cor(x[,i],y)))
}
top.100 <- order(CV.cor, decreasing = TRUE)[1:100]
return(top.100)
}
vknn.correct = function(v,data,cl,k){
# 分割原始数据,先是水平划分,然后用采样的方法打乱顺序。
grps = cut(1:nrow(data),v,labels=FALSE)[sample(1:nrow(data))]
# 对每份数据分别运行KNN函数
pred = lapply(1:v,function(i,data,cl,k){
omit = which(grps == i)
top.100 <- CV.top.100(data[-omit,],cl[-omit])#在训练集中找最相关的变量
pcl = knn(data[-omit,top.100],data[omit,top.100],cl[-omit],k=k)
},data,cl,k)
# 整合预测结果
wh = unlist(pred)
table(wh,cl[order(grps)])
}
vknn(5,CV.sample.x,CV.sample.y,1)
结果表明,预测错误率在50%左右,和真正的结果吻合。