Кодування категоріальних змінних: одна гаряча та не тільки

(або: як правильно використовувати xgboost з R)

R має "одноразове" кодування, приховане у більшості своїх модельних шляхів. Запитати користувача R, де використовується однокоротке кодування, все одно, що запитати рибу, де є вода; вони не можуть вказати на нього, як це скрізь.

кодування

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

Значна частина кодування в R по суті заснована на "контрастах", реалізованих у stats: model.matrix () Примітка: не використовуйте base: data.matrix () або використовуйте хешування перед моделюванням - ви можете з цим уникнути (особливо з використанням деревних методів), але загалом вони не є хорошою технікою, як ми показуємо нижче:

stats: model.matrix () не зберігає свій гарячий план зручним чином (це можна зробити, витягнувши атрибут "контрасти" плюс вивчивши імена стовпців першого кодування, але ідентифіковані рівні не зручно представляти ). При безпосередньому застосуванні stats: model.matrix () ви не можете безпечно припустити, що однакова формула, застосована до двох різних наборів даних (скажімо, поїзд і додаток чи тест), використовує одне і те ж кодування! Ми демонструємо це нижче:

Вищезазначене неправильне кодування може бути критичним недоліком, коли ви будуєте модель, а потім використовуєте модель на нових даних (будь то дані перехресної перевірки, дані тесту або майбутні дані програми). Багато користувачів R не знайомі з вищезазначеною проблемою, оскільки кодування приховується в навчанні моделі, і як кодувати нові дані зберігається як частина моделі. Користувачі Python scikit-learn, які звертаються до R, часто запитують, "де один гарячий кодер" (оскільки це не так багато обговорюється в R, як у scikit-learn), і навіть пропонують ряд (низької якості) одно- off пакети "перенесення одноразового кодування на R".

Основне місце, де користувачеві R потрібен належний кодер (а це кодер, який зберігає свій план кодування у зручній для повторного використання формі, що насправді не вдається зробити багатьом з «одноразово перенесених з Python» пакетів) при використанні реалізація машинного навчання, яка не є повністю R -центричною. Однією з таких систем є xgboost, яка вимагає (як це характерно для машинного навчання в scikit-learn) дані вже закодовані як числова матриця (замість гетерогенної структури, такої як data.frame). Це вимагає явного перетворення з боку користувача R, і багато користувачів R помиляються (не вдається десь зберегти план кодування). Щоб зробити це конкретним, давайте попрацюємо на простому прикладі.

Давайте спробуємо набір даних Titanic, щоб побачити кодування в дії. Примітка: ми не надто працюємо над цим прикладом (як при додаванні додаткових змінних, отриманих із компонування кабіни, спільності імен та інших складних перетворень функцій) - просто підключіть очевидну змінну до xgboost. Як ми вже говорили: xgboost вимагає числової матриці для свого введення, тому, на відміну від багатьох методів моделювання R, ми повинні управляти кодуванням даних самостійно (замість того, щоб залишати це для R, яке часто приховує план кодування в навченій моделі). Також зауважте: відмінності, що спостерігаються у характеристиках нижче рівня шуму вибірки, не слід вважати значущими (наприклад, усі методи, продемонстровані тут, виконуються приблизно однаково).

Ми вводимо наші дані:

І розробіть наш перехресно підтверджений експеримент з моделювання:

Нашим кращим способом кодування даних є використання пакету vtreat у "режимі без змінних", показаному нижче (відрізняється від потужних режимів "y обізнаних", які ми зазвичай навчаємо).

Матриця моделі може виконувати подібне кодування, коли ми маємо лише один набір даних.

Пакет caret також надає функцію кодування, правильно розподілену між навчанням (caret: dummyVars ()) та додатком (так званий predict ()).

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

  • Не враховує значення результатів, тому не вимагає додаткової обережності при перехресній перевірці.
  • Зберігає своє кодування, тому може використовуватися правильно на нових даних.

Зазначені два властивості надаються спільно з caret: dummyVars (). Додаткові функції vtreat: designTreatmentsZ (які відрізняються від вибору caret: dummyVars ()) включають:

  • Vtreat: priprema () не передає значення NA .
  • Присутність НС додається як додаткова інформативна графа.
  • Кілька похідних стовпців (наприклад, об’єднання рідкісних рівнів).
  • Рідкісні фіктивні змінні обрізаються (під контролем користувача), щоб запобігти вибуху кодування.
  • Нові рівні (рівні, які виникають під час тесту або застосування, але не під час навчання) навмисно передаються як "жоден рівень навчання не активований" за допомогою vtreat: priprema () (caret: dummyVars () вважає це помилкою).

Методи vtreat, що усвідомлюють y, включають правильне вкладене моделювання та зменшення розмірностей, відомих y.

vtreat призначений "завжди працювати" (завжди повертати чистий числовий кадр даних без відсутніх значень). Він також перевершує ситуації "великих даних", коли статистика, яку він може збирати за категоріальними змінними високої потужності, може мати величезний позитивний вплив на ефективність моделювання. У багатьох випадках vtreat обробляє проблеми, які вбивають конвеєр аналізу (наприклад, виявлення нових рівнів змінних під час тестування або застосування). Ми навчаємо vtreat болю "бімодально" як в режимі "пожежа і забудь", так і в режимі "всі деталі на палубі" (підходить для офіційного цитування). У будь-якому випадку vtreat може зробити ваші процедури моделювання міцнішими, надійнішими та простішими.

Весь код цієї статті можна знайти тут.