勾配ブースティングマシンの精度は、反復回数が増えると低下します


15

caretR のパッケージを介して勾配ブースティングマシンアルゴリズムを試しています。

小さな大学入学データセットを使用して、次のコードを実行しました。

library(caret)

### Load admissions dataset. ###
mydata <- read.csv("http://www.ats.ucla.edu/stat/data/binary.csv")

### Create yes/no levels for admission. ### 
mydata$admit_factor[mydata$admit==0] <- "no"
mydata$admit_factor[mydata$admit==1] <- "yes"             

### Gradient boosting machine algorithm. ###
set.seed(123)
fitControl <- trainControl(method = 'cv', number = 5, summaryFunction=defaultSummary)
grid <- expand.grid(n.trees = seq(5000,1000000,5000), interaction.depth = 2, shrinkage = .001, n.minobsinnode = 20)
fit.gbm <- train(as.factor(admit_factor) ~ . - admit, data=mydata, method = 'gbm', trControl=fitControl, tuneGrid=grid, metric='Accuracy')
plot(fit.gbm)

そして、驚いたことに、モデルの相互検証の精度は、ブースティング反復の数が増えるにつれて増加するのではなく減少し、約450,000反復で約.59の最小精度に達することに気付きました。

ここに画像の説明を入力してください

GBMアルゴリズムを誤って実装しましたか?

編集:Underminerの提案に従って、上記のcaretコードを再実行しましたが、100〜5,000 回のブースティング反復の実行に焦点を当てました。

set.seed(123)
fitControl <- trainControl(method = 'cv', number = 5, summaryFunction=defaultSummary)
grid <- expand.grid(n.trees = seq(100,5000,100), interaction.depth = 2, shrinkage = .001, n.minobsinnode = 20)
fit.gbm <- train(as.factor(admit_factor) ~ . - admit, data=mydata, method = 'gbm', trControl=fitControl, tuneGrid=grid, metric='Accuracy')
plot(fit.gbm)

結果のプロットは、精度が実際に〜1,800回の反復でほぼ.705でピークに達することを示しています。

ここに画像の説明を入力してください

興味深いのは、精度が〜.70で横ばいにならず、代わりに5,000回の反復で低下したことです。

回答:


14

一般に、ブーストエラーは、特にデータにノイズが多い場合(ラベルの間違ったケースなど)、反復回数とともに増加する可能性があります。これはあなたの問題かもしれませんが、私はあなたのデータについてもっと知ることなく言うことはできません

基本的に、ブースティングは、誤った情報を含むケースを正しく予測することに「焦点を合わせる」ことができ、その過程で、より実質的な他のケースの平均パフォーマンスを低下させます。

このリンク(Boosting and Noise)は、問題について説明できるよりも良い説明を示しています。

LongとServedioによるこの論文(Random Classification Noise)は、この問題の技術的な詳細を提供します。


16

表示されているのは、オーバーフィッティングの典型的な例です。わずかなエラーの増加は、相互検証されたデータセットの検証部分のパフォーマンスの低下によるものです。より多くの反復により、ほぼ常にトレーニングセットのエラーが改善されるはずですが、検証/テストセットの場合は逆です。


では、ブースティングの反復回数に基づく勾配ブースティングのオーバーフィット?面白い。代わりに、最適な反復回数に達した後、精度は横ばいになると思いました。
ロバートF

4
そのとおりです。勾配ブースティングでは、後続の各ツリーは前のツリーの残差から構築されるため、GBMは、検証/テストセットに一般化できる場合でも、トレーニングデータセットの残りのエラーを削減しようとし続けます。これが、クロス検証を実行する理由です。フィッティングアルゴリズムはいつ停止するかをネイティブに認識しないためです
ライアンゾッティ

1
Gradient BoostingはAdaBoostに触発されています。AdaBoostがオーバーフィットすることはめったにありません。オーバーフィットした場合、ほんのわずかであり、何度も何度も繰り返します。@Underminerの説明は、特にこのコメントに参照が含まれていないことを考えると、このコメントよりも起こっていることを代表する可能性が高いと思います。
リカルドクルーズ

2
@RicardoCruz勾配ブースティングのオーバーフィットがめったに見られないのは面白いと思います。私がそれを使ってきた4年ほどで、私は反対のことを見ました-あまりにも多くの木が過剰適合につながります。かつて同僚に似たものを証明する必要があり、トレーニングセットのエラーをほぼゼロに減らすことができましたが、検証エラーはオーバーフィットGBMのエラーよりも大幅に増加しました。私はまだ、勾配ブースティングは素晴らしいアルゴリズムだと思います。これは通常、最初のアルゴリズムIの使用です-あなたはちょうどあなたがクロスバリデーションを経由して追跡することができますあまりにも多くの木、気をつけなければならない
ライアンZotti

2
@RyanZotti私はその時訂正します。私はその美しい強力な理論的基盤を楽しんでいるので、シャピレらからのAdaBoostに関する多くの論文を読みました。著者は、ブースティングは過剰適合の傾向があると主張しますが、それは非常に困難です。私はそれを使用した経験があまりなく、これについて議論するための確固たる理論的基盤がなく、そしてもちろん著者は著者であり、彼らは自然に彼らの発明に熱心です。 、私は訂正します。
リカルドクルーズ

4

グリッド検索なしで同様の結果を再現するコード、

mod = gbm(admit ~ .,
      data = mydata[,-5],
      n.trees=100000,
      shrinkage=0.001,
      interaction.depth=2,
      n.minobsinnode=10,
      cv.folds=5,
      verbose=TRUE,
      n.cores=2)

best.iter <- gbm.perf(mod, method="OOB", plot.it=TRUE, oobag.curve=TRUE, overlay=TRUE)
print(best.iter)
[1] 1487
pred = as.integer(predict(mod, newdata=mydata[,-5], n.trees=best.iter) > 0)
y = mydata[,1]
sum(pred == y)/length(y)
[1] 0.7225

3

gbmパッケージには、最適な反復回数(=木の数、または基底関数の数)を推定する機能があります。

gbm.perf(mod, method="OOB", plot.it=TRUE, oobag=TRUE, overlay=TRUE)

そのためにキャレットの訓練は必要ありません。


それが私が抱えている問題を解決するかどうかはわかりません-精度が0.70(プロットの最初のデータポイント)に近い最高の場合、最適な反復回数は5,000であるようです。しかし、それは間違っているようです。反復回数が多いほど、精度は低くなりますが、低くなりますか?
ロバートF

1
@RobertF最初に、認めることを要素に変える必要はないと思います。同様に機能します:mod = gbm(admit〜。、data = mydata [、-5]、n.trees = 100000、shrink = 0.001、interact.depth = 2、n.minobsinnode = 10、cv.folds = 5 、verbose = TRUE、n.cores = 2)。gbmが最適なiterを選択する場所は、best.iter <-gbm.perf(mod、method = "OOB"、plot.it = TRUE、oobag.curve = TRUE、overlay = TRUE)で確認できます。つまり、偏差の変化が負になったとき(これから生成されたプロットを参照)。
horaceT

1
@RobertFもう1つ。gbm呼び出しでn.trees =(100万)を指定すると、1から1,000,000までのすべての反復回数を実行できます。そのため、キャレットを使用する必要はありません。
horaceT

1
@RobertFさらにフォローアップ。私は10万本の木/反復を実行しました。gbm.perfで最適な反復を選択することで得られた精度は0.7225で、これは完全な反復グリッドを実行しているものにかなり近いものです。
-horaceT
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.