Преобразование категориальных данных: Практическое руководство по обработке нечисловых переменных для алгоритмов машинного обучения
В науке о данных существует несколько способов работы с категориальными данными, также известными как данные меток:
- Горячее кодирование
- Кодирование меток
- Фиктивное кодирование
- Биннинг
- Кодировка подсчета
- Частотное кодирование
- Целевое кодирование
Подходящий метод будет зависеть от конкретных данных и целей анализа. Важно отметить, что некоторые алгоритмы, такие как деревья решений и случайный лес, могут напрямую обрабатывать категориальные переменные, поэтому кодирование может не понадобиться.
Теперь мы рассмотрим все вышеперечисленные способы с некоторым набором образцов данных, а также узнаем, как сделать наши данные обучаемыми.
1. Горячее кодирование
Одноразовое кодирование - это метод, используемый для преобразования категориальных переменных в числовые значения путем создания двоичного столбца для каждой категории. Это полезно для обработки категориальных переменных с несколькими уровнями.
Например, предположим, что у нас есть набор данных сумок со столбцом под названием "color", который содержит следующие значения: "red", "green" и "blue".
| color | price | units |
| red | 500 | 2 |
| green | 800 | 3 |
| blue | 300 | 1 |
| red | 400 | 1 |
| green | 600 | 1 |
Однократное кодирование создало бы три новых двоичных столбца, по одному для каждой уникальной категории, со значением 1, указывающим на то, что категория присутствует, и значением 0, указывающим на то, что ее нет. Результирующие данные могут выглядеть следующим образом:
| color | price | units | color_red | color_green | color_blue |
| red | 500 | 2 | 1 | 0 | 0 |
| green | 800 | 3 | 0 | 1 | 0 |
| blue | 300 | 1 | 0 | 0 | 1 |
| red | 400 | 1 | 1 | 0 | 0 |
| green | 600 | 1 | 0 | 1 | 0 |
Как видите, исходный столбец «color» был заменен тремя новыми бинарными столбцами, по одному для каждой уникальной категории. Каждая строка теперь имеет значение 1 ровно в одном из этих новых столбцов, что указывает на наличие этой категории.
Но подождите, у вас должен быть один вопрос..... Как это сделать с помощью python? Итак, давайте сделаем это с помощью python.
В Python вы можете использовать функцию get_dummies() из библиотеки pandas, чтобы применить одноразовую кодировку к столбцу "color" вашего фрейма данных. Вот пример того, как это сделать:
import pandas as pd
# Create example dataframe
df = pd.DataFrame({'color': ['red', 'green', 'blue', 'red', 'green'],
'price': [500, 800, 300, 400, 600],
'units': [2, 3, 1, 1, 1]})
# Apply one-hot encoding to "color" column
df_encoded = pd.get_dummies(df, columns=['color'])
print(df_encoded)
В качестве альтернативы вы можете использовать класс OneHotEncoder из библиотеки sklearn.preprocessing для применения однократного кодирования.
from sklearn.preprocessing import OneHotEncoder
# Create example dataframe
df = pd.DataFrame({'color': ['red', 'green', 'blue', 'red', 'green'],
'price': [500, 800, 300, 400, 600],
'units': [2, 3, 1, 1, 1]})
# Create an instance of the encoder
encoder = OneHotEncoder(sparse=False)
# Fit and transform the "color" column
color_encoded = encoder.fit_transform(df[['color']])
# Create new dataframe with the encoded values
df_encoded = pd.concat([df.drop(columns=['color']), pd.DataFrame(color_encoded, columns=encoder.get_feature_names(['color']))], axis=1)
print(df_encoded)
Результирующий фрейм данных будет выглядеть так же, как и предыдущий, но столбцы будут иметь префикс 'color_x 0_', а не 'color'.
2. Кодирование меток
Кодирование меток — это метод, используемый для преобразования категориальных переменных в числовые значения путем присвоения каждой категории уникального целочисленного значения. Это полезно для обработки порядковых переменных, где важен порядок категорий.
Например, предположим, что у нас есть набор данных со столбцом под названием "size", который содержит следующие значения: "small", "medium", "large". Кодировка метки заменит каждую категорию целым числом, например: "small" = 0, "medium" = 1, "large" = 2. Результирующие данные могут выглядеть следующим образом:
| size | encoded_size |
| small | 0 |
| medium | 1 |
| large | 2 |
| small | 0 |
| medium | 1 |
Как вы можете видеть, исходный столбец "size" был заменен столбцом "encoded_size", каждая строка теперь имеет уникальное целочисленное значение, представляющее категорию.
Вы можете использовать класс LabelEncoder из библиотеки sklearn.preprocessing, чтобы применить кодировку меток к вашим данным. Вот пример того, как это сделать:
from sklearn.preprocessing import LabelEncoder
# Create example dataframe
df = pd.DataFrame({'size': ['small', 'medium', 'large', 'small', 'medium'],
'price': [500, 800, 300, 400, 600],
'units': [2, 3, 1, 1, 1]})
# Create an instance of the encoder
encoder = LabelEncoder()
# Fit and transform the "size" column
df['encoded_size'] = encoder.fit_transform(df['size'])
print(df)
Результирующий фрейм данных, df, будет иметь новый столбец "encoded_size", представляющий закодированные значения столбца size. Результирующий фрейм данных будет выглядеть следующим образом:
| size | price | units | encoded_size |
| small | 500 | 2 | 0 |
| medium | 800 | 3 | 1 |
| large | 300 | 1 | 2 |
| small | 400 | 1 | 0 |
| medium | 600 | 1 | 1 |
Важно отметить, что кодировка меток изменяет взаимосвязь между категориями. Он присваивает каждой категории уникальный номер, но не учитывает порядковые отношения между категориями. В этом случае закодированные значения "small", "medium" и "large" равны 0, 1 и 2 соответственно, но это не означает, что small вдвое меньше medium или large вдвое больше medium.
3. Фиктивное кодирование
Фиктивное кодирование, также известное как индикаторное кодирование, — это метод, используемый для преобразования категориальных переменных в числовые значения путем создания двоичных столбцов для каждой категории, аналогично горячему кодированию, но при этом не удаляется ни один столбец. Это полезно при работе с категориальными переменными со многими уровнями.
Например, предположим, что у нас есть набор данных со столбцом под названием "color", который содержит следующие значения: "red", "green", "blue". Фиктивное кодирование создало бы три новых двоичных столбца, по одному для каждой уникальной категории, со значением 1, указывающим на то, что категория присутствует, и значением 0, указывающим на то, что ее нет. Результирующие данные могут выглядеть следующим образом:
| color | red | green | blue |
| red | 1 | 0 | 0 |
| green | 0 | 1 | 0 |
| blue | 0 | 0 | 1 |
| red | 1 | 0 | 0 |
| green | 0 | 1 | 0 |
Как вы можете видеть, исходный столбец "color" все еще присутствует в таблице, но были добавлены три новых двоичных столбца, по одному для каждой уникальной категории. Каждая строка теперь имеет значение 1 ровно в одном из этих новых столбцов, что указывает на наличие этой категории.
Вы можете использовать функцию pd.concat() из библиотеки pandas, чтобы применить фиктивную кодировку к столбцу "color" вашего фрейма данных, вот пример того, как это сделать:
# Create example dataframe
df = pd.DataFrame({'color': ['red', 'green', 'blue', 'red', 'green'],
'price': [500, 800, 300, 400, 600],
'units': [2, 3, 1, 1, 1]})
# Apply dummy encoding to "color" column
df_encoded = pd.concat([df, pd.get_dummies(df['color'])], axis=1)
print(df_encoded)
Результирующий фрейм данных df_encoded будет содержать три новых двоичных столбца, по одному для каждой уникальной категории в столбце "color", со значением 1, указывающим на наличие категории, и значением 0, указывающим на ее отсутствие. Исходный столбец "color" все еще присутствует в таблице. Результирующий фрейм данных будет выглядеть следующим образом:
| color | price | units | red | green | blue |
| red | 500 | 2 | 1 | 0 | 0 |
| green | 800 | 3 | 0 | 1 | 0 |
| blue | 300 | 1 | 0 | 0 | 1 |
| red | 400 | 1 | 1 | 0 | 0 |
| green | 600 | 1 | 0 | 1 | 0 |
4. Биннинг
Биннинг — это метод, используемый для группировки числовых значений в ячейки или диапазоны, он используется для обработки числовых переменных с большим количеством уникальных значений. Биннинг может быть полезен для создания категориальных переменных из числовых и для обработки выбросов в данных.
Например, предположим, что у нас есть набор данных со столбцом под названием "age", который содержит следующие значения: 18, 20, 25, 30, 35, 40, 45. Чтобы применить привязку, мы можем разделить диапазон значений на заранее определенное количество интервалов или ячеек. Например, мы можем разделить диапазон возрастов на четыре ячейки: (18, 25], (25, 35], (35, 45], (45, 50]. Это позволило бы сгруппировать возрасты по четырем категориям: "young", "middle-aged", "old" и "very old". Результирующие данные могут выглядеть следующим образом:
| age | age_bin |
| 18 | young |
| 20 | young |
| 25 | middle-aged |
| 30 | middle-aged |
| 35 | old |
| 40 | old |
| 45 | very old |
Как видите, исходный столбец «age» по-прежнему присутствует в таблице, но был добавлен новый столбец «age_bin», который содержит объединенные значения для каждого возраста. Строки в столбце «age_bin» теперь содержат категориальные значения, представляющие возрастную группу.
Вы можете использовать функцию cut() из библиотеки pandas, чтобы применить привязку к столбцу "возраст" вашего фрейма данных, вот пример того, как это сделать:
# Create example dataframe
df = pd.DataFrame({'age': [18, 20, 25, 30, 35, 40, 45],
'price': [500, 800, 300, 400, 600, 700, 800],
'units': [2, 3, 1, 1, 1, 2, 3]})
# Apply binning to "age" column
df['age_bin'] = pd.cut(df['age'], bins=[18, 25, 35, 45, 50], labels=['young', 'middle-aged', 'old', 'very old'])
print(df)
Результирующий фрейм данных df будет иметь новый столбец «age_bin», представляющий объединенные значения столбца age. Результирующий фрейм данных будет выглядеть так:
| age | price | units | age_bin |
| 18 | 500 | 2 | young |
| 20 | 800 | 3 | young |
| 25 | 300 | 1 | middle-aged |
| 30 | 400 | 1 | middle-aged |
| 35 | 600 | 1 | old |
| 40 | 700 | 2 | old |
| 45 | 800 | 3 | very old |
Как видите, исходный столбец «age» по-прежнему присутствует в таблице, но был добавлен новый столбец «age_bin», который содержит объединенные значения для каждого возраста. Строки в столбце «age_bin» теперь содержат категориальные значения, представляющие возрастную группу.
5. Кодирование счета
Кодирование количества - это метод, используемый для преобразования категориальных переменных в числовые значения путем подсчета количества вхождений каждой категории в наборе данных. Он используется для обработки категориальных переменных со многими уровнями.
Например, предположим, что у нас есть набор данных со столбцом под названием "product", который содержит следующие значения: "apple", "orange", "banana", "apple", "orange", "apple", "banana". Кодировка Count заменит каждую категорию количеством раз, когда она появляется в наборе данных. Результирующие данные могут выглядеть следующим образом:
| product | count_encoded |
| apple | 3 |
| orange | 2 |
| banana | 2 |
| apple | 3 |
| orange | 2 |
| apple | 3 |
| banana | 2 |
Как вы можете видеть, исходный столбец "product" все еще присутствует в таблице, но был добавлен новый столбец "count_encoded", который содержит значения в кодировке count для каждого продукта. Строки в столбце "count_encoded" теперь содержат уникальные целочисленные значения, представляющие количество раз, когда каждый продукт появляется в наборе данных.
Вы можете использовать функцию value_counts() из библиотеки pandas, чтобы применить кодировку count к столбцу "product" вашего фрейма данных, вот пример того, как это сделать:
# Create example dataframe
df = pd.DataFrame({'product': ['apple', 'orange', 'banana', 'apple', 'orange', 'apple', 'banana'],
'price': [500, 800, 300, 400, 600, 700, 800],
'units': [2, 3, 1, 1, 1, 2, 3]})
# Apply count encoding to "product" column
df['count_encoded'] = df['product'].map(df['product'].value_counts())
print(df)
Результирующий кадр данных, df, будет иметь новый столбец «count_encoded», представляющий закодированные значения счетчика столбца продукта. Результирующий фрейм данных будет выглядеть так:
| product | price | units | count_encoded |
| apple | 500 | 2 | 3 |
| orange | 800 | 3 | 2 |
| banana | 300 | 1 | 2 |
| apple | 400 | 1 | 3 |
| orange | 600 | 1 | 2 |
| apple | 700 | 2 | 3 |
| banana | 800 | 3 | 2 |
6. Частотное кодирование
Частотное кодирование - это метод, используемый для преобразования категориальных переменных в числовые значения путем представления каждой категории как доли встречаемости этой категории в наборе данных. Это похоже на кодировку count, но она нормализует количество путем деления его на общее количество вхождений всех категорий в наборе данных. Он используется для обработки категориальных переменных со многими уровнями.
Например, допустим, у нас есть набор данных со столбцом под названием «product», который содержит следующие значения: «apple», «orange», «banana», «apple», «orange», «apple», «banana». Частотное кодирование заменит каждую категорию количеством раз, которое она появляется в наборе данных. Полученные данные могут выглядеть следующим образом:
| product | frequency_encoded |
| apple | 0.429 |
| orange | 0.286 |
| banana | 0.286 |
| apple | 0.429 |
| orange | 0.286 |
| apple | 0.429 |
| banana | 0.286 |
Как вы можете видеть, исходный столбец "product" все еще присутствует в таблице, но был добавлен новый столбец "frequency_encoded", который содержит значения в кодировке частоты для каждого продукта. Строки в столбце "frequency_encoded" теперь содержат десятичные значения от 0 до 1, представляющие долю случаев появления каждого продукта в наборе данных.
Вы можете использовать функцию value_counts() из библиотеки pandas, чтобы применить частотное кодирование к столбцу "product" вашего фрейма данных, вот пример того, как это сделать:
# Create example dataframe
df = pd.DataFrame({'product': ['apple', 'orange', 'banana', 'apple', 'orange', 'apple', 'banana'],
'price': [500, 800, 300, 400, 600, 700, 800],
'units': [2, 3, 1, 1, 1, 2, 3]})
# Apply frequency encoding to "product" column
df['frequency_encoded'] = df['product'].map(df['product'].value_counts(normalize=True))
print(df)
Результирующий кадр данных df будет иметь новый столбец «frequency_encoded», представляющий частотно-кодированные значения столбца продукта. Результирующий фрейм данных будет выглядеть так:
| product | price | units | frequency_encoded |
| apple | 500 | 2 | 0.428571 |
| orange | 800 | 3 | 0.285714 |
| banana | 300 | 1 | 0.285714 |
| apple | 400 | 1 | 0.428571 |
| orange | 600 | 1 | 0.285714 |
| apple | 700 | 2 | 0.428571 |
| banana | 800 | 3 | 0.285714 |
7. Целевое кодирование
Целевое кодирование - это метод, используемый для преобразования категориальных переменных в числовые значения путем представления каждой категории как среднего значения целевой переменной для этой категории. Этот метод используется, когда категориальная переменная имеет большое количество уровней, а также полезен в ситуациях, когда данные сильно несбалансированы.
Например, предположим, что у нас есть набор данных со столбцом под названием «product» и целевой переменной под названием «sales», которая содержит следующие значения:
| product | sales |
| apple | 100 |
| orange | 200 |
| banana | 50 |
| apple | 150 |
| orange | 300 |
| apple | 50 |
| banana | 20 |
Целевая кодировка заменила бы каждую категорию в столбце "product" средним значением столбца "sales" для этой категории. Результирующие данные могут выглядеть следующим образом:
| product | sales | target_encoded |
| apple | 100 | 83.333 |
| orange | 200 | 250.0 |
| banana | 50 | 35.0 |
| apple | 150 | 83.333 |
| orange | 300 | 250.0 |
| apple | 50 | 83.333 |
| banana | 20 | 35.0 |
Как вы можете видеть, исходный столбец "product" все еще присутствует в таблице, но был добавлен новый столбец "target_encoded", который содержит целевые значения в кодировке для каждого продукта. Строки в столбце "target_encoded" теперь содержат десятичные значения, представляющие среднее значение столбца "sales" для каждого продукта.
Вы можете использовать функцию groupby() из библиотеки pandas, чтобы применить целевую кодировку к столбцу "product" вашего фрейма данных, вот пример того, как это сделать:
# Create example dataframe
df = pd.DataFrame({'product': ['apple', 'orange', 'banana', 'apple', 'orange', 'apple', 'banana'],
'sales': [100, 200, 50, 150, 300, 50, 20]})
# Apply target encoding to "product" column
df['target_encoded'] = df.groupby('product')['sales'].transform('mean')
print(df)
Результирующий фрейм данных, df, будет иметь новый столбец "target_encoded", представляющий столбец среднего объема продаж для каждого продукта. Результирующий фрейм данных будет выглядеть следующим образом:
| product | sales | target_encoded |
| apple | 100 | 83.333 |
| orange | 200 | 250.0 |
| banana | 50 | 35.0 |
| apple | 150 | 83.333 |
| orange | 300 | 250.0 |
| apple | 50 | 83.333 |
| banana | 20 | 35.0 |