Найти в Дзене

Самое простое объяснение подготовки (кодирования) данных для моделей машинного обучения.

Начнем с небольшого экскурса. Чтобы вы понимали суть добавляю небольшой словарик: В целом, это всё что вам следует знать для понимания текста ниже. Чекаем информацию в данных и можем начинать. Сделаем небольшой вывод: В таблице 309864 объекта и 11 признаков, из которых 6 признаков типа object, в признаках нет пропусков, что уже хорошо, но в дальнейшем нам надо будет поработать над таблицей, чтобы все признаки были количественными. ВАЖНО! Я советую делать манипуляции по кодированию после того как вы разбили данные на на выборки. ПРИЧИНА! Кодирование переменных до разделения на обучающий и тестовый наборы может привести к "утечке данных". Это происходит потому, что кодирование во всем наборе данных, включая тестовый набор, может позволить модели запомнить целевые значения в тестовом наборе, которые не являются репрезентативными для реальных данных, с которыми модель еще не сталкивалась. Это может привести к чрезмерной подгонке и дать слишком оптимистичную оценку эффективности модели. Ва
Оглавление

Начнем с небольшого экскурса. Чтобы вы понимали суть добавляю небольшой словарик:

  • Признаки - столбцы в таблице.
  • Целевой признак - столбец, значения которого надо предсказать.
  • Объекты - строки в таблице

В целом, это всё что вам следует знать для понимания текста ниже.

Осмотр данных

Чекаем информацию в данных и можем начинать.

Базовый осмотр таблицы
Базовый осмотр таблицы
Информация о таблице
Информация о таблице

Сделаем небольшой вывод: В таблице 309864 объекта и 11 признаков, из которых 6 признаков типа object, в признаках нет пропусков, что уже хорошо, но в дальнейшем нам надо будет поработать над таблицей, чтобы все признаки были количественными.

ВАЖНО! Я советую делать манипуляции по кодированию после того как вы разбили данные на на выборки. ПРИЧИНА! Кодирование переменных до разделения на обучающий и тестовый наборы может привести к "утечке данных". Это происходит потому, что кодирование во всем наборе данных, включая тестовый набор, может позволить модели запомнить целевые значения в тестовом наборе, которые не являются репрезентативными для реальных данных, с которыми модель еще не сталкивалась. Это может привести к чрезмерной подгонке и дать слишком оптимистичную оценку эффективности модели. Важно сначала разделить данные на обучающий и тестовый наборы, а затем выполнить кодирование, чтобы предотвратить утечку данных.

Вот тут и начинается теория о том, что можно сделать с данными, чтобы их подготовить для модели машинного обучения (Дальше буду говорить просто - "модель")

Теория "Подготовка категориальных признаков"

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

Первое - Прямое кодирование (One-Hot Encoding, OHE).

Этапы работы:

  1. Мы передаем прямому кодированию категориальный признак через pd.get_dummies()
  2. Прямое кодирование берет все уникальные значения признака
  3. Каждое уникальное значение становиться отдельным признаком (столбцом), где в каждом объекте (строке), если было написано это уникальное значение, то ставиться 1, а если там было написано другое уникальное значение то 0.

Покажу на картинке как было и как стало, где появился 0, а где 1:

Дамми изменение.
Дамми изменение.

Код который реализовал вторую таблицу, которая теперь называется gearbox_ohe:

gearbox_ohe = pd.get_dummies(df['Gearbox']).astype('int')
gearbox_ohe = pd.concat([df, gearbox_ohe], axis=1).drop('Gearbox', axis=1)

Как видите вместо одного столбца появилось 2, потому что там было 2 уникальных значения: auto и manual. Но что нам делать если уникальных значений 50, 100, 300 или более, как например в столбце model.

Количество уникальных значений в столбце Model
Количество уникальных значений в столбце Model

Мы конечно обучить модель на большом количестве признаков, но это будет слишком ресурснозатратно. Надо придумать что - нибудь другое.

Второй вариант - Порядковое кодирование.

Тут надо запариться с кодом и вызвать еще одну библиотеку, но структура библиотеки настолько проста, что если вы выучите одну функцию, то дальше будет проще.

Работает порядковое кодирование просто:

  1. Оно смотрит на данные столбца;
  2. Присваивает каждому уникальному значению свой номер от 0 до n-1 (то есть, если уникальных значений 247, то диапазон будет от 0 до 246);
  3. Превращает столбец в набор чисел.

Давайте реализуем:

Применение OrdinalEncoder
Применение OrdinalEncoder

Так, ну у нас появилась проблема, OrdinalEncoder перевел всё в тип float при этом изменил целевой признак, на это не подходит, давайте доработаем.

Доработанный OrdinalEncoder
Доработанный OrdinalEncoder

Уже не плохо, правда OrdinalEncoder работает не по значимости признака, а по номеру символа, это значит, что все бренды отсортировались по алфавиту и только после этого ему будут давать номер. А что если у нас есть две категории Peugeot и Porsche. Для нас Porsche выше по приоритету, чем Peugeot, но OrdinalEncoder присваивает Porsche один (1), а Peugeot - ноль (0). хотя надо наоборот. В целом это больше проблема для линейных моделей.

Третий вариант - Собственное кодирование

Вообще когда много категорий (>10), можно написать собственный класс кодирования или же просто использовать функции. Я написал в виде класса и вот что у меня получилось.

Собственный Encoder
Собственный Encoder

Конечно он не идеален, но он уже может обрабатывать ваши столбцы по одному и возвращать обработанные. Тоже самое я сделал для столбца "Brand", теперь там обработанные значения. Вот небольшой отчет по итогу наших манипуляций:

Отчет после my_encoder
Отчет после my_encoder

Только не путайте volkswagen это необязательно число 0.308056, а jeep это не 1.222350. Мой способ является необратимым, то есть точно понять что содержала строка изначально понять нельзя. А вот One-Hot является обратимым, то есть вы сможете восстановить исходные данные.

Так закреплю сюда табличку, по данным с плюсами и минусами методов кодирования, которые использовал выше.

Сравнительная характеристика способов кодирования данных.
Сравнительная характеристика способов кодирования данных.

* Для OrdinalEncoder обратимость возможна только если сохранен .categories_

Особенности вашего метода:

  1. Хэширование:
    Преобразует любые данные (не только строки) в числа
    Теоретически возможны коллизии (разные строки → одинаковый хэш)
    Нет сохранения исходного словаря
  2. Нормализация:
    Автоматически масштабирует значения к μ=0, σ=1
    Полезно для алгоритмов, чувствительных к масштабу (SVM, нейросети)
  3. Гибкость:
    Работает с любыми типами данных (не только категориальными)
    Не требует предварительного обучения на всех значениях

Рекомендации по выбору:

  1. Для линейных моделей → One-Hot (но осторожно с размерностью)
  2. Для деревьев → OrdinalEncoder или ваш метод
  3. Для текста/больших категорий → Ваш метод (хэширование экономит память)
  4. Если важна интерпретируемость → One-Hot (можно отследить исходные значения)