J'essaie d'écrire mon propre algorithme de renforcement de gradient. Je comprends qu'il existe des packages existants comme gbmet xgboost,mais je voulais comprendre comment l'algorithme fonctionne en écrivant le mien.
J'utilise l' irisensemble de données et mon résultat est Sepal.Length(continu). Ma fonction de perte est mean(1/2*(y-yhat)^2)(essentiellement l'erreur quadratique moyenne avec 1/2 devant), donc mon gradient correspondant n'est que le résiduel y - yhat. J'initialise les prédictions à 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)
}
Avec cela, j'ai divisé l' irisensemble de données en un ensemble de données de formation et de test et j'adapte mon modèle à celui-ci.
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)
Maintenant, je calcule les valeurs prévues à partir de my.model. Pour my.model, les valeurs ajustées sont 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
J'ai quelques questions
- Mon algorithme d'amplification du gradient semble-t-il correct?
- Ai-je calculé yhats.mymodcorrectement les valeurs prévues ?