AI·빅데이터 융합 경영학 Study Note
[ML수업] 10주차 실습2: Hyperparameter Tuning using Pipeline+Optuna 예시 코드 본문
AI·ML
[ML수업] 10주차 실습2: Hyperparameter Tuning using Pipeline+Optuna 예시 코드
SubjectOwner 2023. 11. 21. 15:541. 수치형 피처
- 결측값처리: SimpleImputer(strategy=`???`)
- 이상값처리: FunctionTransformer()
- 스케일링: StandardScaler()
2. 범주형 피처
- 결측값처리: SimpleImputer(strategy="most_frequent")
- 인코딩: OneHotEncoder(handle_unknown="ignore")
- 차원축소: `MyPCATransformer()` # Custom PCA
3. 공통
- Feature Selection: SelectPercentile(percentile=`???`)
- Modeling: Logistic Regression(C=`???`)
- Hyperparametor Optimization: `OptunaSearchCV`
1. 임포트
%matplotlib inline
import warnings
warnings.filterwarnings("ignore")
#여기에 분류 문제 관련된 패키지들이 거의 다 있음.
#분류문제 풀이를 시작할 때는 이걸 복붙하는 게 첫번째임
import pandas as pd
import numpy as np
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import FunctionTransformer
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.impute import SimpleImputer
from sklearn.experimental import enable_iterative_imputer # still experimental
from sklearn.impute import IterativeImputer
from sklearn.preprocessing import StandardScaler, PowerTransformer
from sklearn.preprocessing import OrdinalEncoder, OneHotEncoder
from category_encoders import TargetEncoder # scikit-learn과 호환됨
from sklearn.decomposition import PCA
from sklearn.feature_selection import SelectKBest, SelectPercentile
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import roc_auc_score
from sklearn import set_config
import optuna
2. load data
data = pd.read_csv('allstate_train.csv')
data.head()
3. 수치형/범주형 피처 분리 & 학습/평가 데이터 분할
# 수치형/범주형 피처 분리
numeric_features = ['group_size','car_age','age_oldest','age_youngest','duration_previous','cost']
categorical_features = ['day','homeowner','car_value','risk_factor','married_couple','C_previous','state','shopping_pt']
# 학습/평가 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(data[numeric_features+categorical_features],
data['record_type'], test_size=0.9,
stratify=data['record_type'], random_state=0)
******4. 파이프라인 구축: 수치형과 범주형 피처를 다르게 처리할 수 있는 ColumnTransformer를 활용
(이게 중요)
# 이상치 처리 방법 중 가장 단순한 방법:
def remove_outlier(X):
df = pd.DataFrame(X)
# df.clip(): 상한선과 하한선을 임계값으로 정해서 임계값 밖의 값을 임계값으로 변경
return df.apply(lambda x: x.clip(x.quantile(.05), x.quantile(.95)), axis=0).values
# PCA 차원을 자동으로 결정하는 Custom PCA 전처리기 클래스
class MyPCATransformer(TransformerMixin, BaseEstimator):
# 전처리기 생성 즉, MyPCATransformer() 호출시 실행
def __init__(self, sum_explained_variance=0.99):
self.sum_explained_variance = sum_explained_variance
# 전처리기의 fit() 호출시 실행
def fit(self, X, y=None):
# 먼저, 전체 피처에 대해 PCA 수행(차원 축소 없음)
max_d = X.shape[1]
pca = PCA(n_components=max_d).fit(X)
# 누적된 분산의 설명량이 um_explained_variance 이상 되는 차원을 축소할 차원으로 설정
cumsum = np.cumsum(pca.explained_variance_ratio_) #분산의 설명량을 누적합
self.num_d = np.argmax(cumsum >= self.sum_explained_variance) + 1 #분산의 설명량이 99%이상 되는 차원의 수
if self.num_d == 1: self.num_d = max_d
# 축소할 차원으로 다시 PCA 수행
self.pca = PCA(n_components=self.num_d)
self.pca.fit(X)
return self
# 전처리기의 transform() 호출시 실행
def transform(self, X):
return self.pca.transform(X)
numeric_transformer = Pipeline(
steps=[
("imputer", SimpleImputer(strategy="median")),
("outlier", FunctionTransformer(remove_outlier)), # 함수를 전처리기로 변환하여 sklearn에 없는 새로운 전처리기를 만듬
("scaler", StandardScaler()),
]
)
categorical_transformer = Pipeline(
steps=[
("imputer", SimpleImputer(strategy="most_frequent")),
("encoder", OneHotEncoder(handle_unknown="ignore", sparse=False)),
("pca", MyPCATransformer()), # Custom 전처리기(PCA) 호출
]
)
column_transformer = ColumnTransformer(
transformers=[
("num", numeric_transformer, numeric_features),
("cat", categorical_transformer, categorical_features),
]
)
preprocessor = Pipeline(
steps=[
("column", column_transformer),
("selector", SelectPercentile(percentile=50)),
]
)
model = Pipeline(
steps=[
("preprocessor", preprocessor),
("classifier", LogisticRegression()),
]
)
set_config(display="diagram") # To view the text pipeline, change to display='text'.
model
5. 파이프라인을 통한 모형 학습
model.fit(X_train, y_train)
print("model score: %.3f" % roc_auc_score(y_test, model.predict_proba(X_test)[:,1]))
6. `파이프라인+Optuna`를 통한 하이퍼파라미터 최적화
%time
param_distributions = {
"preprocessor__column__num__imputer__strategy": optuna.distributions.CategoricalDistribution(["mean", "median"]),
"preprocessor__selector__percentile": optuna.distributions.IntDistribution(50,100,step=10),
"classifier__C": optuna.distributions.FloatDistribution(0.01, 100),
}
optuna_search = optuna.integration.OptunaSearchCV(model, param_distributions, cv=5, scoring='roc_auc', n_trials=20,
study=optuna.create_study(sampler=optuna.samplers.TPESampler(seed=100), direction="maximize"))
optuna_search.fit(X_train, y_train)
print(f"Best params: {optuna_search.best_params_}")
print(f"Internal CV score: {optuna_search.best_score_:.3f}")
print("Test score from grid search: %.3f" % roc_auc_score(y_test, optuna_search.predict_proba(X_test)[:,1]))
"""
Best params: {'preprocessor__column__num__imputer__strategy': 'median', 'preprocessor__selector__percentile': 100, 'classifier__C': 0.16209216634075574}
Internal CV score: 0.844
Test score from grid search: 0.842
"""
'AI·ML' 카테고리의 다른 글
파이썬 다 돌아가면 소리남 (0) | 2023.11.23 |
---|---|
[ML수업] 10주차 실습4: pipeline_stacking 예시 코드1 (0) | 2023.11.21 |
[ML수업] 10주차 실습1: pipeline_basics (0) | 2023.11.21 |
[ML수업] 8주차 실습6: feature engineering- Feature Generation (0) | 2023.11.21 |
[ML수업] 8주차 실습5: feature engineering- Dimensionality Reduction (차원 축소) (0) | 2023.11.21 |