오늘은 stacking을 직접 구현해보았다.
import xgboost as xgb
import lightgbm as lgb
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split, KFold
from sklearn.metrics import mean_absolute_error
from sklearn.linear_model import LinearRegression
# 학습에 사용할 특징 열
feature_columns = [col for col in temp_train_df.columns if col not in ['deposit', '_type', 'index']]
# 학습 및 테스트 데이터 준비
X = temp_train_df[feature_columns]
y = temp_train_df['deposit']
X_test = test_df[feature_columns]
# 학습 데이터를 검증용으로 분할
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)
# XGBoost를 위한 DMatrix 생성
dtrain = xgb.DMatrix(X_train, label=y_train)
dval = xgb.DMatrix(X_val, label=y_val)
dtest = xgb.DMatrix(X_test)
# XGBoost 파라미터 설정
xgb_params = {
'objective': 'reg:absoluteerror',
'eval_metric': 'mae',
'max_depth': 6,
'eta': 0.05,
'subsample': 0.8,
'colsample_bytree': 0.8,
'seed': 42
}
# 모델 학습
xgb_model = xgb.train(
xgb_params,
dtrain,
num_boost_round=500,
early_stopping_rounds=50,
evals=[(dtrain, 'train'), (dval, 'eval')],
verbose_eval=25
)
# 검증 및 테스트 세트에 대한 예측
xgb_val_pred = xgb_model.predict(dval)
xgb_test_pred = xgb_model.predict(dtest)
# LightGBM 모델 초기화
lgb_params = {
'objective': 'regression',
'metric': 'mae',
'boosting_type': 'gbdt',
'num_leaves': 31,
'learning_rate': 0.05,
'feature_fraction': 0.9,
'bagging_fraction': 0.8,
'bagging_freq': 5,
'seed': 42
}
# 콜백 함수 정의
def print_evaluation(period=10):
def callback(env):
if (env.iteration + 1) % period == 0:
train_mae = env.evaluation_result_list[0][2]
val_mae = env.evaluation_result_list[1][2]
print(f"[{env.iteration + 1}] Train MAE: {train_mae:.4f}, Val MAE: {val_mae:.4f}")
return callback
# 모델 학습
lgb_train = lgb.Dataset(X_train, label=y_train)
lgb_val = lgb.Dataset(X_val, label=y_val, reference=lgb_train)
lgb_model = lgb.train(
lgb_params,
lgb_train,
num_boost_round=500,
valid_sets=[lgb_train, lgb_val],
callbacks=[print_evaluation(period=100)]
)
# 검증 및 테스트 세트에 대한 예측
lgb_val_pred = lgb_model.predict(X_val, num_iteration=lgb_model.best_iteration)
lgb_test_pred = lgb_model.predict(X_test, num_iteration=lgb_model.best_iteration)
한 피처에 대한 의존도가 너무 커서 하이퍼파라미터 조정 필요
# 랜덤 포레스트 모델 초기화
rf_model = RandomForestRegressor(
n_estimators=100,
max_depth=10,
random_state=42,
n_jobs=-1
)
# 모델 학습
rf_model.fit(X_train, y_train)
# 학습 세트에 대한 예측
rf_train_pred = rf_model.predict(X_train)
# 검증 세트에 대한 예측
rf_val_pred = rf_model.predict(X_val)
# 테스트 세트에 대한 예측
rf_test_pred = rf_model.predict(X_test)
# 학습 세트의 MAE 계산
train_mae = mean_absolute_error(y_train, rf_train_pred)
print(f"Train MAE: {train_mae:.4f}")
# 검증 세트의 MAE 계산
val_mae = mean_absolute_error(y_val, rf_val_pred)
print(f"Validation MAE: {val_mae:.4f}")
from sklearn.ensemble import GradientBoostingRegressor
# Gradient Boosting 회귀 모델 초기화
gb_model = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1, random_state=42)
# 모델 학습
gb_model.fit(X_train, y_train)
# 검증 및 테스트 세트에 대한 예측
gb_val_pred = gb_model.predict(X_val)
gb_test_pred = gb_model.predict(X_test)
# 학습 세트의 MAE 계산
gb_train_pred = gb_model.predict(X_train)
train_mae = mean_absolute_error(y_train, gb_train_pred)
print(f"Train MAE: {train_mae:.4f}")
# 검증 세트의 MAE 계산
val_mae = mean_absolute_error(y_val, gb_val_pred)
print(f"Validation MAE: {val_mae:.4f}")
MAE가 다른 모델에 비해 1000 이상 높게 나와서 재고 필요
from sklearn.linear_model import ElasticNet
# ElasticNet 회귀 모델 초기화
elastic_model = ElasticNet(alpha=0.1, l1_ratio=0.7, random_state=42, max_iter=10000)
# 모델 학습
elastic_model.fit(X_train, y_train)
# 검증 및 테스트 세트에 대한 예측
elastic_val_pred = elastic_model.predict(X_val)
elastic_test_pred = elastic_model.predict(X_test)
# 학습 세트의 MAE 계산
elastic_train_pred = elastic_model.predict(X_train)
train_mae = mean_absolute_error(y_train, elastic_train_pred)
print(f"Train MAE: {train_mae:.4f}")
# 검증 세트의 MAE 계산
val_mae = mean_absolute_error(y_val, elastic_val_pred)
print(f"Validation MAE: {val_mae:.4f}")
from lightgbm import LGBMRegressor
from sklearn.metrics import mean_absolute_error
from sklearn.model_selection import cross_val_predict, KFold
from sklearn.model_selection import RandomizedSearchCV
import numpy as np
# 검증 세트의 예측을 메타 모델의 입력으로 결합
meta_X = np.column_stack((xgb_val_pred, lgb_val_pred, rf_val_pred, gb_val_pred))
meta_y = y_val
# 테스트 세트의 예측을 메타 모델의 입력으로 결합
meta_X_test = np.column_stack((xgb_test_pred, lgb_test_pred, rf_test_pred, gb_test_pred))
# LGBMRegressor 메타 모델의 하이퍼파라미터 탐색 공간 정의
param_dist = {
'learning_rate': [0.01, 0.05, 0.1],
'max_depth': [3, 5, 7, 9],
'num_leaves': [31, 63, 127],
'min_child_samples': [5, 10, 20, 30],
'min_split_gain' : [0.2, 0.3, 0.5],
}
# LGBMRegressor 메타 모델 초기화
base_model = LGBMRegressor(random_state=42, force_row_wise=True)
# RandomizedSearchCV를 사용한 하이퍼파라미터 튜닝
kf = KFold(n_splits=5, shuffle=True, random_state=42)
random_search = RandomizedSearchCV(base_model, param_distributions=param_dist,
n_iter=50, cv=kf, scoring='neg_mean_absolute_error',
random_state=42, n_jobs=-1)
# 하이퍼파라미터 튜닝 수행
random_search.fit(meta_X, meta_y)
# 최적의 모델 선택
best_model = random_search.best_estimator_
# 교차 검증을 사용한 메타 모델의 성능 평가
cv_predictions = cross_val_predict(best_model, meta_X, meta_y, cv=kf)
cv_mae = mean_absolute_error(meta_y, cv_predictions)
print(f"Meta Model Cross-Validation MAE: {cv_mae:.4f}")
# 전체 데이터로 최종 모델 학습
best_model.fit(meta_X, meta_y)
# 최종 예측 수행
final_pred = best_model.predict(meta_X_test)
# 특성 중요도 출력
feature_importance = best_model.feature_importances_
feature_names = ['XGBoost', 'LightGBM', 'RandomForest', 'GradientBoosting', 'ElasticNet Regressor']
for name, importance in zip(feature_names, feature_importance):
print(f"{name} importance: {importance:.4f}")