Как получить оригинальные названия признаков из Pipeline?

У меня есть Pipeline

    param_tuning = {

        'classifier__learning_rate': [0.01, 0.1],
        'classifier__max_depth': [3, 5, 7, 10],
        'classifier__min_child_weight': [1, 3, 5],
        'classifier__subsample': [0.5, 0.7],
        'classifier__n_estimators' : [100, 200, 500],
    }

cat_pipe = Pipeline(
    [
        ('selector', ColumnSelector(categorical_features)),
        ('encoder', ce.one_hot.OneHotEncoder())
    ]
)

num_pipe = Pipeline(
    [
        ('selector', ColumnSelector(numeric_features)),
        ('scaler', StandardScaler())
    ]
)

preprocessor = FeatureUnion(
    transformer_list=[

        ('cat', cat_pipe),
        ('num', num_pipe)
    ]
)

xgb_pipe = Pipeline(
    steps=[
        ('preprocessor', preprocessor),
        ('classifier', xgb.XGBClassifier())
    ]
)

grid = GridSearchCV(xgb_pipe, param_tuning, cv=5, n_jobs=-1, scoring='accuracy')

ColumnSelector выглядит следующим образом

class ColumnSelector(BaseEstimator, TransformerMixin):
def __init__(self, columns):
    self.columns = columns
    
def fit(self, X, y = None):
    return self

def transform(self, X):
    return X[self.columns]

Когда я пытаюсь получить признаки из Pipeline

xgb['preprocessor'].transformer_list[0[1].named_steps['encoder'].get_feature_names()

Я получаю кодированные признаки (One hot)

['Пол_1', 'Пол_2', 'Адрес ФМЖ_1', 'Адрес ФМЖ_2']

Каким образом мне получить оригинальные названия признаков?

 ['Пол_М', 'Пол_', 'Адрес ФМЖ_Барнаул', 'Адрес ФМЖ_Москва']

Ответы (1 шт):

Автор решения: CrazyElf

У вас где-то раньше названия колонок всё-таки ломаются, OneHotEncoder ничего не ломает, вот я пример набросал:

import pandas as pd
from sklearn.preprocessing import OneHotEncoder

df = pd.DataFrame({'data': "alien invaders from outer space".split(' ')}, dtype="category")
ohe = OneHotEncoder()
ohe.fit_transform(df)
print(ohe.get_feature_names(df.columns))

Вывод:

['data_alien' 'data_from' 'data_invaders' 'data_outer' 'data_space']

Может ColumnSelector названия колонок ломает?

Примечание. Если не передать df.columns в ohe.get_feature_names, то сломается не вторая часть имён как у вас, а первая, так что дело видимо не в этом:

['x0_alien' 'x0_from' 'x0_invaders' 'x0_outer' 'x0_space']

Кстати, а OneHotEncoder у вас из sklearn или может какой-то особенный?

→ Ссылка