Перейти к основному содержимому

Обработка категориальных признаков

Категориальные признаки (categorical features) - это признаки, принимающие дискретные значения, такие как профессия человека или город, в котором он родился. Такие признаки очень часто встречаются на практике. Частным случаем категориальных признаков являются бинарные признаки (binary features), принимающие всего два значения, такие как семейное положение человека или индикатор, были ли у человека просрочки по кредитам.

Модель машинного обучения ожидает на входе вектор, состоящий только из вещественных признаков. Если бинарный признак мы можем представить в вещественном виде, закодировав категории цифрами 0 и 1, то в случае признака, описывающего несколько категорий, возможны различные варианты кодировок.

Порядковое кодирование

В порядковом кодировании (ordinal encoding) категория заменяется её номером. Рассмотрим кодировку признака [профессия]. Пусть, для простоты она принимает всего 4 возможных значения: программист, художник, дизайнер и системный администратор. В порядковом кодировании мы заменяем профессии их номерами:

значениеномер
программист0
художник1
дизайнер2
системный администратор3

Этот вид кодирования не рекомендуется на практике, поскольку метод машинного обучения впоследствии будет считать, что движение в направлении 0,1,2,3 будет соответствовать возрастанию какой-то реально существующей характеристики, которой в действительности нет, поскольку нумерация была произвольной. Также в нашем примере метод машинного обучения, на основе близости численных значений будет считать, что программист ближе по смыслу к художнику, чем к системному администратору, что в действительности не так.

Кодирование частотами

При частотном кодировании (frequency encoding) значение каждой категории заменяется на частоту встречаемости этой категории. Если, например, у нас 7 человек, среди которых программист встретился 2 раза, системный администратор - 3 раза, дизайнер и художник - по одному разу, то частотное кодирование будет выглядеть так:

значениекодировка
программист2/7
системный администратор3/7
системный администратор3/7
дизайнер1/7
художник1/7
системный администратор3/7
программист2/7

Обратим внимание, что кодирование неоднозначное для дизайнера и художника, которые встретились одинаковое число раз. Полезность кодировки определяется тем, насколько частота встречаемости категорий связана с целевой переменной.

One-hot кодирование

One-hot кодирование (one-hot encoding, dummy encoding). Вначале все категории нумеруются (произвольным образом). Каждый категориальный признак, принимающий значение i-й категории среди K возможных, кодируется K-мерным вектором из нулей, где на одной только i-й позиции стоит единица.

Пример соответствия категорий кодировкам:

направлениекодировка
север[0,0,0,1]
юг[0,0,1,0]
восток[0,1,0,0]
запад[1,0,0,0]

Пример применения кодировки к данным:

направлениекодировка
север[0,0,0,1]
север[0,0,0,1]
запад[1,0,0,0]
восток[0,1,0,0]
север[0,0,0,1]

Метод однозначно кодирует категорию и, в отличие от предыдущих методов, производит сопоставление одному категориальному признаку сразу набор бинарных признаков (по числу категорий). Категории, независимо от порядка кодирования, все получаются равнозначными - попарное расстояние между кодировками любой пары категорий получается одним и тем же.

One-hot кодирование - самый популярный способ представления категориальных признаков, однако у него есть недостаток, что при слишком большом числе категорий он приводит к сильному разрастанию числа признаков. Например, если категория - это город, то поскольку городов очень много, число признаков значительно увеличивается, что приводит к слишком сильному увеличению параметров модели машинного обучения, ухудшая её настройку. Одним из способов борьбы с этим является объединение различных родственных категорий в одну. Например, вместо указания города можно указывать область, в которой этот город находится.

Эмбеддинги

Представление определённой дискретной сущности (например, категории в категориальном признаке) вектором вещественных чисел называется эмбеддингом (embedding). One-hot кодирование приводит к слишком длинному вектору, если число категорий велико. Вместе с этим понятно, что если использовать не только значения 0/1, а весь спектр вещественных чисел, то можно даже большое число категорий однозначно закодировать компактным вектором эмбеддинга. Эмбеддинги можно сэмплировать случайно, при этом желательно при этом обеспечивать одинаковое попарное расстояние между эмбеддингами разных категорий. Или генерировать эмбеддинги так, чтобы расстояние между эмбеддингами оказывалось более близким для более близких категорий по смыслу (например, работа программиста более близка к работе системного администратора, а работа художника - к работе дизайнера, поэтому и соответствующие эмбеддинги должны быть ближе). Существуют продвинутые методы автоматической генерации эмбеддингов, о которых можно прочитать, например, в статье А.Г.Дьяконова "Методы решения задач классификации с категориальными признаками".

