1.交叉验证
1.1 基本概念
交叉验证的基本思想是将数据集分割成N份,依次使用其中1份作为测试集,其他N1份整合到一起作为训练集,将训练好的模型用于测试集上,以得到模型好坏的判断或估计值,可以得到N个这样的值。交叉验证通常用于估计模型的误差,这里将N个对应的误差求平均作为对模型误差的估计。也可以根据这N个值,选岀拟合效果最好的模型,对应模型的参数也被认为是最优或接近最优的,因此交叉验证可以用来辅助确定参数。
1.2 代码实现
#本函数实现对样本的分割
#df:data.frame对象
#k:分割数量
#return:带有I_kvalue属性的完整数据集
#注意sample函数中的参数默认是“对位”的sample(x=x,size,replace=TRUE,prob=c(0.4,0.6))分别是数据集、尺寸、是否可重复、抽取的概率
sampleSplit <- function(df,k)
{
df$I_kvalue <- sample(1+((1:dim(df)[1])%%k),dim(df)[1]) # dim(iris):150 5 dim(df)[1]=5
return(df)
}
out=sampleSplit(iris,k=10)
table(out$I_kvalue)
#table是其中的数出现的次数
##
## 1 2 3 4 5 6 7 8 9 10
## 15 15 15 15 15 15 15 15 15 15
# > out
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species I_kvalue
# 1 5.1 3.5 1.4 0.2 setosa 9
# 2 4.9 3.0 1.4 0.2 setosa 1
# 3 4.7 3.2 1.3 0.2 setosa 2
# 4 4.6 3.1 1.5 0.2 setosa 2
# 5 5.0 3.6 1.4 0.2 setosa 8
# 6 5.4 3.9 1.7 0.4 setosa 4
# 7 4.6 3.4 1.4 0.3 setosa 5
# 8 5.0 3.4 1.5 0.2 setosa 3
# 9 4.4 2.9 1.4 0.2 setosa 9
# 1、使用交叉验证得到的参数
set.seed(1234)
k=10
out=sampleSplit(iris,k)
#初始化最小均方误差minError
minError=100
#初始化最佳拟合结果finalfit
finalfit=NULL
for(i in 1:k)
{
#选择第i个子样本之外的其它所有样本作为训练集
trainset=out[out$I_kvalue!=i,1:(dim(out)[2]-2)]
#选择第i个子样本作为测试集
testset=out[out$I_kvalue==i,1:(dim(out)[2]-2)]
#拟合线性回归模型
lm.fit=lm(Petal.Width~Sepal.Length+Sepal.Width+Petal.Length,data=trainset)
#基于测试集得出预测结果
testset$pred=predict(lm.fit,testset)
#计算均方误差
error=mean((testset$Petal.Width-testset$pred)^2)
#判断是否最小均方误差
if(error<minError)
{
minError=error
finalfit=lm.fit
}
}
print(minError)
## [1] 0.009822179
print(finalfit$coefficients)
## (Intercept) Sepal.Length Sepal.Width Petal.Length
## -0.2488242 -0.1977551 0.2176520 0.5157144
# 2、使用一般方法得到的参数
lm.fit=lm(Petal.Width~Sepal.Length+Sepal.Width+Petal.Length,data=iris)
print(lm.fit$coefficients)
## (Intercept) Sepal.Length Sepal.Width Petal.Length
## -0.2403074 -0.2072661 0.2228285 0.5240831
2. 网格搜索
2.1 基本概念
网格搜索的基本原理是将各参数变量值的区间划分为一系列的小区间,并按顺序计算出对应各参数变量值组合所确定的目标值(通常是误差),并逐一择优,以得到该区间内最小目标值及其对应的最佳参数值。该方法可保证所得的搜索解是全局最优或接近最优的,可避免产生重大的误差。
2.2 代码实现
minMSE=1000
f_a0=NULL
f_b0=NULL
f_c0=NULL
f_d0=NULL
k=55
for(a in 0:k)
{
for(b in 0:k)
{
for(c in 0:k)
{
for(d in 0:k)
{
#参数实例化
a0<-(-1)+2*a/k
b0<-(-1)+2*b/k
c0<-(-1)+2*c/k
d0<-(-1)+2*d/k
#计算均方误差
y0<-a0+b0*iris$Sepal.Length+c0*iris$Sepal.Width+
d0*iris$Petal.Length
mse<-mean((iris$Petal.Width-y0)^2)
if(mse<minMSE)
{
minMSE<-mse
f_a0<-a0
f_b0<-b0
f_c0<-c0
f_d0<-d0
}
}
}
}
}
print(minMSE)
## [1] 0.03607967
print(c(f_a0,f_b0,f_c0,f_d0))
## [1] -0.3454545 -0.2000000 0.2363636 0.5272727