R:独自の勾配ブースティングアルゴリズムを実装する


10

独自の勾配ブースティングアルゴリズムを記述しようとしています。私はそこのような既存のパッケージがあり理解gbmし、xgboost,しかし、私はしているアルゴリズムは、独自に書き込むことによって、どのように動作するかを理解したかったです。

irisデータセットを使用していますが、結果はSepal.Length(継続的)です。私の損失関数はmean(1/2*(y-yhat)^2)(基本的には前に1/2の平均二乗誤差)であるため、対応する勾配はただの残差y - yhatです。予測を0に初期化しています。

library(rpart)
data(iris)

#Define gradient
grad.fun <- function(y, yhat) {return(y - yhat)}

mod <- list()

grad_boost <- function(data, learning.rate, M, grad.fun) {
  # Initialize fit to be 0
  fit <- rep(0, nrow(data))
  grad <- grad.fun(y = data$Sepal.Length, yhat = fit)

  # Initialize model
  mod[[1]] <- fit

  # Loop over a total of M iterations
  for(i in 1:M){

    # Fit base learner (tree) to the gradient
    tmp <- data$Sepal.Length
    data$Sepal.Length <- grad
    base_learner <- rpart(Sepal.Length ~ ., data = data, control = ("maxdepth = 2"))
    data$Sepal.Length <- tmp

    # Fitted values by fitting current model
    fit <- fit + learning.rate * as.vector(predict(base_learner, newdata = data))

    # Update gradient
    grad <- grad.fun(y = data$Sepal.Length, yhat = fit)

    # Store current model (index is i + 1 because i = 1 contain the initialized estiamtes)
    mod[[i + 1]] <- base_learner

  }
  return(mod)
}

これにより、irisデータセットをトレーニングデータセットとテストデータセットに分割し、モデルをそれに適合させました。

train.dat <- iris[1:100, ]
test.dat <- iris[101:150, ]
learning.rate <- 0.001
M = 1000
my.model <- grad_boost(data = train.dat, learning.rate = learning.rate, M = M, grad.fun = grad.fun)

次に、から予測値を計算しますmy.model。の場合my.model、近似値は0 (vector of initial estimates) + learning.rate * predictions from tree 1 + learning rate * predictions from tree 2 + ... + learning.rate * predictions from tree Mです。

yhats.mymod <- apply(sapply(2:length(my.model), function(x) learning.rate * predict(my.model[[x]], newdata = test.dat)), 1, sum)

# Calculate RMSE
> sqrt(mean((test.dat$Sepal.Length - yhats.mymod)^2))
[1] 2.612972

少し質問があります

  1. 勾配ブースティングアルゴリズムは正しく見えますか?
  2. 予測値をyhats.mymod正しく計算しましたか?

回答:


0
  1. はい、これは正しいようです。各ステップで、近似に関する損失の導関数として計算される疑似残差に近似します。質問の最初にこの勾配を正しく導き出し、2の因数を正しくすることにさえ苦労しました。
  2. これも正しいようです。トレーニング中に行ったのと同じように、学習率によって重み付けされたモデル全体を集計しています。

しかし、尋ねられなかったことに対処するために、あなたのトレーニング設定にはいくつかの癖があることに気付きました。

  • irisデータセットは、等しく3種(setosa、versicolorの、virginicaの)これらのデータに隣接しているとの間で分割されます。トレーニングデータにはsetosaとversicolorがすべて含まれていますが、テストセットにはvirginicaの例がすべて含まれています。重複がないため、サンプル外の問題が発生します。これを回避するには、トレーニングセットとテストセットのバランスをとることが推奨されます。
  • 学習率とモデル数の組み合わせは私には低すぎるように見えます。近似は次のように収束し(1-lr)^nます。ではlr = 1e-3n = 1000モデル化できるのはデータの大きさの63.2%のみです。つまり、すべてのモデルがすべてのサンプルを正しく予測したとしても、正しい値の63.2%を推定することになります。0の代わりに平均でフィットを初期化すると、効果はドラッグではなく平均への回帰になるので役立ちます。

コメントしてくださってありがとうございます。「フィットが(1-lr)^ nとして収束する理由」を詳しく教えてください。この背後にある根拠は何ですか?
YQW

それは、残差fit <- fit + learning.rate * predictionがどこにあるからです。それで、または。これは単なる指数移動平均です。パーウィキペディア、「k個の用語の後に停止させることにより、省略量が総重量のうち、」(学習率であるとされます)。平均ではなく推定0から始めているため、省略されたこの重みは予測から直接得られます。predictiontarget - fitfit <- fit + lr * (target - fit)fit <- fit * (1 - lr) + target * lr(1-α)^kαkn
mcskinner
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.