Логістична регресія в пакеті машинного навчання «XGboost»

image
У цій статті мова піде про логістичної регресії та її реалізації в одному з найбільш продуктивних пакетів машинного навчання "R" — "XGboost" (Extreme Gradient Boosting).
У реальному житті ми досить часто стикаємося з класом задач, де об'єктом прогнозування є номінативна змінна з двома градаціями, коли нам необхідно передбачити результат якогось події або прийняти рішення у двійковому виразі на підставі моделі даних. Наприклад, якщо ми оцінюємо ситуацію на ринку і нашою метою є прийняття однозначного рішення, має сенс інвестувати в певний інструмент в даний момент часу, купить покупець досліджуваний продукт чи ні, розплатиться за кредитом позичальник або звільниться працівник з компанії найближчим часом і. т. д.
У загальному випадку логістична регресія застосовується для передбачення ймовірності виникнення деякої події за значенням множини ознак. Для цього вводиться так звана залежна змінна (результат події), приймаюча лише одне з двох значень (0 або 1), і безліч незалежних змінних (також званих ознаками, предикторами або регрессорами).
Відразу обмовлюся, що в "R" існує кілька лінійних функцій для навчання логіт-моделі, таких як "glm" із стандартного пакету функцій, але тут ми розглянемо більш просунутий варіант, імплементований в пакеті "XGboost". Ця модель, багаторазовий переможець змагань Kaggle, заснована на побудові бінарних дерев рішень здатна підтримувати багатопотокове оброблення даних. Про особливості реалізації сімейства моделей "Gradient Boosting" можна прочитати тут:
http://www.ncbi.nlm.nih.gov/pmc/articles/PMC3885826/
https://en.wikipedia.org/wiki/Gradient_boosting
Візьмемо тестовий набір даних (Train) і побудуємо модель для прогнозування виживання пасажирів при катастрофі :
data(agaricus.train, package='xgboost') 
data(agaricus.test, package='xgboost') 
train <- agaricus.train 
test <- agaricus.test 

Якщо після перетворення матриця містить багато нулів, то такий масив даних потрібно попередньо перетворити в sparse matrix — в такому вигляді дані займуть набагато менше місця, а відповідно і час обробки даних значно скоротиться. Тут нам допоможе бібліотека 'Matrix' на сьогоднішній день остання доступна версія 1.2-6 містить у собі набір функція для перетворення в dgCMatrix на колонковою основі.
У разі, коли вже ущільнена матриця (sparse matrix) після всіх перетворень не поміщається в оперативній пам'яті, то в таких випадках використовують спеціальну програму «Vowpal Wabbit». Це зовнішня програма, яка може обробити датасеты будь-яких розмірів, читаючи з багатьох файлів або баз даних. «Vowpal Wabbit» являє собою оптимізовану платформу для паралельного машинного навчання, розроблену для розподілених обчислень компанією «Yahoo!» Про неї досить детально можна прочитати за цим посиланням:
https://habrahabr.ru/company/mlclass/blog/248779/
https://en.wikipedia.org/wiki/Vowpal_Wabbit
Використання розріджених матриць дає нам можливість будувати модель з використанням текстових змінних з попередніми їх перетворенням.
Отже, для побудови матриці предикторів спочатку завантажуємо необхідні бібліотеки:
library(xgboost) 
library(Matrix) 
library(DiagrammeR) 

При конвертації в матрицю всі категоріальні змінні будуть транспониваны, відповідно функція зі стандартним бустером включить їх значення в модель. Перше що потрібно зробити, це видалити з набору даних змінні з унікальними значеннями, такими як «Passenger ID», «Name» і «Ticket Number». Такі ж дії проводимо і з тестовим набором даних, за якими розраховується прогнозні результати. Для наочності я завантажив дані з локальних файлів, які скачав у відповідному датасете Kaggle. Для моделі, ним знадобляться наступні колонки таблиці:
input.train <- train[, c(3,5,6,7,8,10,11,12)] 
input.test <- test[, c(2,4,5,6,7,9,10,11)] 

image
окремо формуємо вектор відомих результатів для навчання моделі
train.lable <- train$Survived 

