May 5, 2022

Кодирование неизвестных категорий

Зачастую в категориальной колонке датасета могут присутствовать не все возможные значения. При этом если вы используете энкодер для кодирования колонки (например, OneHotEncoder или OrdinalEncoder) при появлении нового значения метод transform может вызвать ошибку. Рассмотрим, как предусмотреть поведение энкодера на этот случай. Для демонстрационных целей будем использовать следующий датафрейм:

import pandas as pd
from sklearn.preprocessing import OrdinalEncoder, OneHotEncoder

df = pd.DataFrame([['food', 'apple'], ['not_food', 'ball'], ['not_food', 'basket'],
                  ['food', 'banana'], ['food', 'apple']], columns=['cat1', 'cat2'])
df

Создадим объект OrdinalEncoder, обучим его и попытаемся трансформировать набор, в котором отсутствовали значения:

oe = OrdinalEncoder()
oe.fit_transform(df)
display(oe.transform([['food', 'grocery']]))
display(oe.transform([['vegetable', 'grocery']]))

Получим ошибку. Теперь пересоздадим энкодер и зададим параметры handle_unknown='use_encoded_value', unknown_value=-1, благодаря которым OrdinalEncoder будет кодировать неизвестные значения и использовать для этого "-1":

oe = OrdinalEncoder(handle_unknown='use_encoded_value', unknown_value=-1)
oe.fit(df)
display(oe.transform([['food', 'grocery']]))
display(oe.transform([['vegetable', 'grocery']]))

Обратное преобразование для неизвестных значений будет заполняться None категорией:

oe.inverse_transform(oe.transform([['food', 'grocery']]))

Аналогичное поведение можно задать и для OneHotEncoder:

oh = OneHotEncoder(sparse=False, handle_unknown='ignore')
oh.fit_transform(df)
display(pd.DataFrame(oh.transform([['food', 'grocery']]), columns=oh.get_feature_names(df.columns)))
display(pd.DataFrame(oh.transform([['vegetable', 'grocery']]), columns=oh.get_feature_names(df.columns)))

Для него задается параметр handle_unknown='ignore', и значения отсутствующих категорий содержат все 0 в относящихся к ней значениях.

Обратное преобразование будет заполнять незнакомые категории значением None:

display(oh.inverse_transform(pd.DataFrame(oh.transform([['food', 'grocery']]), columns=oh.get_feature_names(df.columns))))
display(oh.inverse_transform(pd.DataFrame(oh.transform([['vegetable', 'grocery']]), columns=oh.get_feature_names(df.columns))))

Чтобы освежить в памяти информацию о кодировании можете почитать:

1. OneHotEncoder

2. OrdinalEncoder

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

Яндекс Дзен

Telegram