рядки як особливості в дереві рішень / випадковому лісі


63

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

Як мені впоратися з таким сценарієм?

Я можу перетворити рядок у числа за допомогою якогось механізму, наприклад хешування в Python. Але я хотів би знати найкращу практику щодо того, як обробляються рядки в задачах дерева рішень.


У випадку sckitlearn я бачив, що нам потрібно кодувати категоричні змінні, інший метод fit видав би помилку, сказавши ValueError: не вдалося перетворити рядок у плаваючу
Kar

Відповіді:


55

У більшості налагоджених систем машинного навчання категоричні змінні обробляються природним шляхом. Наприклад, у R ви використовуєте коефіцієнти, у WEKA ви використовуєте номінальні змінні. Це не так у scikit-learn. Дерева рішень, реалізовані в scikit-learn, використовують лише числові функції, і ці функції завжди трактуються як постійні числові змінні .

Таким чином, слід уникати просто замінювати рядки хеш-кодом, оскільки, розглядаючись як безперервна числова функція, будь-яке кодування, яке ви будете використовувати, призведе до порядку, якого у ваших даних просто немає.

Один із прикладів - кодування ['червоний', 'зелений', 'синій'] з [1,2,3], призведе до дивних речей, як-от "червоний" нижче, ніж "синій", а якщо середній "червоний" а "блакитний" ви отримаєте "зелений". Ще один тонкий приклад може статися, коли ви кодуєте ['низький', 'середній', 'високий' з [1,2,3]. В останньому випадку може трапитися впорядкування, яке має сенс, однак, деякі тонкі невідповідності можуть виникнути, коли "середній" не знаходиться посередині "низького" та "високого".

Нарешті, відповідь на ваше запитання полягає в кодуванні категоріальної ознаки у кілька двійкових ознак . Наприклад, ви можете кодувати ['червоний', 'зелений', 'синій'] з 3 стовпцями, по одному для кожної категорії, маючи 1, коли категорія відповідає, а 0 - інакше. Це називається однокольоровим кодуванням , бінарним кодуванням, кодуванням one-of-k або будь-яким іншим. Ви можете перевірити тут документацію на предмет кодування категоричних особливостей та вилучення функцій - хешування та диктів . Очевидно, що однокольорове кодування розширить ваші потреби в просторі, а іноді і зашкодить продуктивності.


2
Це реалізація scikit, що вона не обробляє належними категоричними змінними. Декламування, як, на думку цієї відповіді, - це, мабуть, найкраще, що ви можете зробити. Більш серйозний користувач може шукати альтернативний пакет.
SmallChess

3
Можна використовувати sklearn.preprocessing.LabelBinarizer для однокольорового кодування категоріальної змінної.
GuSuku

@rapaio Я думаю, що бінарне кодування - це не одне гаряче кодування. Бінарне кодування - це коли ви представляєте 8 категорій з 3 стовпцями або між 9-16 категоріями з 4 стовпцями тощо. Я помиляюся?
Алок Наяк

пакет patsy python буде працювати з гарячим кодуванням категоричних змінних. patsy.readthedocs.io/en/latest/quickstart.html
zhespelt

5
Не використовуйте LabelBinarizer, використовуйте sklearn.preprocessing.OneHotEncoder . Якщо ви використовуєте панди для імпорту та попередньої обробки своїх даних, ви також можете це зробити безпосередньо, використовуючи pandas.get_dummies . Це гадає, що scikit-learn не підтримує категоричні змінні.
Рікардо Крус

11

Вам потрібно кодувати рядки як числові функції, які науковий комплект може використовувати для алгоритмів ML. Ця функціональність обробляється в модулі попередньої обробки (наприклад, див. Приклад sklearn.preprocessing.LabelEncoder ).


3
rapaio пояснює у своїй відповіді, чому це призведе до неправильного результату
Кіт

7

Зазвичай ви повинні кодувати категоричні змінні для наукових моделей, зокрема випадкових лісів. Випадковий ліс часто спрацьовує без кодування гарячого режиму, але, як правило, краще, якщо ви робите однокольоровий кодування. Змінні однокольорового кодування та "манекені" означають одне і те ж у цьому контексті. Scikit-learn має sklearn.preprocessing.OneHotEncoder і Pandas має pandas.get_dummies для цього.

Однак є й альтернативи. Стаття «Поза одним гарячим» у KDnuggets чудово пояснює, чому потрібно кодувати категоричні змінні та альтернативи кодирувальному кодуванню.

Існують альтернативні реалізації випадкових лісів, які не потребують однокольорового кодування, такі як R або H2O. Реалізація в R обчислювально дорога і не працюватиме, якщо у ваших функціях є багато категорій . H2O буде працювати з великою кількістю категорій. Континуум зробив H2O доступним в Anaconda Python.

Існує постійні зусилля , щоб зробити scikit-Learn обробляти категоріальні особливості безпосередньо .

У цій статті є пояснення алгоритму, який використовується у H2O. Він посилається на науковий документ Алгоритм дерева потокового паралельного рішення та більш тривалий варіант цього ж документу.


5

Оновлення 2018 року!

Ви можете створити простір для вбудовування (щільний вектор) для ваших категоричних змінних. Багатьом з вас знайомі слова word2vec і fastext, які вбудовують слова у змістовний щільний векторний простір. Тут ідея така сама - ваші категоричні змінні відображатимуться у векторному сенсі.

З паперу Го / Берхана :

Вбудовування об'єктів не тільки зменшує використання пам'яті та прискорює нейронні мережі порівняно з однокольоровим кодуванням, але, що ще важливіше, відображаючи подібні значення, близькі один до одного у вбудовуваному просторі, воно виявляє внутрішні властивості категоричних змінних. Ми успішно застосували його в недавньому конкурсі Kaggle і змогли вийти на третю позицію порівняно простими функціями.

Автори встановили, що представлення категоричних змінних таким чином підвищило ефективність усіх перевірених алгоритмів машинного навчання, включаючи випадкові ліси.

Найкращим прикладом може бути застосування методики Pinterest для групування пов'язаних штифтів:

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

Люди в Фастаї реалізували категоричні вкладення та створили дуже приємну публікацію в блозі із супутником демо-ноутбука .

Додаткові відомості та пояснення

Нейронна сітка використовується для створення вбудовування, тобто присвоює вектор кожному категоричному значенню. Отримавши вектори, ви можете використовувати їх у будь-якій моделі, яка приймає числові значення. Кожен компонент вектора стає вхідною змінною. Наприклад, якщо ви використовували 3-D вектори для вбудовування свого категоричного списку кольорів, ви можете отримати щось на зразок: red = (0, 1,5, -2,3), blue = (1, 1, 0) тощо. Ви б використали три вхідні змінні у вашому випадковому лісі, що відповідають трьом компонентам. Для червоних речей c1 = 0, c2 = 1,5 і c3 = -2,3. Для блакитних речей c1 = 1, c2 = 1 і c3 = 0.

Насправді не потрібно використовувати нейронну мережу для створення вбудовування (хоча я не рекомендую уникати техніки). Ви можете створювати власні вкладки вручну чи іншими способами, коли це можливо. Деякі приклади:

  1. Показуйте кольори на вектори RGB.
  2. Розташуйте розташування на векторах lat / long.
  3. У політичній моделі США відображайте міста на деяких векторних компонентах, що представляють вирівнювання зліва / праворуч, податкове навантаження тощо.

Добре круто, але якщо я щось не пропустив, це для мереж починають закінчувати. Як ми створимо вбудовування і потім передаємо це вбудовування у форрест? Я думаю, що вам доведеться навчити цілу мережу з усіма функціями, а потім взяти перші кілька шарів і використовувати це як вашу вхідну функцію для вашого Forrest. Незрозуміло, як би це було зроблено.
Кіт

@Keith нейронна сітка використовується для створення вбудовування, тобто присвоює вектор кожному категоричному значенню. Отримавши вектори, ви можете використовувати їх у будь-якій моделі, яка приймає числові значення. Кожен компонент вектора стає вхідною змінною. Наприклад, якщо ви використовували 3-D вектори для вбудовування свого категоричного списку кольорів, ви можете отримати щось на зразок: red = (0, 1.5, -2.3), blue = (1, 1, 0)тощо. Ви б використали три вхідні змінні у своєму випадковому лісі, що відповідають трьом компонентам. Для червоних речей c1 = 0, c2 = 1,5 і c3 = -2,3. Для блакитних речей c1 = 1, c2 = 1, і c3 = 0.
Піт

Я повністю розумію цю концепцію, оскільки вона досить проста. Я маю на увазі, як би це було зроблено при впровадженні? Демо-ноутбук fast.ai, до якого ви посилаєтеся, має дещо з RandomForestRegressor наприкінці, але я не дуже розумію, як це додається до вбудовування.
Кіт

Я думаю, що це може бути хорошим прикладом коду в Keras github.com/entron/entity-embedding-rossmann
Кіт

3

Ви можете використовувати фіктивні змінні в таких сценаріях. За допомогою панд panda.get_dummiesви можете створювати фіктивні змінні для рядків, які потрібно помістити в Дерево рішень або Випадковий ліс.

Приклад:

import pandas as pd
d = {'one' : pd.Series([1., 2., 3.,4.], index=['a', 'b', 'c','d']),'two' :pd.Series(['Paul', 'John', 'Micheal','George'], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(d)

df_with_dummies= pd.get_dummies(df,columns=["two"],drop_first=False)
df_with_dummies

2

Перетворіть їх на числа, наприклад, для кожної країни, яка містить унікальне число (наприклад, 1,2,3 та ...)

також вам не потрібно використовувати One-Hot Encoding (також фіктивні змінні) під час роботи з випадковим лісом, оскільки дерева не працюють як інші алгоритми (наприклад, лінійна / логістична регресія) і вони не працюють віддаленими (вони працюйте з пошуком хорошого розбиття для ваших особливостей), тому НЕ ПОТРІБНО для One-Hot Encoding


1
Це насправді залежить від конкретного алгоритму, який тренує дерево. Зокрема, scikit НЕ підтримує категоричні змінні.
ч.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.