저번 글에는 regression 4종으로 예측해보고, 결과가 가장나은 ElasticNet의 결과로 제출 해보았다.
이번글에는 조금더 핫하고 자주쓰이는 모델 중 LightGBM, XGBoost, GradientBoost 그리고 꼽사리로 RandomForest와 앙상블 기법으로 등수를 올려보자.
prediction with ensemble algorithms¶
임포팅, 데이터 로딩
# Imports
import pandas as pd
import numpy as np
from sklearn.model_selection import cross_val_score, train_test_split, KFold
from sklearn.preprocessing import StandardScaler, RobustScaler
from sklearn.linear_model import LinearRegression, RidgeCV, LassoCV, ElasticNetCV
from sklearn.metrics import mean_squared_error, make_scorer
from IPython.display import display
import matplotlib.pyplot as plt
import warnings
def ignore_warn(*args, **kwargs): pass
warnings.warn = ignore_warn #ignore annoying warning (from sklearn and seaborn)
%matplotlib inline
pd.set_option('display.float_format', lambda x: '%.3f' % x)
pd.set_option('display.max_colwidth', -1)
pd.set_option('display.max_rows', 500)
# 데이터 읽어오기
# 이전 글에서 데이터 전처리를 잘 따라왔다면 해당경로에 데이터가 저장되어 있을것이다.
# 동일한 데이터가 아니더라도 똑같은 포맷이라면 동일한 방식으로 사용해 볼 수 있다.
X_train = pd.read_csv("../data/X_train.csv", index_col=0, header=0)
X_test = pd.read_csv("../data/X_test.csv", index_col=0, header=0)
y_train = pd.read_csv("../data/y_train.csv", header=None, index_col = 0).values[:, 0]
Id_test = pd.read_csv("../data/Id_train.csv", index_col=0, header=None).values[:, 0]
print(X_train.shape)
print(X_test.shape)
print(y_train.shape)
print(Id_test.shape)
Ensembel Modeling
- GradientBoostingRegressor
- XGBRegressor
- LGBMRegressor
- RandomForest
네 가지에 대해서 모델을 돌리고 평가해보자.
#Validation function
n_folds = 5
def rmsle_cv(model):
kf = KFold(n_folds, shuffle=True, random_state=42).get_n_splits(X_train.values)
rmse= np.sqrt(-cross_val_score(model, X_train.values, y_train, scoring="neg_mean_squared_error", cv = kf))
return(rmse)
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
import xgboost as xgb
import lightgbm as lgb
model_gb = GradientBoostingRegressor(n_estimators=3000, learning_rate=0.05,
max_depth=4, max_features='sqrt',
min_samples_leaf=15, min_samples_split=10,
loss='huber')
model_xgb = xgb.XGBRegressor(colsample_bytree=0.4603, gamma=0.0468,
learning_rate=0.05, max_depth=3,
min_child_weight=1.7817, n_estimators=2200,
reg_alpha=0.4640, reg_lambda=0.8571,
subsample=0.5213, silent=1,
random_state =7, nthread = -1)
model_lgb = lgb.LGBMRegressor(objective='regression',num_leaves=5,
learning_rate=0.05, n_estimators=720,
max_bin = 55, bagging_fraction = 0.8,
bagging_freq = 5, feature_fraction = 0.2319,
feature_fraction_seed=9, bagging_seed=9,
min_data_in_leaf =6, min_sum_hessian_in_leaf = 11)
model_rf = RandomForestRegressor(n_estimators=3000,
max_depth=4, max_features='sqrt',
min_samples_leaf=15, min_samples_split=10)
score = rmsle_cv(model_gb)
gb_score = score.mean()
print("GradientBoostingRegressor score: {:.4f} ({:.4f})".format(score.mean(), score.std()))
score = rmsle_cv(model_xgb)
xgb_score = score.mean()
print("XGBRegressor score: {:.4f} ({:.4f})".format(score.mean(), score.std()))
score = rmsle_cv(model_lgb)
lgb_score = score.mean()
print("LGBMRegressor score: {:.4f} ({:.4f})".format(score.mean(), score.std()))
score = rmsle_cv(model_rf)
print("RandomForestRegressor score: {:.4f} ({:.4f})".format(score.mean(), score.std()))
GradientBoostingRegressor, XGBRegressor, LGBMRegressor 세가지는 Linear Regressor 보다 성능이 잘나왔지만,
Random forest 는 성능이 현저히 낮았다. 파라매터 튜닝을 안한 탓도 있겠지만 통상적으로 이렇게 나온다.
제일 잘나온 xgb로 제출을 해보니 0.12517 로 상위 22% 정도에 Rank 되었다 !
ElasticNet보다 8% 향상 된 수치이다.
또 다른 중요 차이점이 있다면 train set의 결과와 차이가 줄어들었다. 즉, 오버 피팅이 줄어든 샘이다.
오버 피팅에 강하다고 하는 xgb의 강점이 여기서도 빛을 발한다.
하지만 아직 조금 아쉽다.
등수를 조금 더 향상 시켜보도록 하자.
Ensemble of Ensemble Modeling
결과가 잘나온 앙상블 모델 3개를 앙상블 하면 결과가 더 잘나올 것이다. 진행해보자.
model_gb.fit(X_train, y_train)
model_xgb.fit(X_train, y_train)
model_lgb.fit(X_train, y_train)
pred_gb = model_gb.predict(X_test)
pred_xgb = model_xgb.predict(X_test)
pred_lgb = model_lgb.predict(X_test)
total_weight = (1. / gb_score) + (1. / xgb_score) + (1. / lgb_score)
pred = (pred_gb * (1. / gb_score) + pred_xgb * (1. / xgb_score) + pred_lgb * (1. / lgb_score)) / total_weight
pd_test_pred = pd.DataFrame({'Id': Id_test, 'SalePrice': np.expm1(pred)})
pd_test_pred.to_csv('submission.csv', index=False)
총합이 1이 되게 모델마다 weight를 정해주었다.
캐글에서는 임의로 개발자의 직감에 의해서 정하는 경우가 많았던것 같은데
나는 train set 결과인 rmse의 역수에 비례해서 가중치를 주었다.
각 모델의 가중치와 예측값을 곱해서 최종 결과물 산출했다.
그 결과 0.12176을 기록해 상위 13% 까지 올랐다!
내심 10% 안에 들기를 바랬는데 무리였다보다.
다음번엔 잘나온 모델들은 합쳐서 ensemble이 아닌 stacking 기법을 사용해보자.
# 티스토리에 올리기 위한 레이아웃 조정
from IPython.core.display import display, HTML
display(HTML("<style>.container {width:100% !important;}</style>"))
다음글에는 10% 이내를 목표로 모델 stacking 을 진행해보자.
'ML | DL | Big data > Projects' 카테고리의 다른 글
kaggle 주택 가격 예측(5) - Stacking과 Blending으로 등수 올리기(상위 6%) (3) | 2020.08.24 |
---|---|
kaggle 주택 가격 예측(3) - 간단한 regression으로 예측하기(상위 30%) (0) | 2020.08.20 |
kaggle 주택 가격 예측(2) - Data preprocess / Feature engineering (0) | 2020.08.17 |
kaggle 주택 가격 예측(1) - 포괄적인 데이터 탐색 분석 / EDA (0) | 2020.08.10 |
댓글