June 4, 2022

Бинарное кодирование

Для численного представления категорий в моделях машинного обучения существуют разные методики (распространенные примеры OneHotEncoder и OrdinalEncoder). Рассмотрим одну из них - BinaryEncoder, которая напоминает OneHotEncoder, так как ставит каждой категории в соответствие вектор из 0 и 1, но в отличие от него формирует более плотное представление.

Так, если OneHotEncoder ставит категории в соответствии вектор со всеми 0 и лишь одной 1 на месте порядкового номера этой категории в общем списке (соответственно, вектор имеет размерность N - количество уникальных категорий), то бинарный кодировщик каждому порядковому номеру уникальной категории ставит в соответствие его битовое представление (количество категорий - logN).

Одна из реализаций бинарного кодировщика реализована в классе BinaryEncoder библиотеки category_encoders. Для демонстрации его работы рассмотрим датафрейм:

import pandas as pd

df = pd.DataFrame([['food', 'apple', 10], ['not_food', 'ball', 20], ['not_food', 'basket', 12],
                  ['food', 'banana', 33], ['food', 'apple',22]], columns=['cat1', 'cat2', 'price'])
df

Создадим экземпляр класса, обучим и запустим трансформер:

from category_encoders import BinaryEncoder

enc = BinaryEncoder()
enc.fit_transform(df)

В конструктор класса можно передать параметр (cols) со списком имен колонок для трансформации, если не заданы преобразуются все с типом object или category.

Обратите внимание, что несмотря на наличие 4 категорий во второй колонке (cat2) под нее был зарезервирован вектор длины 3 (в строке под номером 2 две единицы в cat2_1 и cat2_2). Если бы использовали OneHotEncoder, единица была бы только в одном столбце для новых колонок категориального столбца:

from sklearn.preprocessing import OneHotEncoder
cat_cols = ['cat1', 'cat2']
ohe = OneHotEncoder(sparse=False)
pd.DataFrame(ohe.fit_transform(df[cat_cols]), columns=ohe.get_feature_names_out(cat_cols))

Если встретится новая категория, то по умолчанию она будет трансформирована в вектор нулей:

enc.transform(pd.DataFrame([['food', 'cherry', 6]],columns=['cat1', 'cat2', 'price']))

Обратная трансформация неизвестной категории приведет к Nan:

enc.inverse_transform(enc.transform(pd.DataFrame([['food', 'cherry', 6]], 
                                                 columns=['cat1', 'cat2', 'price'])))

Полезные ссылки:

1. OneHotEncoder

2. OrdinalEncoder

Не пропустите ничего интересного и подписывайтесь на страницы канала в других социальных сетях:

Яндекс Дзен

Telegram