加权随机森林的R包?classwt选项?


16

我正在尝试使用随机森林来预测极端不平衡的数据集的结果(少数族裔比率仅为1%甚至更低)。因为传统的随机森林算法将总错误率降到最低,而不是特别注意少数类,所以它不能直接应用于不平衡数据。因此,我想为少数群体的错误分类分配高昂的成本(成本敏感型学习)。

我阅读了一些可以在R中使用选项classwt的资料randomForest,但我不知道如何使用它。我们还有其他替代randomForest功能吗?

Answers:


29

线程引用了另外两个线程,并对此发表了一篇不错的文章。看来类加权和下采样同样好。我按如下所述使用下采样。

请记住,训练集必须很大,因为只有1%的人会代表稀有课程。少于25〜50个此类的样本可能会有问题。很少有表征该类的样本将不可避免地使所学模式变得粗糙且难以再现。

RF默认使用多数投票。训练集的班级流行率将作为某种有效的先验进行操作。因此,除非稀有阶级是完全可分离的,否则在预测时这种稀少阶级不可能赢得多数表决。您可以汇总投票分数,而不是通过多数投票进行汇总。

分层抽样可用于增加稀有类别的影响。这是通过降低其他类的采样成本来完成的。种植的树木将变得不那么深,因为需要分割的样本更少,因此限制了所获潜在模式的复杂性。生长的树木数量应该很大,例如4000棵,这样大多数观察结果都可以参与到几棵树木中。

在下面的示例中,我模拟了一个训练数据集,该训练数据集包含3个类别的5000个样本,其患病率分别为1%,49%和50%。因此,将有50个类别为0的样本。第一个图显示了训练集的真实类别,它是两个变量x1和x2的函数。 此图显示了要学习的模拟模式

训练了四个模型:默认模型,以及三个分层模型,这些分层模型具有1:10:10 1:2:2和1:1:1的类别分层。Main时每棵树中的袋装样本数量(包括重绘)将分别为5000、1050、250和150。由于我不使用多数投票,因此不需要进行完美平衡的分层。取而代之的是,对稀有类的投票可以加权10倍或其他某种决策规则。您误报和误报的费用应会影响此规则。

下图显示了分层如何影响投票分数。请注意,分层类别比率始终是预测的重心。 分层投票

最后,您可以使用ROC曲线来找到一个投票规则,从而在特异性和敏感性之间取得良好的平衡。黑色线无分层,红色1:5:5,绿色1:2:2和蓝色1:1:1。对于此数据集,最好选择1:2:2或1:1:1。 罗克曲线

顺便说一下,投票分数在这里可以进行交叉验证。

和代码:

library(plotrix)
library(randomForest)
library(AUC)

make.data = function(obs=5000,vars=6,noise.factor = .2,smallGroupFraction=.01) {
X = data.frame(replicate(vars,rnorm(obs)))
yValue = with(X,sin(X1*pi)+sin(X2*pi*2)+rnorm(obs)*noise.factor)
yQuantile = quantile(yValue,c(smallGroupFraction,.5))
yClass = apply(sapply(yQuantile,function(x) x<yValue),1,sum)
yClass = factor(yClass)
print(table(yClass)) #five classes, first class has 1% prevalence only
Data=data.frame(X=X,y=yClass)
}

plot.separation = function(rf,...) {
triax.plot(rf$votes,...,col.symbols = c("#FF0000FF",
                                       "#00FF0010",
                                       "#0000FF10")[as.numeric(rf$y)])
}

#make data set where class "0"(red circles) are rare observations
#Class 0 is somewhat separateble from class "1" and fully separateble from class "2"
Data = make.data()
par(mfrow=c(1,1))
plot(Data[,1:2],main="separation problem: identify rare red circles",
     col = c("#FF0000FF","#00FF0020","#0000FF20")[as.numeric(Data$y)])

#train default RF and with 10x 30x and 100x upsumpling by stratification
rf1 = randomForest(y~.,Data,ntree=500, sampsize=5000)
rf2 = randomForest(y~.,Data,ntree=4000,sampsize=c(50,500,500),strata=Data$y)
rf3 = randomForest(y~.,Data,ntree=4000,sampsize=c(50,100,100),strata=Data$y)
rf4 = randomForest(y~.,Data,ntree=4000,sampsize=c(50,50,50)  ,strata=Data$y)

#plot out-of-bag pluralistic predictions(vote fractions).
par(mfrow=c(2,2),mar=c(4,4,3,3))
plot.separation(rf1,main="no stratification")
plot.separation(rf2,main="1:10:10")
plot.separation(rf3,main="1:5:5")
plot.separation(rf4,main="1:1:1")

par(mfrow=c(1,1))
plot(roc(rf1$votes[,1],factor(1 * (rf1$y==0))),main="ROC curves for four models predicting class 0")
plot(roc(rf2$votes[,1],factor(1 * (rf1$y==0))),col=2,add=T)
plot(roc(rf3$votes[,1],factor(1 * (rf1$y==0))),col=3,add=T)
plot(roc(rf4$votes[,1],factor(1 * (rf1$y==0))),col=4,add=T)

一位标题说明说的是1:5:5而不是1:2:2
Soren Havelund Welling 2015年

非常感谢您提供详细的答案,这肯定会对我的日常工作有所帮助。我不明白一句话:“主要是每棵树上的袋装样品数量(包括重绘)分别为5000,1050、250和150”。请您解释一下这些数字是从哪里来的?
Metariat

1
我很高兴;)在这个例子中,罕见的班级有50名成员。如果按1:10:10分层,则需要指定sampsize = c(50,500,500)。50 + 500 + 500 =1050。一棵包含1050个样本的完全生长的树将总共具有1050x2节点。
Soren Havelund Welling

抱歉,如果我的问题是白痴,那么1:10:10、1:2:2和1:1:1分层在这里是什么意思?当您说“稀有阶层的选票可以加权10倍”时。代码的哪一部分代表了这一点?是1:10:10吗?非常感谢你!
Metariat 2015年

1
班级之间的比例是1:10:10。模拟数据集被设计为具有1:49:50的比率。通过向下采样两个较大的类来更改这些比率。通过选择例如sampsize = c(50,500,500)与c(1,10,10)* 50相同,可以更改树中的类比率。50是稀有类别的样本数。如果进一步设置keep.inbag = TRUE并检查rf $ inbag,您将看到稀有类别的样本在大约2/3棵树中是袋装的,而由于降采样,每个非稀有类别的样本都包含在极少数的树中。
Soren Havelund Welling
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.