이전 포스팅에서 다룬 GridSearchCV 클래스를 통해 머신러닝 모델의 최적의 파라매터를 찾는 방법을 배웠다.
하지만 실전 데이터를 다루면서 중간에 전처리 과정이 들어가게 되면 GridSearchCV를 사용할 때 주의할 점이 생긴다.
다음 예제를 통해 무엇이 문제인지 생각해보자.
from sklearn.datasets import load_breast_cancer
data = load_breast_cancer()
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(
X, y,
test_size=0.3,
stratify=y,
random_state=11)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler().fit(X_train)
X_train_scaled=scaler.transform(X_train)
X_test_scaled=scaler.transform(X_test)
데이터를 불러와서 분할한 후 StandardScaler로 전처리를 하는 과정이다.
scaler에 학습 데이터를 모두 적용시키고 변환을 완료하였다.
from sklearn.model_selection import KFold, GridSearchCV
from sklearn.linear_model import LogisticRegression
param_grid=[{'penalty' : ['l2'],
'solver' : ['lbfgs'],
'C' : [1.0,0.1,10,0.01,100],
'class_weight': ['balanced',{0:0.9,1:0.1}]},
{'penalty' : ['elasticnet'],
'solver' : ['saga'],
'C' : [1.0,0.1,10,0.01,100],
'class_weight': ['balanced',{0:0.9,1:0.1}]}]
cv = KFold(n_splits=5,shuffle=True,random_state=11)
base_model = LogisticRegression(n_jobs=-1,random_state=11)
grid_model = GridSearchCV(base_model, param_grid=param_grid, cv=cv,
scoring='f1', n_jobs=-1)
grid_model.fit(X_train_scaled,y_train)
# 학습된 머신러닝 모델의 평가
print(f'SCORE(TRAIN) : {grid_model.score(X_train_scaled, y_train)}')
print(f'SCORE(TEST) : {grid_model.score(X_test_scaled, y_test)}')
이제 모델을 불러와 grid search를 수행하여 최적의 파라매터를 찾아주고
완성된 모델로 학습 평가 및 테스트 성능을 평가해준다.
보기에는 완벽해보이는 과정이지만 문제점이 있는 코드이다.
문제는 학습 데이터를 모두 전처리한 후 그걸로 교차검증이 이루어진다는 점이다.
Pipeline을 사용해 데이터의 전처리 과정 및 모델의 학습 과정을 연결해줌으로써 이런 문제를 해결할 수 있다.
Pipeline
※ 파이프라인 객체의 생성
Pipeline([('1번째 변환기 클래스 객체의 이름', 객체), ('2번째 변환기 클래스 객체의 이름', 객체) ... ])
- 파이프라인의 마지막 객체를 제외한 나머지 객체들은 transform, fit_transform 메소드를 제공하는 변환기만 허용
- 파이프라인의 마지막 객체는 predict 메소드를 제공하는 예측기가 될 수 있음
※ 파이프라인의 실행 과정
1. fit 메소드가 호출되는 경우
- 입력된 X 데이터를 첫 번째 변환기로 전달하여 fit_transform
- 변환된 결과를 다음 변환기 / 예측기로 전달
- 변환기라면 fit_transform 반복, 예측기라면 fit 후 종료
2. score / predict 메소드가 호출되는 경우
- 입력된 X 데이터를 첫번째 변환기로 전달하여 transform
- 변환된 결과를 다음 변환기 / 예측기로 전달
- 변환기라면 transform 반복, 예측기라면 score / predict 메소드의 실행 결과 반환
Pipeline 예제
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
# Pipeline을 예측기로 사용하는 GridSearchCV 클래스의
# 파라메터 정보는 키 값의 형태를
# 파이프라인의예측기객체명__파라메터이름
param_grid=[{'base_model__penalty' : ['l2'],
'base_model__solver' : ['lbfgs'],
'base_model__C' : [1.0,0.1,10,0.01,100],
'base_model__class_weight': ['balanced',{0:0.9,1:0.1}]},
{'base_model__penalty' : ['elasticnet'],
'base_model__solver' : ['saga'],
'base_model__C' : [1.0,0.1,10,0.01,100],
'base_model__class_weight': ['balanced',{0:0.9,1:0.1}]}]
cv = KFold(n_splits=5,shuffle=True,random_state=11)
base_model = LogisticRegression(n_jobs=-1,random_state=11)
from sklearn.pipeline import Pipeline
pipe = Pipeline([('s_scaler',scaler),('base_model',base_model)])
grid_model = GridSearchCV(pipe, param_grid=param_grid, cv=cv,
scoring='f1', n_jobs=-1)
grid_model.fit(X_train,y_train)
# 학습된 머신러닝 모델의 평가
print(f'SCORE(TRAIN) : {grid_model.score(X_train, y_train)}')
print(f'SCORE(TEST) : {grid_model.score(X_test, y_test)}')
GridSearchCV의 estimator에 pipe를 넣어 객체를 생성한 모습이다.
이렇게 되면 5개의 폴드 중 4개의 폴드를 전처리 한 후 학습을 진행하고
나머지 하나의 폴드는 기존의 4개의 폴드로 전처리된 변환기 클래스에 의해 transform 되어 예측에 사용된다.
GridSearchCV는 이러한 과정을 통해 교차검증 score가 가장 높은 파라메터를 찾아주게 된다.
'머신러닝' 카테고리의 다른 글
[머신러닝] GridSearchCV (0) | 2022.06.08 |
---|---|
[머신러닝] 교차검증(Cross-Validation) - KFold (0) | 2022.06.08 |
[머신러닝] 데이터 전처리 - 문자열 인코딩 (0) | 2022.06.07 |
[머신러닝] 데이터 전처리 - 결측 데이터 처리 (0) | 2022.06.07 |
[머신러닝] 선형 모델의 성능 향상을 위한 방법 (0) | 2022.04.22 |