Частотное кодирование факторных колонок
Важной задачей при построении моделей машинного обучения является перевод факторных колонок в числа. Наиболее частым способом является 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) кодирование
Не пропустите ничего интересного и подписывайтесь на страницы канала в других социальных сетях: