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

Кодирование категорий

Модели машинного обучения работают с числами. Но в таблицах часто встречаются строковые признаки: отдел, город, пол, категория товара, тип ремонта.

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

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

OrdinalEncoder — преобразователь категориальных признаков. Он заменяет каждую категорию числом, запоминает соответствие между категориями и кодами и использует его при последующих преобразованиях данных.

Ниже показан пример со столбцом Отдел: именно он затем приводится в полном коде.

OrdinalEncoder преобразует столбец Отдел в числовые коды

В этом примере категории получают коды:

IT -> 0
Продажи -> 1
HR -> 2

Пример:

uses MLABC;
begin
var df := DataFrame.FromCsvText('''
Имя,Отдел,Возраст
Анна,IT,28
Борис,Продажи,35
Вера,HR,31
Глеб,IT,29
''',
categoricalColumns := ['Отдел']);
var encoder := new OrdinalEncoder('Отдел');
var encoded := encoder.FitTransform(df);
encoded.Print;
end.

Вывод:

Имя Отдел Возраст
Анна 0 28
Борис 1 35
Вера 2 31
Глеб 0 29

Такое кодирование простое и компактное. Но у него есть важный недостаток: некоторые модели могут воспринять числа как порядок, хотя между категориями IT, Продажи и HR настоящего порядка нет.

OneHotEncoder — другой преобразователь категориальных признаков. Он создаёт отдельный числовой столбец для каждой категории: значение 1 означает наличие категории, а 0 — её отсутствие.

OneHotEncoder превращает категориальный столбец в бинарные признаки

Например, столбец Отдел превращается в несколько признаков:

Отдел_IT Отдел_Продажи Отдел_HR
1 0 0
0 1 0
0 0 1

Каждый новый столбец отвечает на вопрос: “строка относится к этой категории или нет?” Поэтому здесь нет ложного порядка между категориями.

uses MLABC;
begin
var df := DataFrame.FromCsvText('''
Имя,Отдел,Возраст
Анна,IT,28
Борис,Продажи,35
Вера,HR,31
Глеб,IT,29
''',
categoricalColumns := ['Отдел']);
var encoder := new OneHotEncoder('Отдел');
var encoded := encoder.FitTransform(df);
encoded.Print;
end.

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

Кодировщик сначала запоминает, какие категории встречаются в данных, а потом применяет это правило к таблице.

Короткая запись:

var encoded := encoder.FitTransform(df);

То же самое в два шага:

encoder.Fit(df);
var encoded := encoder.Transform(df);

Разделение на Fit и Transform важно, когда одно и то же правило нужно применить к нескольким таблицам.

  • OrdinalEncoder создаёт один числовой столбец вместо строкового.
  • OneHotEncoder создаёт несколько столбцов с признаками “да/нет”.
  • Если категорий мало и между ними нет естественного порядка, чаще лучше OneHotEncoder.
  • Если категорий много, OneHotEncoder может сильно увеличить число столбцов. В таких случаях используют OrdinalEncoder или заранее укрупняют редкие категории.
  • Если у категорий есть естественный порядок, обычно подходит OrdinalEncoder.
  • Для деревьев решений часто допустим OrdinalEncoder.
  • Для линейных моделей и методов, основанных на расстояниях, чаще лучше OneHotEncoder.

Примеры:

  • Пол, Тип оплаты, Отдел — категорий мало, порядка нет; обычно подходит OneHotEncoder.
  • Город, Товар, Артикул — категорий может быть много; OneHotEncoder создаст слишком много столбцов.
  • Низкий, Средний, Высокий — есть естественный порядок; можно использовать OrdinalEncoder.

OrdinalEncoder и OneHotEncoder используются для признаков, то есть столбцов, по которым модель делает предсказание.

Целевой столбец — правильные ответы для обучения модели — кодируется отдельно с помощью метода EncodeTarget. Например, это используется в разделе Быстрый старт, где модель учится определять вид ириса.