Тепер необхідно виконати перетворення даних, щоб при навчанні моделі облік були прийняті статистично значущі змінні. Виконаємо такі перетворення:
Замінимо змінні містять категоріальні дані числові значення. При цьому потрібно враховувати що впорядковані категорії, такі як 'good', 'normal', 'bad' можна замінити на 0,1,2. Не впорядковані дані з відносно невеликою селективністю, такі як 'gender' або 'Country Name' можна залишити факторними без зміни, після перетворення в матрицю вони транспонуються у відповідну кількість стовпців з нулями та одиницями. Для числових змінних, необхідно обробити всі неприсвоенные і пропущені значення. Тут є як мінімум три варіанти: їх можна замінити на 1, 0 або більш прийнятний варіант буде заміна на середнє значення по колонці цієї змінної.
При використанні пакету «XGboost» зі стандартним бустером (gbtree), масштабування змінних можна не виконувати, на відміну від інших лінійних методів, таких як «glm» або «xgboost» c лінійним бустером (gblinear).
Основну інформацію про пакеті можна знайти за наступними посиланнями:
https://github.com/dmlc/xgboost
https://cran.r-project.org/web/packages/xgboost/xgboost.pdf
Повертаючись до нашого коду, в результаті ми отримали таблицю наступного формату:
image
далі, замінюємо всі пропущені запису на середнє арифметичне значення за стовпцем предиктора
if (class(inp.column) %in% c('numeric', 'integer')) {
inp.table[is.na(inp.column), i] <- mean(inp.column, na.rm=TRUE) 

після попередньої обробки робимо перетворення в "dgCMatrix":
sparse.model.matrix(~., inp.table) 

Має сенс створити окрему функцію для попередньої обробки предикторів та перетворення в sparse.model.matrix формат, наприклад, варіант з "for" циклом наведено нижче. З метою оптимізації продуктивності можна векторизовать вираз використовуючи функцію "apply".
spr.matrix.conversion <- function(inp.table) { 
for (i in 1:ncol(inp.table)) { 
inp.column <- inp.table [i] 
if (class(inp.column) == 'character') { 
inp.table [is.na(inp.column), i] <- 'NA' 
inp.table [i] <- as.factor(inp.table [i]) 
} 
else 
if (class(inp.column) %in% c('numeric', 'integer')) { 
inp.table [is.na(inp.column), i] <- mean(inp.column, na.rm=TRUE) 
} 
} 
return(sparse.model.matrix(~.,inp.table))
} 

Тоді скористаємося функцією нашої і перетворимо фактичну і тестову таблиці в розріджені матриці:
sparse.train <- preprocess(train) 
sparse.test <- preprocess(test) 

image
Для побудови моделі нам буде потрібно два набори даних: матриця даних, яку ми тільки що створили і вектор фактичних результатів з бінарним значення (0,1).
Функція «xgboost» є найбільш зручною у використанні. У «XGBoost» імплементований стандартний бустер заснований на бінарних деревах рішень.
Для використання «XGboost», ми повинні вибрати один з трьох параметрів: загальні параметри, параметри бустера і параметрів призначення:
• Загальні параметри – визначаємо, який бустер буде використаний, лінійний або стандартний.
Інші параметри бустера залежать від того, який бустер ми вибрали на першому кроці:
• Параметри завдань навчання – визначаємо призначення і сценарій навчання
• Параметри командного рядка використовуються для визначення режиму командного рядка при використанні «xgboost.».
Загальний вигляд функції «xgboost» який ми використовуємо:
xgboost(data = NULL, label = NULL, missing = NULL, params = list(), nrounds, verbose = 1, print.every.n = 1L, early.stop.round = NULL, maximize = NULL ...) 

"data" – дані матричному форматі ( "matrix", "dgCMatrix", local data file or "xgb.DMatrix".)
"label" – вектор залежної змінної. Якщо це поле було складової вихідної таблиці параметрів, то перед обробкою і перетворенням в матрицю, його слід вилучити, щоб уникнути транзитивности зв'язків.
"nrounds" –кількість побудованих дерев рішень у фінальній моделі.
"objective" – через цей параметр ми передаємо завдання і призначення моделі навчання. Для логістичної регресії існують 2 варіанти:
"reg:logistic" – логістична регресія з безперервною величиною оцінки від 0 до 1;
"binary:logistic" – логістична регресія з бінарної величиною передбачення. Для цього параметра можна вказати специфічну порогову величину переходу від 0 до 1. За замовчуванням це значення 0.5.
Детально про параметризацію моделі можна прочитати за цим посиланням
http://xgboost/parameter.md%20at%20master%20·%20dmlc/xgboost%20·%20GitHub
Тепер приступаємо до створення і навчання моделі «XGBoost»:
set.seed(1) 
xgb.model <- xgboost(data=sparse.train, label=train$Survived, nrounds=100, objective='reg:logistic') 

при бажанні можна отримати структуру дерев за допомогою функції xgb.model.dt.tree( model = xgb). Далі, використовуємо стандартну функцію «predict» для формування прогнозного вектора:
prediction <- predict(xgb.model, sparse.test) 

і нарешті, збережемо дані в прийнятному для читання форматі
solution <- data.frame(prediction = round(prediction, digits = 0), test) 
write.csv(solution, 'solution.csv', row.names=FALSE, quote=FALSE 

додаючи вектор прогнозованих результатів, отримуємо таблицю наступного виду:
image
Тепер трохи повернемося і коротко розглянемо саму модель, яку ми тільки що створили. Для відображення дерев рішення, можна скористатися функціями "xgb.model.dt.tree" і "xgb.plot.tree". Так, остання функція видасть нам список обраних дерев з коефіцієнтом підгонки моделі:
image
Використовуючи функцію xgb.plot.tree ми також побачимо графічне представлення дерев, хоча треба зазначити, що в поточній версії, воно далеко не найкращим способом імплементовано в даній функції і є мало корисним. З цього, для наочності, мені довелося вручну відтворити елементарне дерево рішень на базі стандартної моделі даних Train.
image
Перевірка статистичної значущості змінних в моделі підкаже нам як оптимізувати матрицю предикторів для навчання XGB-моделі. Краще всього використовувати функцію xgb.plot.importance в яку ми передамо агреговану таблицю важливості параметрів.
importance_frame <- xgb.importance(sparse.train@Dimnames[[2]], model = xgb) 
xgb.plot.importance(importance_frame) 

image
Отже, ми розглянули одну з можливих реалізацій логістичної регресії на базі пакету функції «xgboost» зі стандартним бустером. На даний момент я рекомендую використовувати пакет «XGboost» як найбільш просунуту групу моделей машинного навчання. У справжні час предиктивные моделі на базі логіки «XGboost» широко використовуються у фінансовому та ринковому прогнозування, маркетингу і багатьох інших областях прикладної аналітики і машинного інтелекту.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.