Частотное кодирование факторных колонок
Важной задачей при построении моделей машинного обучения является перевод факторных колонок в числа. Наиболее частым способом является one-hot энкодинг, о котором я рассказывал ранее. В случае большого количества категорий такой способ может привести к переобучению модели, поэтому рассматривают другие приемы. При этом прибегают как к использованию грубых путей как порядковое кодирование, так и попыткам ухватит дополнительную информацию, которую могут нести категории. В частности, ею может быть абсолютная или относительная частота встречаемости значений колонки. Для демонстрации работы частотного кодирования рассмотрим датафреймы:
import pandas as pd import numpy as np df_train = pd.DataFrame([['fourth_cat1', 'third_cat2', 1], ['first_cat1', 'third_cat2', 1], ['second_cat1', 'third_cat2', 2], ['second_cat1', 'second_cat2', 5], ['second_cat1', None, 5]]) df_valid = pd.DataFrame([['fifth_cat1', 'third_cat2', np.nan], ['second_cat1', 'third_cat2', 2], ['second_cat1', 'second_cat2', 2]])
Сначала создадим собственный преобразователь (о том, как подробнее рассказывал здесь):
from sklearn.base import TransformerMixin, BaseEstimator class FreqEncoding(TransformerMixin, BaseEstimator): freq_d = {} def fit(self, X): for col in X.select_dtypes(include=['category', 'object']).columns: self.freq_d[col] = X[col].value_counts(normalize=True).to_dict() return self def transform(self, X): X_tr = X.copy() for col in X_tr.select_dtypes(include=['category', 'object']).columns: X_tr[col] = X_tr[col].map(lambda x: self.freq_d[col].get(x, 0), na_action='ignore') return X_tr
Сначала вызовем fit_transform для обучения и преобразования df_train:
enc = FreqEncoding() enc.fit_transform(df_train)
А теперь transform для преобразования df_valid:
enc.transform(df_valid)
Ниже привожу словарь с частотами категорий, сформированный в ходе обучения на df_train:
enc.freq_d
Теперь вызовем pipeline предобработки данных с нашим классом:
from sklearn.pipeline import Pipeline from sklearn.impute import SimpleImputer tr = Pipeline(steps=[('freq', FreqEncoding()),('imp', SimpleImputer())]) tr.fit_transform(df_train) tr.transform(df_valid)
Следует отметить, что в библиотеке category_encoders с реализованными энкодерами, пока не включенными в sklearn, имеется рассматриваемый в данной статье frequency encoder, который называется CountEncoder. Конечно, его функционал шире, реализованного нами FreqEncoding (например, можно выбирать нормализуются ли частоты с параметром normalize, есть обработка Nan значений):
import category_encoders as ce enc = ce.CountEncoder(normalize=True) enc.fit_transform(df_train) enc.transform(df_valid)
Как можно догадаться, CountEncoder также поддерживается в pipeline-ах:
from sklearn.pipeline import Pipeline from sklearn.impute import SimpleImputer tr = Pipeline(steps=[('freq', ce.CountEncoder(normalize=True)),('imp', SimpleImputer())]) tr.fit_transform(df_train) tr.transform(df_valid)
- Создание пользовательских преобразователей данных
- Порядок обучения и запуска преобразователей данных
- Бинарное кодирование
- One-hot кодирование
- Порядковое (Ordinal) кодирование
Не пропустите ничего интересного и подписывайтесь на страницы канала в других социальных сетях: