Answers:
该线程引用了另外两个线程,并对此发表了一篇不错的文章。看来类加权和下采样同样好。我按如下所述使用下采样。
请记住,训练集必须很大,因为只有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)