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

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

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

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

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 работает иначе: он создаёт отдельный столбец для каждой категории.

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 используются для признаков, то есть столбцов, по которым модель делает предсказание.

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