R:gbmとRandomForestの部分依存プロットには何が見えますか?


14

実際、部分依存プロットで何を表示できるか理解できたと思っていましたが、非常に単純な仮説例を使用すると、かなり困惑しました。コードの次のチャンクに私は、3つの独立変数(生成、BC)と1つの従属変数(Y付き)Cと密接な直線関係を示すYをしながら、そしてbは無相関であるY。Rパッケージを使用して、ブーストされた回帰ツリーで回帰分析を行います。gbm

a <- runif(100, 1, 100)
b <- runif(100, 1, 100)
c <- 1:100 + rnorm(100, mean = 0, sd = 5)
y <- 1:100 + rnorm(100, mean = 0, sd = 5)
par(mfrow = c(2,2))
plot(y ~ a); plot(y ~ b); plot(y ~ c)
Data <- data.frame(matrix(c(y, a, b, c), ncol = 4))
names(Data) <- c("y", "a", "b", "c")
library(gbm)
gbm.gaus <- gbm(y ~ a + b + c, data = Data, distribution = "gaussian")
par(mfrow = c(2,2))
plot(gbm.gaus, i.var = 1)
plot(gbm.gaus, i.var = 2)
plot(gbm.gaus, i.var = 3)

驚くことではありませんが、変数abについて、部分依存プロットはaの平均の周りに水平線を生成ます。私が困惑させているのは、変数cのプロットです。範囲c <40およびc > 60の水平線が表示され、y軸はyの平均に近い値に制限されます。以来、及びbはとは全く無関係であり、Y(従ってそこモデルにおける変数の重要度が0である)、私は期待Cをその値の非常に制限された範囲に対して、そのシグモイド形状の代わりにその範囲全体に沿って部分的な依存性を示します。Friedman(2001)「Greedy関数近似:勾配ブースティングマシン」およびHastie et al。(2011)「統計的学習の要素」。しかし、私の数学スキルは、その中のすべての方程式と式を理解するには低すぎます。したがって、私の質問:変数cの部分依存プロットの形状を決定するものは何ですか?(非数学者が理解できる言葉で説明してください!)

2014年4月17日に追加:

応答を待っている間、R-packageを使用した分析に同じサンプルデータを使用しましたrandomForest。randomForestの部分依存プロットは、gbmプロットから予想したものにはるかに似ています。説明変数abの部分依存はランダムに50前後で変化しますが、説明変数cは、その範囲全体(およびほぼyの全範囲)。gbmおよびの部分依存プロットのこれらの異なる形状の理由は何randomForestでしょうか?

gbmとrandomForestの部分プロット

ここで、プロットを比較する修正されたコード:

a <- runif(100, 1, 100)
b <- runif(100, 1, 100)
c <- 1:100 + rnorm(100, mean = 0, sd = 5)
y <- 1:100 + rnorm(100, mean = 0, sd = 5)
par(mfrow = c(2,2))
plot(y ~ a); plot(y ~ b); plot(y ~ c)
Data <- data.frame(matrix(c(y, a, b, c), ncol = 4))
names(Data) <- c("y", "a", "b", "c")

library(gbm)
gbm.gaus <- gbm(y ~ a + b + c, data = Data, distribution = "gaussian")

library(randomForest)
rf.model <- randomForest(y ~ a + b + c, data = Data)

x11(height = 8, width = 5)
par(mfrow = c(3,2))
par(oma = c(1,1,4,1))
plot(gbm.gaus, i.var = 1)
partialPlot(rf.model, Data[,2:4], x.var = "a")
plot(gbm.gaus, i.var = 2)
partialPlot(rf.model, Data[,2:4], x.var = "b")
plot(gbm.gaus, i.var = 3)
partialPlot(rf.model, Data[,2:4], x.var = "c")
title(main = "Boosted regression tree", outer = TRUE, adj = 0.15)
title(main = "Random forest", outer = TRUE, adj = 0.85)

1
実際に、ハイパーパラメーターを少し調整することをお勧めします。デフォルトのツリー数がgbmにあるかどうかはわかりませんが、非常に小さいため、健全な曲率を学習する時間がありません。
シアパークス14

@Shea Parkes-そのとおりです。ツリーのデフォルト数は100です。これは、適切なモデルを生成するのに十分ではありませんでした。2000本の木では、gbmとランダムフォレストの部分依存プロットはほとんど同じです。
user7417

回答:


7

R randomForestライブラリに既にバンドルされていることに気付く前に、自分で「partial.function-plotter」を書くのに少し時間を費やしました。

[編集...しかし、CRANパッケージforestFloorを作成するのに1年を費やしました。これは、私の意見では、古典的な部分依存プロットよりもはるかに優れています]

ここで示すこのシミュレーションの例では、説明変数が他の変数と相互作用しないため、Partial.functionプロットはインスタンスに最適です。各説明変数が何らかの未知の関数によってターゲットYに相加的に寄与する場合、この方法は推定された隠れ関数を示すのに最適です。部分関数の境界でこのような平坦化がよく見られます。

