【模型比较与选择】交叉验证方法原理及R语言代码实现
交叉验证是进行模型比较的一种有效方法。
它的基本原理如下(Kohavi,1995):
(1)把原始数据集分解成 r个大小近似相等的子数据集。
(2)把第一个子数据集作为验证数据集,把其余r-1个子数据集合并后用于估计模型参数。基于该模型的参数对验证数据集的因变量进行预测,并计算预测误差的平方和。
(3)把第二个、第三个......直至第r个子数据集分别作为验证数据集,并把其余的r-1个子数据集合并后用于估计模型参数。基于验证数据集计算因变量预测误差的平方和。
(4)计算前述r个预测误差平方和的平均值,平均值最小的模型为最优模型。
注意,最优模型选定以后,模型的最终参数需要基于全体数据重新估计。
交叉验证的一个特例是将每个观察值作为一个子数据集,然后使用该观察值之外的其他所有观察值估计模型参数,并计算预测误差的平方。
表达式如下:
附带R语言实现代码:以数据集state.x77为例(R语言自带,以下代码可直接运行)
#R平方的k重交叉验证
#library(bootstrap) #crossval函数实现k重交叉验证
shrinkage <- function(fit,k=10){
require(bootstrap)
theta.fit <- function(x,y){lsfit(x,y)}
theta.predict <- function(fit,x){cbind(1,x)%*%fit$coef}
#library(bootstrap) #crossval函数实现k重交叉验证
shrinkage <- function(fit,k=10){
require(bootstrap)
theta.fit <- function(x,y){lsfit(x,y)}
theta.predict <- function(fit,x){cbind(1,x)%*%fit$coef}
x <- fit$model[,2:ncol(fit$model)]
y <- fit$model[,1]
y <- fit$model[,1]
results <- crossval(x,y,theta.fit,theta.predict,ngroup = k)
r2 <- cor(y,fit$fitted.values)^2
r2cv <- cor(y,results$cv.fit)^2
cat("Original R-square =",r2,"\n")
cat(k,"Fold Cross-Validated R-square =",r2cv,"\n")
cat("Change =",r2-r2cv,"\n")
}
#对数据states所有预测变量进行回归,然后用shrinkage()函数做10重验证
states <- as.data.frame(state.x77[,c("Murder","Population","Illiteracy","Income","Frost")])
fit0 <- lm(Murder~Population+Illiteracy+Income+Frost,data=states)
shrinkage(fit0)
r2cv <- cor(y,results$cv.fit)^2
cat("Original R-square =",r2,"\n")
cat(k,"Fold Cross-Validated R-square =",r2cv,"\n")
cat("Change =",r2-r2cv,"\n")
}
#对数据states所有预测变量进行回归,然后用shrinkage()函数做10重验证
states <- as.data.frame(state.x77[,c("Murder","Population","Illiteracy","Income","Frost")])
fit0 <- lm(Murder~Population+Illiteracy+Income+Frost,data=states)
shrinkage(fit0)