Точність машини для підвищення градієнта зменшується зі збільшенням кількості ітерацій


15

Я експериментую з алгоритмом машини для підвищення градієнта через caretпакет в Р.

Використовуючи невеликий набір даних про вступ до коледжу, я застосував такий код:

library(caret)

### Load admissions dataset. ###
mydata <- read.csv("http://www.ats.ucla.edu/stat/data/binary.csv")

### Create yes/no levels for admission. ### 
mydata$admit_factor[mydata$admit==0] <- "no"
mydata$admit_factor[mydata$admit==1] <- "yes"             

### Gradient boosting machine algorithm. ###
set.seed(123)
fitControl <- trainControl(method = 'cv', number = 5, summaryFunction=defaultSummary)
grid <- expand.grid(n.trees = seq(5000,1000000,5000), interaction.depth = 2, shrinkage = .001, n.minobsinnode = 20)
fit.gbm <- train(as.factor(admit_factor) ~ . - admit, data=mydata, method = 'gbm', trControl=fitControl, tuneGrid=grid, metric='Accuracy')
plot(fit.gbm)

і я здивував, що точність крос-валідації моделі зменшилась, а не збільшилася, оскільки кількість ітерацій підсилення збільшувалась, досягаючи мінімальної точності приблизно в 599 при ~ 450 000 ітерацій.

введіть тут опис зображення

Чи я неправильно реалізував алгоритм GBM?

EDIT: За пропозицією Underminer я перезаписав вищезгаданий caretкод, але зосередився на виконанні 100-000 прискорених ітерацій:

set.seed(123)
fitControl <- trainControl(method = 'cv', number = 5, summaryFunction=defaultSummary)
grid <- expand.grid(n.trees = seq(100,5000,100), interaction.depth = 2, shrinkage = .001, n.minobsinnode = 20)
fit.gbm <- train(as.factor(admit_factor) ~ . - admit, data=mydata, method = 'gbm', trControl=fitControl, tuneGrid=grid, metric='Accuracy')
plot(fit.gbm)

Отриманий графік показує, що точність насправді досягає майже .705 при ~ 1800 ітераціях:

введіть тут опис зображення

Цікавим є те, що точність не плато на ~ .70, а натомість знизилася після 5000 ітерацій.

Відповіді:


14

Загалом, помилка прискорення може збільшуватись із кількістю ітерацій, зокрема, коли дані шумно (наприклад, неправильно позначені випадки). Це може бути вашою проблемою, але я не зміг би сказати, не знаючи більше про ваші дані

В основному, прискорення може «зосередитись» на правильному прогнозуванні випадків, що містять дезінформацію, і в процесі цього погіршить середню ефективність в інших суттєвих випадках.

Це посилання ( Збільшення рівня шуму ) показує кращий опис, ніж я можу надати проблему.

У цьому документі ( Шум випадкової класифікації ) Лонг та Серведіо подано більше технічних деталей випуску.


16

Те, що ви показали, - це класичний приклад оздоблення. Невелика помилка помилки походить від меншої продуктивності на частині перевірки вашого перехресного набору даних. Більше ітерацій майже завжди повинно покращувати помилки на тренувальному наборі, але навпаки справедливо для валідації / тестового набору.


Отже, градієнт збільшує надлишки на основі # підсилюючих ітерацій? Цікаво. Я подумав, що точність замість цього стане платою після досягнення оптимальної # ітерацій.
RobertF

4
Це правильно. При збільшенні градієнта кожне наступне дерево будується від залишків попередніх дерев, тож ГБМ продовжуватиме намагатися вирізати решту помилок у наборі даних про навчання, навіть ціною змоги узагальнити до наборів перевірки / тестування. Ось чому ви виконуєте перехресну перевірку - адже алгоритм підгонки не знає, коли зупинитись
Ryan Zotti

