Saya mencoba untuk menulis algoritma meningkatkan gradien saya sendiri. Saya mengerti ada paket-paket yang ada seperti gbm
dan xgboost,
tetapi saya ingin mengerti bagaimana algoritma bekerja dengan menulis sendiri.
Saya menggunakan iris
kumpulan data, dan hasil saya Sepal.Length
(berkelanjutan). Fungsi kerugian saya adalah mean(1/2*(y-yhat)^2)
(pada dasarnya kesalahan kuadrat rata-rata dengan 1/2 di depan), jadi gradien yang sesuai saya hanya residual y - yhat
. Saya menginisialisasi prediksi pada 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)
}
Dengan ini, saya membagi iris
set data menjadi pelatihan dan menguji set data dan sesuai dengan model saya.
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)
Sekarang saya menghitung nilai prediksi dari my.model
. Sebab my.model
, nilai yang dipasang adalah 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
Saya punya beberapa pertanyaan
- Apakah algoritma peningkatan gradien saya terlihat benar?
- Apakah saya menghitung nilai prediksi
yhats.mymod
dengan benar?
fit <- fit + learning.rate * prediction
, di manaprediction
residualtarget - fit
. Jadifit <- fit + lr * (target - fit)
, ataufit <- fit * (1 - lr) + target * lr
. Ini hanya rata-rata bergerak eksponensial. Per Wikipedia , "bobot dihilangkan dengan berhenti setelah istilah k(1-α)^k
keluar dari berat total" (α
adalah tingkat belajar dank
sedangn
). Anda mulai dengan perkiraan 0 bukannya rata-rata, sehingga bobot yang dihilangkan ini langsung keluar dari prediksi.