sklearn ColumnsTransformer 및 변수별로 전처리 적용하는 예시

2020. 5. 2. 13:46분석 Python/Data Preprocessing

728x90

광고 한 번씩 눌러주세요! 블로그 운영에 큰 힘이 됩니다 :)

예시 3개를 소개함

  • 변수 그룹별로 나눠서 전처리 해보기
  • Pipeline을 내부적으로 만들어서 해보기
  • Custom Class를 이용해서 해보기

변수 그룹별로 나눠서 전처리 해보기

from sklearn.compose import ColumnTransformer
from sklearn.pipeline import FeatureUnion, Pipeline
num_var1 = num_var[5:]
num_var2 = num_var[:5]
print(num_var1, num_var2)

pipe = ColumnTransformer(transformers=[
    ("num1", MinMaxScaler(), num_var1),
    ("num2", StandardScaler(), num_var2)
])
pipe.fit(data[num_var])

주의할 점

Transform을 하게 되면 num_var1  num_var2 로 정렬됨
그러므로 Transform후 ColumnTransformer에서 적용한 변수 순서를 맞춰야함.

data[num_var1 + num_var2] = pipe.transform(data[num_var])

 


Pipeline을 내부적으로 만들어서 해보기

from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
numeric_features = numeric_col 
numeric_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='median')),
    ('scaler', StandardScaler())])

categorical_features = category_col
categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant', fill_value='missing')),
    ('onehot', OneHotEncoder(handle_unknown='ignore'))])

preprocessor = ColumnTransformer(
    transformers=[
        ('num', numeric_transformer, numeric_features),
        ('cat', categorical_transformer, categorical_features)])
clf = Pipeline(steps=[('preprocessor', preprocessor),])

Custom Class를 이용해서 해보기

변수 선택 하는 Class와 Type으로 선택하는 Class 

from sklearn.compose import ColumnTransformer
from sklearn.pipeline import FeatureUnion, Pipeline
from sklearn.base import BaseEstimator, TransformerMixin, ClassifierMixin
from sklearn.preprocessing import *


class ColumnSelector(BaseEstimator, TransformerMixin):
    def __init__(self, columns):
        self.columns = columns

    def fit(self, X, y=None):
        return self

    def transform(self, X):
        assert isinstance(X, pd.DataFrame)

        try:
            return X[self.columns]
        except KeyError:
            cols_error = list(set(self.columns) - set(X.columns))
            raise KeyError("The DataFrame does not include the columns: %s" % cols_error)
class TypeSelector(BaseEstimator, TransformerMixin):
    def __init__(self, dtype):
        self.dtype = dtype

    def fit(self, X, y=None):
        return self

    def transform(self, X):
        assert isinstance(X, pd.DataFrame)
        return X.select_dtypes(include=[self.dtype])

변수 선택 및 전처리함수 적용하기

step1 = [("selector_1", ColumnSelector(num_var[-5:])),
         ("num_scaling_1" , MinMaxScaler())]
step2 = [("selector_2", ColumnSelector(num_var[:-5])),
         ("num_scaling_2" , StandardScaler())]

pipe라인 list를 만들고 Feature Union으로 결합하기

 

pipeline_list = [("pipe_step1",Pipeline(step1)),
                  ("pipe_step2",Pipeline(step2))]
clf = FeatureUnion(transformer_list=pipeline_list)

적용하기

* 주의해야할 것은 이것도 역시 step1 ,2 순서대로 적용해서 변형시키므로 transform된 결과가 기존 컬럼 순서와 동일하지 않음. 그러므로 맞춰주는 작업이 필요함.

clf.fit(train[num_var])
train[num_var[-5:]+num_var[:-5]] = clf.transform(train[num_var])

 

728x90