Почему категориальный признак нельзя просто передать модели как слово
Для человека категория вроде `city = 'spb'` понятна мгновенно. Для модели это просто строка, с которой она не знает, что делать. Именно поэтому категориальные признаки нужно превращать в числовое представление. One-hot encoding — самый известный и самый прозрачный способ это сделать. Он не пытается придумать сложную статистику по категории. Он просто превращает каждый возможный вариант в отдельный бинарный столбец.
У этого подхода есть важное достоинство: модель больше не путает категорию с порядком. Если мы бы просто присвоили `spb=1`, `msk=2`, `ekb=3`, часть алгоритмов начала бы воспринимать это как шкалу, хотя никакого реального «расстояния» между такими кодами нет.
Как выглядит идея one-hot encoding
$$ x_{cat} \in \{0,1\}^K $$Категориальное значение превращается в вектор длины K, где единица стоит только на позиции соответствующей категории, а остальные координаты равны нулю.
x_{cat}— векторное представление одной категории\{0,1\}— бинарные значения, из которых строится кодировкаK— число уникальных категорий в признаке
Это и есть главный смысл метода. Вместо одного текстового столбца мы получаем набор бинарных индикаторов. Для линейной модели это очень удобно: вес каждого такого столбца можно интерпретировать как вклад конкретной категории.
Где one-hot encoding хорош, а где начинает вредить
Он хорош на умеренном числе категорий и в ситуациях, где нужна прозрачность. Если категорий десятки, one-hot обычно работает спокойно. Но если их тысячи или десятки тысяч, пространство признаков резко разрастается. Матрица становится очень разреженной, обучение может замедляться, а часть категорий встречается слишком редко, чтобы модель успела что-то про них понять. В таких случаях начинают думать про target encoding, hashing, embeddings или модели, которые умеют работать с категориями иначе.
То есть one-hot encoding — не устаревший прием, а базовый инструмент, который особенно хорош, пока размерность и число редких категорий остаются под контролем.
Как это делается в Python
import pandas as pd # создаем небольшой пример с категориальным и числовым признаком
from sklearn.preprocessing import OneHotEncoder # используем классическую кодировку категорий
frame = pd.DataFrame({ # задаем входные признаки
'city': ['spb', 'msk', 'ekb', 'spb'], # категориальный признак города
'sessions': [3, 5, 2, 4], # числовой признак активности
})
encoder = OneHotEncoder(sparse_output=False, handle_unknown='ignore') # кодируем категории в плотную матрицу и игнорируем новые значения
encoded = encoder.fit_transform(frame[['city']]) # превращаем столбец city в набор бинарных индикаторов
encoded_frame = pd.DataFrame(encoded, columns=encoder.get_feature_names_out(['city'])) # собираем удобную таблицу с именами новых признаков
result = pd.concat([frame[['sessions']].reset_index(drop=True), encoded_frame], axis=1) # объединяем числовой признак и one-hot колонки
print(result) # смотрим финальную матрицу признаков после кодированияПолезнее всего здесь увидеть не синтаксис, а саму идею: мы не «считаем что-то по категории», а даем модели корректное бинарное представление, в котором нет ложного порядка.