모델 튜닝 장에서 전처리와 모델을 파이프라인(Pipeline) 으로 하나로 묶고 GridSearchCV 로 튜닝했습니다. 실제 분석에서는 여러 전처리 단계를 잇고, 여러 모델을 같은 흐름으로 비교하게 됩니다. 파이프라인은 이런 알고리즘 체인을 하나의 추정기처럼 다루게 해 줍니다.
1여러 단계 연결¶
파이프라인은 변환기(전처리) 여러 개와 마지막 모델을 순서대로 연결합니다. 각 단계는 앞 단계의 출력을 입력으로 받습니다. 캘리포니아 주택 데이터에 다항식 특성 → 단위 변환 → 릿지 회귀를 잇는 체인을 만들어 보겠습니다. 다항식으로 만든 특성은 값의 크기 차이가 크기 때문에, 그 뒤에 단위 변환을 두어 회귀를 안정적으로 수행합니다.
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures, StandardScaler
from sklearn.linear_model import Ridge
import pandas as pd
housing = fetch_california_housing()
훈련데이터, 시험데이터, 훈련정답, 시험정답 = train_test_split(
housing.data, housing.target, random_state=4)
체인 = Pipeline([
('poly', PolynomialFeatures(degree=2)),
('scaler', StandardScaler()),
('ridge', Ridge()),
])
체인.fit(훈련데이터, 훈련정답)
print(f'시험 R^2: {체인.score(시험데이터, 시험정답):.3f}')시험 R^2: 0.409
세 단계를 하나의 객체로 묶었기 때문에, fit 한 번으로 다항식 확장·단위 변환·회귀 학습이 순서대로 수행됩니다. 예측할 때도 같은 변환이 자동으로 적용됩니다.
2전체 체인 튜닝¶
파이프라인의 장점은, 여러 단계에 걸친 하이퍼파라미터를 GridSearchCV 로 한꺼번에 탐색할 수 있다는 점입니다. 다항식 차수와 릿지의 규제 강도를 동시에 튜닝해 보겠습니다. 단계 매개변수는 단계이름__매개변수 형식으로 지정합니다.
from sklearn.model_selection import GridSearchCV
탐색범위 = {
'poly__degree': [1, 2],
'ridge__alpha': [0.1, 1.0, 10.0],
}
튜닝기 = GridSearchCV(체인, param_grid=탐색범위)
튜닝기.fit(훈련데이터, 훈련정답)
print('최적 설정:', 튜닝기.best_params_)
print(f'시험 R^2: {튜닝기.score(시험데이터, 시험정답):.3f}')최적 설정: {'poly__degree': 1, 'ridge__alpha': 10.0}
시험 R^2: 0.595
한 번의 탐색으로 전처리 단계(다항식 차수)와 모델 단계(릿지 규제)의 조합을 교차 검증하며 최적값을 찾습니다. 전처리와 모델을 따로 튜닝할 때 생기는 번거로움과 데이터 누수 위험을 함께 해결합니다.
3여러 모델을 같은 흐름으로 비교¶
파이프라인도 단일 모델과 똑같이 fit·predict·score 를 제공하는 하나의 추정기입니다. 덕분에 내부가 단일 모델이든 전처리가 포함된 파이프라인이든, 같은 평가 흐름으로 다룰 수 있습니다. 여러 모델을 사전으로 묶어 동일한 반복문으로 비교해 보겠습니다.
from sklearn.linear_model import LinearRegression
from sklearn.neighbors import KNeighborsRegressor
from sklearn.preprocessing import RobustScaler
모델들 = {
'선형회귀': LinearRegression(),
'릿지+다항식': 체인,
'kNN+단위변환': Pipeline([('scaler', RobustScaler()),
('knn', KNeighborsRegressor())]),
}
점수 = {}
for 이름, model in 모델들.items():
model.fit(훈련데이터, 훈련정답)
점수[이름] = model.score(시험데이터, 시험정답)
pd.Series(점수).round(3).rename('R^2')선형회귀 0.595
릿지+다항식 0.409
kNN+단위변환 0.665
Name: R^2, dtype: float64모델이 단일 추정기든 파이프라인이든 같은 인터페이스를 가지므로, 반복문 하나로 여러 모델을 공정하게 비교할 수 있습니다. 이렇게 파이프라인은 전처리·모델·튜닝·비교를 일관된 방식으로 묶어 줍니다.
열마다 다른 전처리가 필요한 경우(예: 수치형은 단위 변환, 범주형은 원-핫 인코딩)에는 ColumnTransformer 로 열별 변환을 묶어 파이프라인의 한 단계로 넣을 수 있습니다.