独自の勾配ブースティングアルゴリズムを記述しようとしています。 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
_
少し質問があります
yhats.mymod
_を正しく計算しましたか?しかし、尋ねられなかったことに対処するために、私はあなたのトレーニング設定にいくつかの癖があることに気づきました。
iris
データセットは3つの種(setosa、versicolor、virginica)の間で均等に分割され、これらはデータ内で隣接しています。トレーニングデータにはsetosaとversicolorがすべて含まれていますが、テストセットにはvirginicaの例がすべて含まれています。重複がないため、サンプル外の問題が発生します。これを回避するには、トレーニングセットとテストセットのバランスをとることが推奨されます。(1-lr)^n
として収束します。 lr = 1e-3
とn = 1000
では、モデル化できるのはデータの大きさの63.2%のみです。つまり、すべてのモデルがすべてのサンプルを正しく予測したとしても、正しい値の63.2%を推定することになります。 0の代わりに平均でフィットを初期化すると、効果は単なるドラッグではなく平均への回帰になるので役立ちます。