KaggleのHouse Prices CompetitionをXGBoostで解く
machinelearning以前TitanicをやったXGBoostでHome Prices Competitionに挑戦する。
KaggleのTitanicのチュートリアルをXGBoostで解く - sambaiz-net
import pandas as pd
df_train = pd.read_csv('house-prices/train.csv')
df_test= pd.read_csv('house-prices/test.csv')
前処理
目的変数であるSalePriceと相関のある変数を抽出する。XGBoostは欠損値をそのまま扱うことができるので特に何もしていない。
KaggleのHome Prices CompetitionのKernelからデータの探り方を学ぶ - sambaiz-net
use_columns = df_train.corr()['SalePrice'].drop('SalePrice').where(lambda x: abs(x) > 0.5).dropna().keys()
# Index(['OverallQual', 'YearBuilt', 'YearRemodAdd', 'TotalBsmtSF', '1stFlrSF', 'GrLivArea', 'FullBath', 'TotRmsAbvGrd', 'GarageCars', 'GarageArea'], dtype='object')
def preprocess(df):
return df[use_columns].copy()
df_train_p = preprocess(df_train)
df_train_p['SalePrice'] = df_train['SalePrice']
df_test_p = preprocess(df_test)
ハイパーパラメータの最適化
ベイズ最適化でハイパーパラメータを決める。 他にもいろいろなパラメータがあるが、やみくもに増やしても提出した後のスコアが良くならなかった。
ベイズ最適化でランダムフォレストとXGBoostの良いハイパーパラメータを探す - sambaiz-net
! pip install bayesian-optimization
import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from bayes_opt import BayesianOptimization
num_boost_round=500
def optimize_params(df):
def train(
learning_rate,
colsample_bytree,
sub_sample):
train_x = df.drop('SalePrice', axis=1)
train_y = df.SalePrice
(train_x, test_x ,train_y, test_y) = train_test_split(train_x, train_y, test_size = 0.3)
dtrain = xgb.DMatrix(train_x, label=train_y)
param = {
'learning_rate': learning_rate,
'colsample_bytree': colsample_bytree,
'sub_sample': sub_sample}
bst = xgb.train(param, dtrain, num_boost_round)
preds = bst.predict(xgb.DMatrix(test_x))
# Root-Mean-Squared-Error (RMSE) between the logarithm of the predicted value and the logarithm of the observed sales price
return -np.sqrt(mean_squared_error(
np.log(np.clip(np.nan_to_num(test_y), 1e-6, None)),
np.log(np.clip(np.nan_to_num(preds), 1e-6, None))
))
bo = BayesianOptimization(
train,
{'learning_rate': (0.01, 0.5), # default=0.3
'colsample_bytree': (0.1, 1.0), # default=1
'sub_sample': (0.1, 1.0), # default=1
})
bo.maximize(n_iter=50, alpha=1e-5)
return bo.max['params']
params = optimize_params(df_train_p)
結果こんな感じ。
print(params)
# => {'colsample_bytree': 1.0, 'learning_rate': 0.01, 'sub_sample': 0.28979827351242066}
実行
学習して予測結果を出力する。
bst = xgb.train(
params,
xgb.DMatrix(df_train_p.drop('SalePrice', axis=1).values, label=df_train_p.SalePrice),
num_boost_round)
preds = bst.predict(xgb.DMatrix(df_test_p.values))
submit_data = pd.Series(preds, name='SalePrice', index=df_test['Id'])
submit_data.to_csv('submit.csv', header=True)
スコアは 0.15509
だった。