One-Hot Encoding простыми словами

Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.

Зачем это знать

ML-модели работают с числами, не с категориями. Если у вас колонка city с значениями ['Moscow', 'SPb', 'Kazan'], модель не поймёт их напрямую. Нужно закодировать в числа. Способов кодирования — несколько, и от выбора зависит performance модели.

One-hot encoding — самый распространённый способ. На собеседовании DS/ML вас обязательно спросят: «как закодируете категориальную переменную», «что такое one-hot», «когда использовать target encoding». Без этих знаний — середняк уровень.

В статье — полное понимание:

  • Что такое one-hot на примере
  • Плюсы и минусы
  • Альтернативы: label encoding, target encoding, binary encoding
  • Когда какое применять
  • Practical в 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).

Зачем: избежать multicollinearity в линейных моделях. Для tree-based моделей (Random Forest, XGBoost) не обязательно.

Когда one-hot работает хорошо

  • Небольшое количество категорий (2-20)
  • Категории без порядка (номинальные)
  • Модель линейная или tree-based

Когда one-hot работает плохо

  • Много уникальных значений (сотни городов)
  • Большие dataset (размер взрывается)
  • Redundant для 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? Для linear моделей плохо.

Для tree-based — ок, модель игнорирует порядок.

2. Target Encoding

Заменяет категорию на среднее значение target по этой категории:

Moscow → 0.15 (avg conversion)
SPb →    0.12
Kazan →  0.08
# manual
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

Заменяет на frequency появления:

Moscow (1000 раз) → 1000 / 10000 = 0.1
SPb (500) → 0.05

Когда какое использовать

Cardinality Model Выбор
Low (2-10) любая One-Hot
Medium (10-50) tree-based Label или One-Hot
Medium linear One-Hot
High (50+) любая Target / Frequency
Very high (1000+) любая Embeddings (deep learning)

Handling unseen categories

Проблема: в 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 колонок. Memory explosion.

2. Не сохранить encoder

Обучили encoder на train, забыли save. В prod новая инструкция не закодируется.

3. Label encoding для linear

Модель решит, что Moscow < SPb < Kazan. Лучше one-hot.

4. Target encoding без CV

Target leakage: среднее target включает саму строку. Нужен specific leave-one-out подход.

Связанные темы

FAQ

Sparse matrix?

Для big data — да, memory-efficient. В sklearn sparse_output=True.

Drop first обязательно?

Для linear — рекомендуется. Tree-based — по желанию.

Категория встречается 2 раза — удалять?

Обычно удаляют или заменяют на «Other», если cardinality большая.

Какой pipeline в sklearn?

ColumnTransformer для разных типов колонок + OneHotEncoder.


Тренируйте ML — откройте тренажёр с 1500+ вопросами для собесов.