Категориальные переменные — это распространенный тип данных, встречающийся в задачах машинного обучения. Эти переменные представляют категории или метки и часто не являются числовыми по своей природе. Правильная обработка категориальных переменных имеет решающее значение для построения эффективных моделей машинного обучения. В этом уроке мы рассмотрим различные методы и лучшие практики работы с категориальными переменными в ваших проектах машинного обучения.

Типы категориальных переменных

Категориальные переменные можно разделить на два основных типа:

  • Номинальные переменные. Эти переменные имеют категории без внутреннего порядка или ранжирования. Например, цвета или виды животных.
  • Порядковые переменные. Эти переменные имеют категории с определенным порядком или рейтингом. Например, уровни образования (Средняя школа ‹ Бакалавр ‹ Магистр ‹ Доктор философии).

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

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

По умолчанию OrdinalEncoder использует лексикографическую стратегию для сопоставления меток строковых категорий с целыми числами. Эта стратегия произвольна и часто бессмысленна. При работе с порядковыми категориальными переменными крайне важно поддерживать значимый порядок категорий в наборе данных. Класс OrdinalEncoder из scikit-learn принимает аргумент конструктора categories для явной передачи категорий в ожидаемом порядке, как показано ниже:

import pandas as pd
from sklearn.preprocessing import OrdinalEncoder

encoder = OrdinalEncoder(
    categories=[['salvage' , 'fair' , 'good' , 'excellent' , 'like new' , 'new'], 
                ['full-size' , 'mid-size' , 'compact', 'sub-compact']]
)
Car_data[['condition', 'size']] = encoder.fit_transform(Car_data[['condition', 'size']])

Кроме того, OrdinalEncoder в scikit-learn имеет несколько параметров, которые вы можете использовать для настройки его поведения, включая обработку неизвестных или новых значений и работу с редкими данными. Вот некоторые из ключевых параметров:

  1. categories: Этот параметр позволяет явно указать желаемый порядок категорий. Это должен быть список списков или «авто» (по умолчанию), чтобы автоматически определять категории по данным. Когда используется «авто», кодер определит уникальные категории в обучающих данных и назначит целые числа на основе лексикографического порядка.
  2. unknown_value: Если вы решите использовать собственное значение для неизвестных категорий, вы можете указать это значение с помощью этого параметра.
  3. handle_unknown: этот параметр определяет, как обрабатывать неизвестные или новые категории в тестовых или невидимых данных. Есть несколько вариантов:
  • 'use_encoded_value': он присваивает ранее невиданной категории значение, равное закодированному значению параметра unknown_value. Например, handle_unknown='use_encoded_value', unknown_value=-1 присвоит -1 неизвестным категориям.
  • 'error': Выдает ошибку, если во время преобразования встречается неизвестная категория.

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

Горячее кодирование

preprocessing.OneHotEncoder в scikit-learn используется для быстрого кодирования категориальных функций, обычно номинальных функций без внутреннего порядка. Ниже я объясню ключевые параметры класса OneHotEncoder:

  1. categories (по умолчанию='auto'): этот параметр позволяет явно указать категории. Вы можете передать список массивов, где каждый массив соответствует уникальным категориям для определенной функции. Если установлено значение «авто», кодер автоматически определит категории на основе данных.
  2. drop (по умолчанию = Нет): указывает, следует ли удалить одну из категорий, чтобы избежать мультиколлинеарности. Если установлено значение «первый», в каждой функции удаляется первая категория. Если установлено значение «if_binary», первая категория удаляется, если объект имеет только две категории. Если установлено значение «Нет», ни одна категория не удаляется.
  3. sparse (по умолчанию = True): определяет, следует ли возвращать после кодирования разреженную матрицу (True) или плотный массив (False). Разреженные матрицы эффективно используют память, что может быть полезно для категориальных функций с высокой мощностью.
  4. dtype (по умолчанию=‹класс 'numpy.float64'›): определяет тип выходных данных. Вы можете установить для него соответствующий тип данных в зависимости от вашего варианта использования и ограничений памяти.
  5. handle_unknown (по умолчанию='error'): определяет, как обрабатывать неизвестные категории, встречающиеся во время преобразования тестовых данных. Опции включают в себя:
  • 'error': Выдает ошибку, если встречается неизвестная категория.
  • 'ignore': Игнорирует неизвестные категории во время преобразования.
  • 'infrequent_if_exist': Если во время преобразования встречается неизвестная категория, результирующие столбцы с горячим кодированием для этого объекта будут сопоставляться с редко встречающейся категорией, если она существует. Эта опция была добавлена ​​в sklearn версии 1.1.

