[SKlearn]pipeline에서 열마다 다른 작업 처리해주기

신동혁·2022년 9월 13일
0

SKlearn

목록 보기
2/3

1.사이킷런 pipeline

사이킷런의 전처리 과정을 간단하게 할 수 있는 방법 중 하나가 pipeline이다. pipeline이란 여러 단계의 머신러닝 프로세스 (전처리의 각 단계, 모델생성, 학습) 처리 과정을 묶어서 한번에 처리하기 위한 기술을 의미한다. pipeline을 사용하는 모습을 예시로 확인해본다.

<예시>

from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
order = [
    ("scaler",StandardScaler()),
    ("svm",SVC())
]

from sklearn.pipeline import Pipeline
pipeLine = Pipeline(order, verbose=True) # 파이프라인 생성

# X_train, y_train 데이터 있다고 가정
pipeLine.fit(X_train, y_train) # 파이프라인을 이용한 학습

pred_train = pipeLine.predict(X_train) # 파이프라인을 이용한 예측
pred_test = pipeLine.predict(X_test)

print(accuracy_score(y_train, pred_train))
print(accuracy_score(y_test, pred_test))

위 코드는 X_train데이터를 StandardScaler()로 표준화해주고, 표준화된 데이터를 SVC()모델로 학습시켜주는 일련의 작업을 pipeline으로 한번에 처리하는 코드다.

이때 만약 X_train데이터에 StandardScaler()로 표준화할 수 있는 연속형 feature도 존재하지만 StandardScaler()로 표준화할 수 없는 범주형 feature도 존재할 수 있다. 이럴 경우 X_train의 특정 feature들에만 따로 따로 전처리를 해주고 싶다면 어떻게 해야할까? 이때 사용되는 것이 BaseEstimatorTransformerMixin다.

2.BaseEstimator와 TransformerMixin

원리는 다음과 같다. pipeline은 매개변수로 튜플들을 담은 리스트에 원하는 작업들을 튜플형태로 넣어줘야 하는데, 이 때 넣어줄 함수자체를 따로 만들어주는 형식이다.(정확히는 클래스) 다음 예시를 통해 알아본다.

다음과 같은 train데이터프레임이 존재한다고 가정한다.

row_iddatecountrystoreproductnum_sold
002017-01-01BelgiumKaggleMartKaggle Advanced Techniques663
112017-01-01BelgiumKaggleMartKaggle Getting Started615
222017-01-01BelgiumKaggleMartKaggle Recipe Book480
332017-01-01BelgiumKaggleMartKaggle for Kids: One Smart Goose710
442017-01-01BelgiumKaggleRamaKaggle Advanced Techniques240
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import LabelEncoder
from sklearn.pipeline import Pipeline

class myscaler(BaseEstimator, TransformerMixin):
        
    def fit(self, X, y=None):
        return self

    def transform(self, X, y=None):
        scaler = StandardScaler()
        X["num_sold"] = scaler.fit_transform(pd.DataFrame(X["num_sold"]))
        
        le1 = LabelEncoder()
        X["country"] = le1.fit_transform(X["country"])
        
        le2 = LabelEncoder()
        X["store"] = le2.fit_transform(X["store"])
        
        le3 = LabelEncoder()
        X["product"] = le3.fit_transform(X["product"])
        return X


pipe = Pipeline([
    ("first_scaling", myscaler())
])

pipe.fit_transform(train)

위 코드에서 myscaler 클래스의 transform 메서드를 확인해보면 train 데이터프레임의 num sold feature에는 StandardScaler()로 표준화를 해주고 train 데이터프레임의 country, store, product feature에는 LabelEncoder()로 범주형 전처리를 함을 확인할 수 있다.

위와 같은 class를 만드는 방식을 기억하면, pipeline을 이용할 때 특정 열에만 원하는 작업을 처리할 수 있다. myscaler함수는 BaseEstimatorTransformerMixin이라는 클래스를 상속받고 있다. BaseEstimator는 get_params 메서드와 set_params 메서드를 가지고 있어서 이 두 메서드를 상속받아 하이퍼파라미터를 변경하는데 사용한다. TransformerMixin은 fit_transform 메서드를 가지고 있어서 이 메서드를 상속받아 데이터를 학습 및 변환을 하는데 사용한다.

즉, 우리가 만들어야 할 부분은 fit 메서드와 transform 메서드다. fit 메서드와 transform 메서드는 위에 코드를 참고하여 형태를 익혀놓으면 좋을 듯하다.

참고한 블로그 : https://databuzz-team.github.io/2018/11/11/make_pipeline/

profile
개발취준생

0개의 댓글