在R中,如何对不平衡的2类数据进行特征选择的平衡10倍CV信息增益测试



我有一个大的训练数据集data.trn,在50多个变量上有260000多个观测值,因变量loan_status由两个类别"paid off""default"组成,各自的不平衡度约为5:1。我想使用FSelector包中的information.gain命令来将功能减少到最有意义的程度。然而,我担心这种保留的过滤方法会偏向于大多数类别,导致对特征的误导性评估。为了避免这种情况,我认为一种基于sapply的程序可以通过提取10个不同平衡交叉验证折叠上的几个信息增益测试的平均值来缓解这个问题。我想象折叠可以通过每次获取所有少数阶级的观察结果,并与来自多数阶级的不同等量的观察结果配对来构建。然而,问题是,我是R的初学者,所以我不太擅长自己创建这样的结构,所以我想这里的人可以向我展示如何做到这一点,因为我仍然无法理解这项任务。到目前为止,我只做了基本信息增益测试,不知道如何制作所需的平衡CV版本:

info_gain <- FSelector::information.gain(loan_status ~ ., data.trn)

我会推荐这两种策略之一:

  1. 对多数类的子集进行采样,直到一个与较小类更一致的数字。重复多次,每次都记录重要功能。然后看看是否有在所有集合中始终处于最重要的特征中的特征。

  2. 对较小的类重新采样以获得合成膨胀的样本数。从本质上估计它们的协方差,从中抽取随机样本,在此数据上拟合模型(并在估计性能之前去除样本(。因此,从某种意义上说,你只是借用合成数据来稳定模型拟合过程。

第一个可能不那么复杂。

以下是方法1的简单演示:


## Using the `mpg` dataset, pretending the 'dri' column is of particular interest to us.
##
## 'drv' is a column with three levels, that are not very balanced:
##
## table( mpg$drv )
##   4   f   r
## 103 106  25
## Let's sub-sample 25 of each class, it makes sense from the table above
n.per.class  <- 25
## let's do the sampling 10 times
n.times <- 10
library(foreach) ## for parallell work
library(doMC)
registerDoMC()
unique.classes <- unique( mpg$drv ) ## or just use levels( mpg$drv ) if you have a factor
variable.importances <- foreach( i=1:n.times ) %dopar% {
j <- sapply(
unique.classes,
function(cl.name) {
sample( which( mpg$drv == cl.name ), size=n.per.class )
},
simplify=FALSE
)
## 'j' is now a named list, we easily turn it to a vector with unlist:
sub.data <- mpg[ unlist(j), ]
## table( sub.data$drv )
##  4  f  r
## 25 25 25
##
## 25 of each!

fit <- train.your.model()
varimp <- variable.importance( fit )
## I don't know what varimp will look like in your case, is it a numeric vector perhaps?
}
## variable.importances now is a list with the result of each
## iteration. If it is a vector wiht number for example, the following
## could be useful to have those collected into a matrix:
matrix.of.variable.importances <- Reduce( rbind, variable.importances )
colnames( matrix.of.variable.importances ) <- colnames( your.data )

如果你对方法2感兴趣,我建议你研究一下caret包,它很容易做到这一点,尽管我不知道他们是否支持你的特定方法。

相关内容

  • 没有找到相关文章

最新更新