1
Gradient Boosting натхненний AdaBoost. AdaBoost дуже рідко переповнює, і коли це робиться, це лише трохи і після багатьох, багатьох ітерацій. Я думаю, що пояснення @Underminer швидше буде представником того, що відбувається, ніж цей коментар, особливо враховуючи, що в цьому коментарі немає посилань.
Рікардо Крус

2
@RicardoCruz Я думаю, що цікаво, що ви рідко бачили градієнт, що збільшує наряд. Протягом чотирьох або більше років, якими я користувався, я бачив навпаки - занадто багато дерев призводять до надмірного вбрання. Мені колись довелося довести щось подібне колезі, і я зміг зменшити помилку на тренувальному наборі майже до нуля, але помилка перевірки зросла значно більше, ніж помилка непридатного GBM. Я все ще думаю, що градієнтне підвищення - це чудовий алгоритм. Зазвичай це перший алгоритм, який я використовую - ви просто повинні бути обережними щодо занадто багато дерев, які ви можете відстежувати за допомогою перехресної перевірки
Ryan Zotti

2
@RyanZotti Я виправляюсь тоді. Я прочитав купу робіт про AdaBoost від Schapire et al, тому що мені подобається її прекрасна міцна теоретична основа. Автори стверджують, що підсилення схильне до надмірного оснащення, але це вкрай складно. Я не маю великого досвіду його використання, і вони не мають твердої теоретичної основи для аргументації цього, і, звичайно, автори, які є авторами, вони, природно, ревно ставляться до свого винаходу, тому якщо у вас є досвід протилежного , Я виправлений.
Рікардо Крус

4

Коди для відтворення аналогічного результату без пошуку в сітці,

mod = gbm(admit ~ .,
      data = mydata[,-5],
      n.trees=100000,
      shrinkage=0.001,
      interaction.depth=2,
      n.minobsinnode=10,
      cv.folds=5,
      verbose=TRUE,
      n.cores=2)

best.iter <- gbm.perf(mod, method="OOB", plot.it=TRUE, oobag.curve=TRUE, overlay=TRUE)
print(best.iter)
[1] 1487
pred = as.integer(predict(mod, newdata=mydata[,-5], n.trees=best.iter) > 0)
y = mydata[,1]
sum(pred == y)/length(y)
[1] 0.7225

3

Пакет gbm має функцію для оцінки оптимальної # ітерацій (= # дерев або # базових функцій),

gbm.perf(mod, method="OOB", plot.it=TRUE, oobag=TRUE, overlay=TRUE)

Для цього вам не потрібен потяг карети.


Я не знаю, чи це вирішує проблему, яку я маю - виявляється, що в моєму випадку оптимальна кількість ітерацій - 5000, коли точність є найвищою, близько 0,70 (перша точка мого сюжету). Але це здається неправильним. Більше ітерацій повинно призвести до більшої точності, а не нижче, правда?
RobertF

1
@RobertF По-перше, я думаю, вам не потрібно перетворювати визнання на фактор. Він працює так само: mod = gbm (визнай ~., Data = mydata [, - 5], n.trees = 100000, усадка = 0,001, взаємодія.depth = 2, n.minobsinnode = 10, cv.folds = 5 , багатослівний = ІСТИНА, n.cores = 2). Ви можете побачити, де gbm вибирає оптимальний ітер за: best.iter <- gbm.perf (mod, method = "OOB", plot.it = TRUE, oobag.curve = TRUE, overlay = TRUE). Тобто, коли зміна відхилення стає негативною (див. Сюжет, породжений з цього).
horaceT

1
@RobertF Ще одна річ. Вказавши n.trees = (один мільйон) у виклику gbm, ви б запустили всі числа ітерацій від 1 до 1 000 000. Тож вам не потрібна карета, щоб зробити це за вас.
horaceT

1
@RobertF Детальніше Я щойно пробіг 100 к дерев / ітерацій. Точність, яку я отримав, вибравши найкращу ітерацію за допомогою gbm.perf, становить 0,7225, що досить близько до вашого, виконуючи повну сітку ітерацій.
horaceT
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.