借助caret包实现特征选择的工作

网友投稿 1148 2022-11-09

借助caret包实现特征选择的工作

借助caret包实现特征选择的工作

我们有一期的文章讲述了如何使用caret包进行数据的预处理,其中内容包括哑变量的创建、近零方差变了的筛选、数据标准化、缺失值处理、数据分割等。可以在​​教你使用caret包(一)--数据预处理​​获取更详细的内容介绍。下面我们接着讲讲如何使用caret包实现特征选择的任务。

特征选择的实质就是在已有的变量基础上,选择部分子集,在一定程度上避免维度灾难造成的模型过拟合,从而提升模型的精确度、降低模型的运行时间等。在卢辉的《数据挖掘与数据化运营实战》一书中一直强调一个观点:少而精的变量可以充分发挥模型的效率。

目前关于特征选择的方法主要有两大类,即封装法和过滤法:

封装法,将特征选择过程与训练过程融合在一起,以模型的预测能力作为特征选择的衡量标准。例如在多元线性模型中,我们常常会使用逐步回归的方法进行变量的筛选,这里的逐步回归就是属于封装法的一种。封装法可以选出高质量的变量子集,但运行速度上会大打折扣。

过滤法,与封装法不同的是特征选择过程与训练过程相互独立,通过分析变量内部的关系进行筛选操作,与训练模型的选择并没有关系。例如通过变量间的相关性、近零方差检验、聚类分析等方法选择出来的变量,再用于不同的训练模型构建、评估等。过滤法虽然在速度上比封装法更占优势,但可能会删除非常有实质意义的变量。

我们使用R中的caret包进行特征选择,该包也为我们提供了封装和过滤两种方法进行特征选择,首先来看看相对简单的过滤法,过滤法的实现可以使用caret包中的sbf(select by filter)函数实现,该函数需要与sbfControl函数搭配使用。我们来看看sbfControl和sbf函数的语法和参数含义:

过滤法

sbfControl(functions = NULL, method = "boot", saveDetails = FALSE, number = ifelse(method %in% c("cv", "repeatedcv"), 10, 25), repeats = ifelse(method %in% c("cv", "repeatedcv"), 1, number), verbose = FALSE, returnResamp = "final", p = 0.75, index = NULL, indexOut = NULL, timingSamps = 0, seeds = NA, allowParallel = TRUE, multivariate = FALSE)

sbfControl函数用来设置sbf函数的控制参数,几个重要的参数如下:

functions:用于设置模型拟合、预测和特征选择的一系列函数,可以是lmSBF(线性回归),rfSBF(随机森林),treebagSBF(袋装决策树),ldaSBF(线性判别分析法),nbSBF(朴素贝叶斯)和caretSBF(自定义函数)。

method:指定抽样方法,可以是boot(BootStrap抽样),cv(交叉验证抽样),LOOCV(留一交叉验证法)和LGOCV(留组交叉验证法)。

saveDetails:是否保存特征选择过程中的预测值和变量重要性,默认为FALSE。

number:指定折数或者重抽样迭代次数,当method为cv或repeatedcv时,则默认从总体中抽取10份样本并迭代10次,否则抽取25份并迭代25次。

repeats:指定抽样组数,默认抽取一组样本。

verbose:是否返回每次重抽样的详细信息,默认为FALSE。

returnResamp:返回重抽样的汇总信息。

p:如果指定method为LGOCV时,该参数起作用,指定训练集的比重。

seeds:为抽样设置随机种子。

allowParallel:在并行后台已加载和允许的情况下,是否允许并行运算。

sbf(x, y, sbfControl = sbfControl(), ...)

x:指定输入变量。

y:指定输出变量。

sbfControl:指定sbf函数的控制参数。

过滤法的案例实战

我们使用C50包中的用户流失数据作为案例,通过过滤法进行特征选择:

#加载所需的R包

if(!suppressWarnings(require(C50))){install.packages('C50')require(C50)}if(!suppressWarnings(require(caret))){install.packages('caret')require(caret)}

#加载C50包中的数据集

data(churn)

#构建sbf函数的控制参数(使用朴素贝叶斯函数和BootStrap抽样方法)

sbfControls_nb <- sbfControl(

functions = nbSBF,

method = 'boot')

#使用sbf函数进行特征选择