Кодирование средним

Кодирование средним (mean encoding, target encoding) - компактный и максимально информативный способ кодирования категориального признака путём замены каждой категории на среднее прогнозируемого отклика при условии этой категории.

Пример для регрессии (например, когда по профессии и другим признакам пытаемся предсказать зарплату):

признак (профессия)откликкодирование признака
программист300350
системный администратор250200
системный администратор200200
дизайнер220200
художник150150
дизайнер180200
программист400350
системный администратор150200

Пример для классификации (например, когда по профессии и другим признакам пытаемся предсказать вернёт человек кредит или нет):

признак (профессия)откликкодирование признака
программист11
системный администратор12/3
системный администратор02/3
дизайнер11/2
художник00
дизайнер01/2
программист11
системный администратор12/3

Такой способ кодирования не приводит к разрастанию признакового пространства. Как видим, для регрессии и бинарной классификации один столбец исходного признака заменяется на один столбец условных средних. В случае многоклассовой классификации каждая категория будет заменяться на вектор условных частот каждого из классов (при условии категории). Такой способ кодирования максимально информативен для решения итоговой задачи предсказания отклика по кодировке, поскольку кодировка в явном виде агрегирует информацию об отклике.

Переобучение

Свойство кодирования отклика в признаке приводит к переобучению, поскольку мы через признак явно сообщаем информацию об ожидаемом отклике, пусть и в усреднённом виде. Для категорий, которые встретились единожды ("художник" в нашем примере) мы вообще явно перенесли отклик в признак. Получается, мы решаем нечестную задачу, поскольку сообщаем модели информацию об ожидаемом отклике (которую она не должна знать). Для тестовых объектов такой информации у нас уже не будет. Поэтому, чтобы избежать переобучения и сделать прогнозы честными, нужно выделить отдельную обучающую выборку на кодирование средним только по ней, а потом перенести вычисленное соответствие категорий средним откликам в основную обучающую выборку, по которой уже будем настраивать модель.

Более эффективный способ с точки зрения переиспользования данных - для каждого объекта подставлять вместо категории условное среднее отклика по всем объектам кроме рассматриваемого (leave one out encoding)

Вариант метода

Вместо каждой категории можно подставлять условное среднее по другому вещественному или бинарному признаку. Такое кодирование не приводит к подглядыванию в неизвестный отклик, поэтому для него не нужна отдельная выборка для кодировки. Вместо среднего значения при условии каждой категории можно подставлять условную медиану, максимум, минимум и стандартное отклонение в зависимости от задачи.


Кодирование циклических переменных

Циклическое кодирование (cyclic encoding) применяется для кодирования категориальных переменных, принимающих циклические значения, такие как час в сутках, номер недели, день месяца и т.д. В этих случаях существует естественный порядок на значениях.

Например, час в сутках принимает значения 0,1,2,3,...22,23. За счёт вещественного представления часа в сутках удаётся передать модели, что соседние часы близки, а дальние - далеки, что сделает зависимость от часа дня более плавной. При этом необходимо учесть, что, в силу цикличности, час 23 близок к нулевому часу.

Моделировать такие виды близости можно с помощью циклического кодирования, при котором признак u[0,max(u))u\in [0,\max(u)) кодируется парой вещественных значений:

u[sin(2πumax(u));cos(2πumax(u))]u \longrightarrow \left[\sin\left(\frac{2\pi\cdot u}{\max(u)}\right);\cos\left(\frac{2\pi\cdot u}{\max(u)}\right)\right]

Поскольку sin()иcos()\sin() и \cos() - непрерывные функции, то такое представление для близких значений uu и uu' будет выдавать близкие кодировки. При этом нулевое значение признака будет близко к максимальному, поскольку указанные синус и косинус будут иметь период величиной max(u)\max(u), как показано на рисунке ниже при кодировании часа синусом:

Какую кодировку использовать?

Конечный вид кодировки подбирается методом проб и ошибок и в конечном счете определяется тем, какой из них будет приводить к более точным прогнозам. Можно кодировать категориальный признак сразу несколькими способами!