One-Hot Encoding простыми словами
NULL в столбце источника перехода на значение 'direct'. Какой вариант записан корректно и эквивалентен по смыслу?Содержание:
Зачем это знать
ML-модели работают с числами, а не с категориями. Если у вас колонка city со значениями ['Moscow', 'SPb', 'Kazan'], модель не поймёт их напрямую. Нужно закодировать в числа. Способов кодирования несколько, и от выбора зависит качество модели.
One-hot encoding — самый распространённый способ. На собеседовании DS/ML обязательно спросят: «как закодируете категориальную переменную», «что такое one-hot», «когда использовать target encoding». Без этих знаний — уровень ниже middle.
В статье — полное понимание:
- Что такое one-hot на примере.
- Плюсы и минусы.
- Альтернативы: label encoding, target encoding, binary encoding.
- Когда какое применять.
- Практика в pandas и sklearn.
Короткое объяснение
One-hot превращает категориальную переменную в набор бинарных (0/1) колонок — по одной на каждое уникальное значение.
Пример
city
----
Moscow
SPb
Moscow
KazanПосле one-hot:
city_Moscow city_SPb city_Kazan
1 0 0
0 1 0
1 0 0
0 0 1Каждое значение → отдельная колонка, в ней 1 если match.
В pandas
df_encoded = pd.get_dummies(df, columns=['city'])Или через sklearn:
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder(sparse_output=False)
encoded = encoder.fit_transform(df[['city']])drop_first
pd.get_dummies(df, columns=['city'], drop_first=True)Удаляет первую колонку (Moscow). Она и так выводится из остальных (если все 0 → Moscow).
Зачем: избежать мультиколлинеарности в линейных моделях. Для tree-based моделей (Random Forest, XGBoost) не обязательно.
Когда one-hot работает хорошо
- Небольшое количество категорий (2–20).
- Категории без порядка (номинальные).
- Модель линейная или tree-based.
Когда one-hot работает плохо
- Много уникальных значений (сотни городов).
- Большие датасеты (размер матрицы взрывается).
- Избыточно для tree-based (можно обойтись label encoding).
Альтернативы
1. Label Encoding
Просто целые числа: Moscow=0, SPb=1, Kazan=2.
from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
df['city_encoded'] = encoder.fit_transform(df['city'])Плюсы: одна колонка, компактно. Минусы: вводит ложный порядок. Moscow < SPb < Kazan? Для линейных моделей плохо.
Для tree-based — ок, модель игнорирует порядок.
2. Target Encoding
Заменяет категорию на среднее значение target по этой категории:
Moscow → 0.15 (средняя конверсия)
SPb → 0.12
Kazan → 0.08# вручную
city_target = df.groupby('city')['target'].mean()
df['city_encoded'] = df['city'].map(city_target)Плюсы: работает для high cardinality (много уникальных значений). Минусы: риск data leakage, нужна регуляризация.
3. Binary Encoding
Представляет числа в двоичном виде.
100 уникальных значений → label encoding даёт 100 чисел → 7 бит в двоичном представлении → 7 колонок.
Меньше, чем one-hot, при high cardinality.
4. Frequency Encoding
Заменяет категорию на её частоту в данных:
Moscow (1000 раз) → 1000 / 10000 = 0.1
SPb (500) → 0.05Когда какое использовать
| Cardinality | Модель | Выбор |
|---|---|---|
| Low (2–10) | любая | One-Hot |
| Medium (10–50) | tree-based | Label или One-Hot |
| Medium | линейная | One-Hot |
| High (50+) | любая | Target / Frequency |
| Very high (1000+) | любая | Embeddings (deep learning) |
Новые категории в test
Проблема: в train есть 'Moscow', в test появится 'Новгород', которого в train не было.
encoder = OneHotEncoder(handle_unknown='ignore')Или заменить редкие на 'Other' до кодирования.
На собесе
«Что такое one-hot encoding?» Каждое значение категории превращается в отдельную бинарную колонку.
«Когда label encoding?» Tree-based модели с категориями без естественного порядка.
«Минусы target encoding?» Data leakage, если не разделить правильно train и test.
«Категория из 1000 городов — как?» Target или frequency encoding вместо one-hot.
Частые ошибки
1. One-hot на high cardinality
10 000 категорий → 10 000 колонок. Разрыв памяти.
2. Не сохранить encoder
Обучили encoder на train, забыли сохранить. В проде новое значение не закодируется тем же способом.
3. Label encoding для линейных моделей
Модель решит, что Moscow < SPb < Kazan. Лучше one-hot.
4. Target encoding без CV
Утечка таргета: среднее включает саму строку. Нужен leave-one-out или обучение encoder только на train-фолде.
Связанные темы
- Overfitting простыми словами
- Что такое clustering
- Data leakage простыми словами
- Нормализация данных простыми словами
FAQ
Sparse matrix?
Для big data — да, memory-efficient. В sklearn sparse_output=True.
Drop first обязательно?
Для linear — рекомендуется. Tree-based — по желанию.
Категория встречается 2 раза — удалять?
Обычно удаляют или заменяют на «Other», если cardinality большая.
Какой pipeline в sklearn?
ColumnTransformer для разных типов колонок + OneHotEncoder.