R语言(四)——十折交叉验证/机器学习回归【决策树(随机森林)、组合方法、SVR】

六月ゝ 毕业季﹏ 提交于 2020-01-17 14:56:22

目录

一、数据

二、十折交叉验证

1.思想

         2.实现

三、决策树

1.单树

2.Boosting回归

3.bagging回归

3.随机森林回归


一、数据

可以直接使用我上传的数据(经过处理,直接导入使用)

从网页https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/regression/mg获取mg数据,该数据有1个因变量和6个自变量。

将数据复制进excel,选中第一列,数据->分列->分隔符号->空格,将数据进行分列。

将数据中的x:删去(可以使用替换功能)

最后在第一行加入变量名,另存为csv文件,即可以在R中正常载入。

二、十折交叉验证

1.思想

十折交叉验证的方法用于判断实验结果的可靠性。

其基本实现方法是:将所有数据划分为十份,依次选取一份数据作为测试集,其余九份做训练集,共建立十个模型,可分别得到10个标准化的均方误差(NMSE),求出10次平均的NMSE。

对于训练集来说,其NMSE=1-R²,对于测试机来说,NMSE与回归得到的R²没有太大关系。交叉验证主要关心的是测试集的NMSE。

2.实现

rm(list=ls())
#setwd("")  #设置路径

#随机选择Z折下标集的函数,n样本量,seed随机种子
CV=function(n,Z=10,seed=888){
  z=rep(1:Z,ceiling(n/Z))[1:n]
  set.seed(seed)
  z=sample(z,n)
  mm=list()
  #mm[[i]]为第i个下标集
  for (i in 1:Z) mm[[i]]=(1:n)[z==i];return(mm)
}

#数据导入
w=read.csv("mg.csv")
n=nrow(w);Z=10;mm=CV(n,Z);D=1

MSE=rep(0,Z) #建立一个向量储存结果
for(i in 1:Z){   #循环十次
  m=mm[[i]];
  M=mean((w[m,D]-mean(w[m,D]))^2)
  a=lm(y~.,w[-m,]) #简单线性回归,[-m]为训练集下标集合
  MSE[i]=mean((w[m,D]-predict(a,w[m,]))^2)/M  #求测试集NMSE
}
mean(MSE)

预测效果大约在0.41左右。也可以对数据集进行更多的划分,改变Z值

三、决策树

1.单树

如果没有安装rpart,需要先进行install

#install.packages("rpart")
library(rpart.plot)
w=read.csv("mg.csv")
a=rpart(y~.,w)
rpart.plot(a,type=2)

决策树调用rpart实现,通过rpart.plot绘制树图

 

进行交叉验证只需要将之前的

a=lm(y~.,w[-m,])

修改为

a=rpart(y~.,w[-m,])

之后的交叉验证同理,只需改变相应回归的函数代码。得到NMSE0.3624

2.Boosting回归

boosting方法是一种组合方法,把弱学习器组合起来进行投票,每次使用的是全部的样本,每轮训练改变样本的权重。依据少数服从多数原则作出决策。

产生多学习器可以靠抽样法,如自助法(bootstrap)抽样,在数据中反复放回地抽取样本量大小相同的样本,boosting方法在再次抽样时还会自动调整。比如,在前一次抽样时,某些样本点在产生弱学习器的决策时会有较大误差,可能是由于它们在样本中缺乏代表性所致,于是第二次抽样时就会增加其被抽中的概率以改进结果,也可以不等权重投票,而是根据其错误率或误差大小来加权(或加权平均),因此存在许多不同的boosting方法。

通过对弱分类器(单一决策树)的“逐步优化”,使之成为强分类器。假定当前在训练集中存在n个点,对其权重分别赋值Wj(0<= j < n),在迭代的学习过程中(假定迭代次数为m),我们将根据每次迭代的分类结果,不断调整这些点的权重,如果当前这些点分类是正确的,则调低其权值,否则,增加样例点的权值。这样,当整个迭代过程结束时,算法将得到m个合适的模型,最终,通过对每棵决策树加权平均得到最后的预测结果,权值b由每棵决策树的分类质量决定

