Get feature names of ColumnTransformer using StandarScaler and One-Hot-Encoding

Viewed 663

I am using a simple ColumnTransformer with StandardScaler and OneHotEncoder like:

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import OneHotEncoder

num_features = ['num_feat_1',
                'num_feat_2',
                'num_feat_3']
cat_features = ['cat_feat_1',
                'cat_feat_2',
                'cat_feat_3']

ct = ColumnTransformer([
    ("scaler", StandardScaler(), num_features),
    ("onehot", OneHotEncoder(sparse=False,
                             handle_unknown='ignore'), cat_features)], 
    remainder='passthrough') 

ct.fit(X_train)
X_train_trans = ct.transform(X_train)
X_test_trans = ct.transform(X_test)

To map the coefficients of a LinearRegression, I need ct.get_feature_names(), but I get the error Transformer scaler (type StandardScaler) does not provide get_feature_names. Why is that and how can I solve this?

1 Answers

In your case, get_feature_names() will work only on the onehot , and for StandardScaler() you would not change the names of the transformed variable, so we go through the transformers, if the get_feature doesn't work, we retain the original feature names.

Using an example dataset:

import pandas as pd
import numpy as np
X = pd.concat([
    pd.DataFrame(np.random.uniform(0,1,(100,3)),columns=num_features),
    pd.DataFrame(np.random.choice(['a','b'],(100,3)),columns=cat_features)
],axis=1)

X_train = X.iloc[:50,:]
X_test = X.iloc[50:,:]

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import OneHotEncoder

num_features = ['num_feat_1',
                'num_feat_2',
                'num_feat_3']
cat_features = ['cat_feat_1',
                'cat_feat_2',
                'cat_feat_3']

ct = ColumnTransformer([
    ("scaler", StandardScaler(), num_features),
    ("onehot", OneHotEncoder(sparse=False,
                             handle_unknown='ignore'), cat_features)], 
    remainder='passthrough') 

ct.fit(X_train)

We try this:

tx = ct.get_params()['transformers']
feature_names = []
for name,transformer,features in tx:
    try:
        Var = ct.named_transformers_[name].get_feature_names().tolist()
    except AttributeError:
        Var = features
    feature_names = feature_names + Var

feature_names
['num_feat_1',
 'num_feat_2',
 'num_feat_3',
 'x0_a',
 'x0_b',
 'x1_a',
 'x1_b',
 'x2_a',
 'x2_b']
Related