いくつかの理由:randomForsestには 'nodesize = 5'という引数があります。これは、ツリーが5メンバー以下のグループを分割しないことを意味します。したがって、各ツリーはさらに正確に区別できません。個々のツリーの多くのステップ関数に投票することにより、アンサンブルのバギング/ブートストラップ層がスムーズになります-ただし、データ領域の中央でのみです。空間を表すデータの境界に近づくと、partial.functionの「振幅」が低下します。nodesize = 3を設定する、および/またはノイズと比較してより多くの観測値を取得すると、この境界平坦化効果を減らすことができます。したがって、予測は絶対的に正確な用語ではなく、ターゲットと線形相関しているだけです。aとbの値は、非常に低いS / N比の例として見ることができます。したがって、これらの部分関数は非常にフラットです。これはランダムフォレストの優れた機能であり、トレーニングセットの予測範囲から既にモデルのパフォーマンスを推測できます。OOB.predictionsも素晴らしいです。

データのない地域での部分プロットの平坦化は合理的です。ランダムフォレストとCARTはデータドリブンモデリングであるため、私はこれらのモデルが外挿しないという概念が個人的に好きです。したがって、c = 500またはc = 1100の予測は、c = 100とまったく同じであり、ほとんどの場合、c = 98でもあります。

以下は、境界の平坦化が削減されたコード例です。

gbmパッケージを試していない...

ここにあなたのサンプルに基づいたいくつかの例示的なコードがあります...

#more observations are created...
a <- runif(5000, 1, 100)
b <- runif(5000, 1, 100)
c <- (1:5000)/50 + rnorm(100, mean = 0, sd = 0.1)
y <- (1:5000)/50 + rnorm(100, mean = 0, sd = 0.1)
par(mfrow = c(1,3))
plot(y ~ a); plot(y ~ b); plot(y ~ c)
Data <- data.frame(matrix(c(y, a, b, c), ncol = 4))
names(Data) <- c("y", "a", "b", "c")
library(randomForest)
#smaller nodesize "not as important" when there number of observartion is increased
#more tress can smooth flattening so boundery regions have best possible signal to             noise, data specific how many needed

plot.partial = function() {
partialPlot(rf.model, Data[,2:4], x.var = "a",xlim=c(1,100),ylim=c(1,100))
partialPlot(rf.model, Data[,2:4], x.var = "b",xlim=c(1,100),ylim=c(1,100))
partialPlot(rf.model, Data[,2:4], x.var = "c",xlim=c(1,100),ylim=c(1,100))
}

#worst case! : with 100 samples from Data and nodesize=30
rf.model <- randomForest(y ~ a + b + c, data = Data[sample(5000,100),],nodesize=30)
plot.partial()

#reasonble settings for least partial flattening by few observations: 100 samples and nodesize=3 and ntrees=2000
#more tress can smooth flattening so boundery regions have best possiblefidelity
rf.model <- randomForest(y ~ a + b + c, data = Data[sample(5000,100),],nodesize=5,ntress=2000)
plot.partial()

#more observations is great!
rf.model <- randomForest(y ~ a + b + c,
 data = Data[sample(5000,5000),],
 nodesize=5,ntress=2000)
plot.partial()

4

上記のコメントで述べたように、gbmモデルはパラメーターを調整することで改善されます。モデルの問題とそのようなパラメーターの必要性を見つける簡単な方法は、いくつかの診断プロットを生成することです。たとえば、上記のgbmモデルとデフォルトのパラメーター(および plotmo パッケージを使用してプロットを作成する)の場合、

gbm.gaus <- gbm(y~., data = Data, dist = "gaussian")
library(plotmo)   # for the plotres function
plotres(gbm.gaus) # plot the error per ntrees and the residuals

与える

プロット

左側のプロットでは、エラー曲線が底を打っていないことがわかります。そして、右側のプロットでは、残差は望んでいるものではありません。

より多くのツリーでモデルを再構築する場合

gbm.gaus1 <- gbm(y~., data = Data, dist = "gaussian",
                 n.trees=5000, interact=3)
plotres(gbm.gaus1)

我々が得る

プロット

多数の木でエラーカーブがボトムアウトし、残差プロットがより健全であることがわかります。新しいgbmモデルとランダムフォレストモデルの部分依存プロットもプロットできます。

library(plotmo)
plotmo(gbm.gaus1, pmethod="partdep", all1=TRUE, all2=TRUE)
plotmo(rf.model,  pmethod="partdep", all1=TRUE, all2=TRUE)

与える

プロット

予想どおり、gbmとランダムフォレストモデルのプロットは類似しています。


3

interaction.depthブーストされたモデルを作成するときに、パラメーターを更新する必要があります。デフォルトは1で、これにより、gbmアルゴリズムが構築するすべてのツリーがそれぞれ1回だけ分割されます。これは、すべてのツリーが変数cで分割されていることを意味し、使用する観測のサンプルに応じて、40〜60前後で分割されます。

以下は部分プロットです。 interaction.depth = 3

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


良い点、それはある
ソレンHavelundウェリング
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.