Вот пример использования некоторых из этих параметров:

from sklearn.preprocessing import OneHotEncoder

# Apply one-hot encoder to each column with categorical data
OH_encoder = OneHotEncoder(
    drop='first',
    sparse=False,
    dtype=int,
    handle_unknown='ignore'
)
OH_cols_train = pd.DataFrame(OH_encoder.fit_transform(X_train[low_cardinality_cols]))
OH_cols_valid = pd.DataFrame(OH_encoder.transform(X_valid[low_cardinality_cols]))

# One-hot encoding removed index; put it back
OH_cols_train.index = X_train.index
OH_cols_valid.index = X_valid.index

# Remove categorical columns (will replace with one-hot encoding)
num_X_train = X_train.drop(object_cols, axis=1)
num_X_valid = X_valid.drop(object_cols, axis=1)

# Add one-hot encoded columns to numerical features
OH_X_train = pd.concat([num_X_train, OH_cols_train], axis=1)
OH_X_valid = pd.concat([num_X_valid, OH_cols_valid], axis=1)

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

Целевая кодировка

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

Вот упрощенный пример использования scikit-learn для целевого кодирования:

import numpy as np
from sklearn.preprocessing import TargetEncoder

enc_auto = TargetEncoder(smooth="auto",target_type='continuous')

# The target variable is the price
target = Car_data['price']

# The features are the model and manufacturer
features = Car_data[['model', 'manufacturer']]

X_trans[['model', 'manufacturer']] = pd.DataFrame(enc_auto.fit_transform(features, target))
X_train = pd.concat([Car_data.drop(['model', 'manufacturer'], axis=1), X_trans], axis=1)

Хеширование кодирования

Хеш-кодирование, также известное как хеширование признаков или прием хеширования, — это метод, используемый для кодирования категориальных данных в числовые значения с помощью хэш-функции. Это эффективный с точки зрения использования памяти способ обработки категориальных переменных с высокой мощностью, особенно когда количество категорий велико. Scikit-learn имеет класс sklearn.feature_extraction.FeatureHasher. Вот как его использовать:

from sklearn.feature_extraction import FeatureHasher
import pandas as pd

# Create a sample DataFrame with a categorical column 'color'
data = {'color': ['red', 'green', 'blue', 'red', 'yellow']}
df = pd.DataFrame(data)

# Initialize the FeatureHasher with the desired number of hash bits
n_hash_bits = 8  # You can adjust this value as needed
hasher = FeatureHasher(n_features=n_hash_bits, input_type='string')

# Transform the categorical column 'color' using hashing
hashed_features = hasher.transform(df['color'])

# Convert the hashed features to a dense array or DataFrame
hashed_features_array = hashed_features.toarray()
hashed_df = pd.DataFrame(hashed_features_array, columns=[f'hash_{i}' for i in range(n_hash_bits)])

# Concatenate the original DataFrame with the hashed features
result_df = pd.concat([df, hashed_df], axis=1)
print(result_df)

Хеш-кодирование полезно для работы с категориальными переменными с высокой мощностью, поскольку оно уменьшает размерность данных, делая их более управляемыми, сохраняя при этом некоторую информацию об исходных категориях.

FeatureHasher присвоит хеш-значение любой новой категории, которая появится в наборе тестов. Это значение хеш-функции будет отличаться от значений хеш-функции известных категорий. Однако имейте в виду, что возможны коллизии хешей, а это означает, что разные категории могут иметь одно и то же значение. Регулировка количества хеш-битов может помочь контролировать компромисс между эффективностью памяти и риском коллизий.

Нечастые категории

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

В scikit-learn версии 1.3.0 при использовании порядкового или горячего кодирования вы можете обрабатывать нечастые категории двумя способами:

  • Агрегация. Редко встречающиеся категории можно объединить в одну категорию. Это делается путем установки для параметра min_frequency значения больше 1. Например, если min_frequency=5, то все категории с кардинальностью менее 5 будут агрегированы в одну категорию.
  • Исключение. Редко встречающиеся категории можно исключить из кодировки. Это делается путем установки параметра max_categories на значение, меньшее общего количества категорий. Например, если max_categories=10, то будут закодированы только 10 наиболее часто встречающихся категорий.

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

Заключение:

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