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), і вони суміжні в даних. У ваших даних про навчання є всі сетоза і версіколор, тоді як у тестовому наборі є всі приклади virginica. Не існує перекриття, яке призведе до позапробних проблем. Бажано збалансувати тренувальний і тестовий набори, щоб цього уникнути.
  • Поєднання рівня навчання та кількості моделей здається мені занадто низьким. Підходить сходиться як (1-lr)^n. З lr = 1e-3і n = 1000можна моделювати лише 63,2% від величини даних. Тобто, навіть якщо кожна модель правильно прогнозує кожен зразок, ви оцінювали б 63,2% від правильного значення. Ініціалізація пристосування із середнім, а не 0, допоможе з тих пір ефектом є регресія до середнього, а не просто перетягування.

Дякую за ваші коментарі. Чи можете ви розширити, чому "fit збігається як (1-lr) ^ n"? Що обґрунтовує це?
YQW

Це тому fit <- fit + learning.rate * prediction, що де predictionзалишковий target - fit. Так fit <- fit + lr * (target - fit), або fit <- fit * (1 - lr) + target * lr. Це просто експоненціальна ковзаюча середня величина. Згідно з Вікіпедією , "вага, опущений після зупинки після k термінів, (1-α)^kвиходить із загальної ваги" ( αце рівень навчання та kє n). Ви починаєте з оцінки 0 замість середньої, тому ця вага, опущена, виходить безпосередньо з прогнозування.
mcskinner
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.