重み付きランダムフォレストのRパッケージ?classwtオプション?


16

ランダムフォレストを使用して、極端に不均衡なデータセットの結果を予測しようとしています(マイノリティクラスの割合は約1%以下です)。従来のランダムフォレストアルゴリズムは、少数クラスに特別な注意を払うのではなく、全体的なエラー率を最小化するため、不均衡なデータには直接適用できません。したがって、マイノリティクラスの誤分類に高いコストを割り当てたいと思います(コストに敏感な学習)。

R のオプションclasswtを使用できるソースをいくつか読みましたがrandomForest、これの使用方法がわかりません。そして、機能に代わるものは他にありrandomForestますか?

回答:


29

このスレッドは、他の2つのスレッドと、この問題に関するすばらしい記事を指します。クラスウェイトとダウンサンプリングも同様に良いようです。以下で説明するように、ダウンサンプリングを使用します。

まれなクラスを特徴付けるのは1%だけなので、トレーニングセットは大きくする必要があります。このクラスのサンプルは25〜50未満である可能性があります。クラスを特徴付けるサンプルはほとんどなく、必然的に学習パターンを粗雑にし、再現性を低下させます。

RFは多数決をデフォルトとして使用します。トレーニングセットのクラスの有病率は、何らかの効果的な事前分布として機能します。したがって、まれなクラスが完全に分離可能でない限り、このまれなクラスが予測時に多数決で勝つことはまずありません。多数決で集計する代わりに、投票の端数を集計できます。

層別サンプリングを使用して、まれなクラスの影響を増やすことができます。これは、他のクラスのダウンサンプリングのコストで行われます。分割する必要があるサンプルの数が少なくなると、成長したツリーの深さが浅くなり、学習される潜在的なパターンの複雑さが制限されます。ほとんどの観察結果が複数の木に参加するように、成長する木の数は、たとえば4000でなければなりません。

以下の例では、それぞれ1%、49%、50%の罹患率を持つ3つのクラスを持つ5000サンプルのトレーニングデータセットをシミュレートしました。したがって、クラス0の50個のサンプルがあります。最初の図は、2つの変数x1およびx2の関数としてのトレーニングセットの真のクラスを示しています。 この写真は、学習するシミュレーションパターンを示しています

4つのモデルがトレーニングされました:デフォルトモデル、およびクラスの1:10:10 1:2:2および1:1:1の階層化を持つ3つの階層化モデル。主に、各ツリーのインバッグサンプル(再描画を含む)の数は5000、1050、250、および150になります。多数決を使用しないため、完全にバランスのとれた層別化を行う必要はありません。代わりに、まれなクラスの投票に10倍の重みを付けるか、他の決定規則を使用できます。偽陰性と偽陽性のコストは、このルールに影響するはずです。

次の図は、層別化が投票率にどのように影響するかを示しています。階層化されたクラス比は常に予測の重心であることに注意してください。 階層化と投票

最後に、ROC曲線を使用して、特異性と感度の間の適切なトレードオフを提供する投票ルールを見つけることができます。黒い線は層別化されていません、赤1:5:5、緑1:2:2、青1:1:1。このデータセットでは、1:2:2または1:1:1が最適です。 roc曲線

ちなみに、投票の端数はここですぐにクロス検証されます。

そしてコード:

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つの図のキャプションには、1:2:2ではなく1:5:5と書かれています
Soren Havelund Welling

詳細な回答をありがとうございました。これは私の日々の仕事で私を大いに助けてくれるでしょう。私が理解できない文が1つあります:「メインツリーのインバッグサンプル(再描画を含む)の数は5000、1050、250、および150になります。」
Metariat

1
私の喜び;)この例では、まれなクラスには50人のメンバーがいました。1:10:10を階層化する場合、sampsize = c(50,500,500)を指定する必要があります。50 + 500 + 500 =1050。1050サンプルの完全に成長したツリーには、合計1050x2ノードが含まれます。
ソレンヘイブランドウリング

私の質問がばかである場合は申し訳ありませんが、ここで1:10:10、1:2:2および1:1:1の層別化の意味は何ですか?そして、「珍しいクラスへの投票は10倍になる可能性がある」と言ったとき。コードのどの部分がそれを表しますか?1:10:10ですか?どうもありがとうございました!
Metariat

1
1:10:10はクラス間の比率です。シミュレートされたデータセットは、1:49:50の比率になるように設計されました。これらの比率は、2つの大きなクラスをダウンサンプリングすることで変更されました。たとえば、c(1,10,10)* 50と同じsampsize = c(50,500,500)を選択すると、ツリーのクラス比を変更できます。50は、レアクラスのサンプル数です。さらにkeep.inbag = TRUEを設定してrf $ inbagを調べると、まれなクラスのサンプルが〜2/3ツリーでinbagであるのに対し、ダウンサンプリングのために各非まれなクラスサンプルが非常に少数のツリーに含まれていることがわかります。
ソレンHavelundウェリング
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.