处理mg数据时,使用程序包mboost

library(mboost)
MSE=rep(0,Z)
set.seed(1010)
for(i in 1:Z){
  m=mm[[i]];
  M=mean((w[m,D]-mean(w[m,D]))^2)
  a=mboost(y~btree(x1)+btree(x2)+btree(x3)+btree(x4)+btree(x5)
           +btree(x6),data=w[-m,])
  MSE[i]=mean((w[m,D]-predict(a,w[m,]))^2)/M
}
mean(MSE)

得到NMSE0.3407,较之前结果好一点

3.bagging回归

是比boosting简单的组合方法,在bagging中,就是不断地对训练样本进行再抽样,每次抽取样本大小相同。对每个自助法样本,都建立一棵回归树,每棵树给出一个预测值,最终预测值为这些值的简单平均

  bagging boosting
样本选择 放回抽样 全量选取
样本权重 权重相等 错误率大的样本权重越大
弱学习器权重 权重相等 准确率大的分类器权重越大
并行计算 可以并行 不能并行,各个分类器按顺序生成,后一个模型参数要依赖前面的模型结果

https://www.cnblogs.com/earendil/p/8872001.html

#bagging回归
library(ipred)
MSE=rep(0,Z)
set.seed(1010)
for(i in 1:Z){
  m=mm[[i]];
  M=mean((w[m,D]-mean(w[m,D]))^2)
  a=bagging(y~.,data=w[-m,])
  MSE[i]=mean((w[m,D]-predict(a,w[m,]))^2)/M
}
mean(MSE)

得到测试集的NMSE为0.3164,比boosting有改进

3.随机森林回归

随机森林是另一种组合方法,由随机放回地再抽样的样本形成的决策树组成的,其特点是这些决策树每一节点的分割变量不是由所有的自变量竞争产生的,而是由随机选取的少数变量产生。因此不仅产生每棵决策树的样本是随机的,每棵树的每个节点的产生也是随机的。但产生的数目很多,因此称为随机森林,结果的投票(或平均)是等权的。

R语言中使用randomForest程序包

#随机森林
library(randomForest)
MSE=rep(0,Z)
set.seed(1010)
for(i in 1:Z){
  m=mm[[i]];
  M=mean((w[m,D]-mean(w[m,D]))^2)
  a=randomForest(y~.,data=w[-m,])
  MSE[i]=mean((w[m,D]-predict(a,w[m,]))^2)/M
}
mean(MSE)

得到测试集的NMSE为0.2789,较之前的方法有所改进。其中,对于不同的随机种子,运行得到的随机森林的结果也不同,且其不会有过拟合的现象,还可以输出自变量重要性的度量

SS=randomForest(y~.,data=w,importance=TRUE,proximity=TRUE)
SS$importance

四、支持向量机回归(SVR) 

1.SVM

2.SVR

                                                        

3.实现

在R语言中有多个包可以实现SVM,比如rminer、e1071和kernlab,由于代码完全一样,只需要改变调用函数,因此用注释语句对应。

#支持向量机回归
library(rminer)
#library(e1071)
#library(kernlab)
MSE=rep(0,Z)
set.seed(1010)
for(i in 1:Z){
  m=mm[[i]];
  M=mean((w[m,D]-mean(w[m,D]))^2)
  a=fit(y~.,w[-m,],model="svm")
  #a=svm(y~.,w[-m,])
  #a=ksvm(y~.,w[-m,],model="svm)
  MSE[i]=mean((w[m,D]-predict(a,w[m,]))^2)/M
}
mean(MSE)

误差都在0.29左右。

五、总结

就这个数据而言,随机森林具有最好的表现,最差的是传统的线性模型,但由于在方法调用过程中并没有进行参数调整比较,用的都为默认值,因此许多模型都存在较大的改进空间。同时,每次数据的选取也具有偶然性。

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!