fs_nb <- sbf(x = churnTrain[,-20],

y = churnTrain[,20],

)

基于随机森林函数和BootStrap抽样方法,从19个自变量中筛选出11个优秀的变量.

其中的11个变量为:

#构建sbf函数的控制参数(使用随机森林函数和10重交叉验证抽样方法,并抽取5组样本)

sbfControls_rf <- sbfControl(

functions = rfSBF,

method = 'cv',

repeats = 5)

#使用sbf函数进行特征选择

fs_rf <- sbf(x = churnTrain[,-20],

y = churnTrain[,20],

)

基于随机森林函数和10重交叉验证的抽样方法,从19个自变量中筛选出11个优秀的变量.

选出的变量是:

封装法

caret包中提供的封装法主要有3种,即递归特征删减法、遗传算法和蚁群算法。三种方法实现的函数分别是rfe(),gafs()和safs()。同样,我们来看看这三个函数的语法特征和参数含义:

rfeControl(functions = NULL, rerank = FALSE, method = "boot", saveDetails = FALSE, number = ifelse(method %in% c("cv", "repeatedcv"), 10, 25), repeats = ifelse(method %in% c("cv", "repeatedcv"), 1, number), verbose = FALSE, returnResamp = "final", p = .75, index = NULL, indexOut = NULL, timingSamps = 0, seeds = NA, allowParallel = TRUE)

rerank:布尔类型参数,在每次特征删除的过程中是否重新计算特征的重要性,默认为False。

其他参数与sbfControl函数的参数一致,这里不再赘述。

rfe(x, y, sizes = 2^(2:4), metric = ifelse(is.factor(y), "Accuracy", "RMSE"), maximize = ifelse(metric == "RMSE", FALSE, TRUE), rfeControl = rfeControl(), ...)

x:指定输入变量。

y:指定输出变量。

sizes:通过一个整数向量,指定需要保留的特征数量。

metric:指定衡量最优模型的判断指标,默认使用RMSE(均方根误差)和Rsquared(判决系数)衡量回归模型,使用Accuracy(精确度)和Kappa系数衡量分类模型。

maximize:布尔类型参数,如果metric为RMSE,则不要求metric最小化,否则要求Kappa系数、判决系数最大化和精确度达到最大化。

rfeControl:指定rfe函数的控制参数。

递归特征删减法的案例实战

我们仍然使用C50包中的用户流失数据作为案例,用来比较过滤法和封装法。

#构建rfe函数的控制参数(使用随机森林函数和BootStrap抽样方法)

rfeControls_nb <- rfeControl(

functions = nbFuncs,

method = 'boot')

#使用rfe函数进行特征选择

fs_nb <- rfe(x = churnTrain[,-20],

y = churnTrain[,20],

sizes = seq(4,19,2),

)

从返回的结果可知,可以选择的最优变量个数为11或12个,同样通过图形也能够看出来。似乎跟过滤法没有太大的差异,而且运行时间非常长!

plot(fs_nb, type = c('g','o'))

#构建rfe函数的控制参数(使用随机森林函数和10重交叉验证抽样方法,并抽取5组样本)

rfeControls_rf <- rfeControl(

functions = rfFuncs,

method = 'cv',

repeats = 5)

#使用rfe函数进行特征选择

fs_nb <- rfe(x = churnTrain[,-20],

y = churnTrain[,20],

)

使用随机森林函数,当选择10个变量时,精确度就超过95%了,而过滤法选择11个变量时,精确度还不足93%,故在93%的精确度下,完全可以使用随机森林函数,而且只需要8个变量就可以达到功效,速度还是非常快的!。

如下是变量选择的可视化结果:

plot(fs_rf, type = c('g','o'))

通过比较发现,随机森林函数在特征选择时还是非常优秀的,既能保证精确度的提升,又能够快速的返回运行结果。

本期的内容就到这里,基于遗传算法和蚁群算法的特征选择将在后期补上,这里面的理论内容消化起来非常费力,请各位朋友谅解。同时也欢迎热爱数据分析与挖掘的朋友们多多分享与交流!

每天进步一点点2015

学习与分享,取长补短,关注小号!

长按识别二维码 马上关注

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:概率 · dp练习 (16.04.16)
下一篇:从零开始学Python【17】--matplotlib(面积图)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~