【Kaggle】xgboostを使ってみる

#1.目的

Kaggleのようなコンペでは、xgboostやLGBMといった勾配ブースティングがよく使われている。
ただ、これらについては参考になる記事やサイトが少ないと感じたこと／自分で実装する際に結構困ったので、今回はxgboostについて、自分が試したこと・各パラメータの意味合いを記しておくことが目的。

※参考書籍
今回は基本的にこちらの書籍に則って実装しています。
「Kaggleで勝つ　データ分析の技術」
https://www.amazon.co.jp/Kaggle%E3%81%A7%E5%8B%9D%E3%81%A4%E3%83%87%E3%83%BC%E3%82%BF%E5%88%86%E6%9E%90%E3%81%AE%E6%8A%80%E8%A1%93-%E9%96%80%E8%84%87-%E5%A4%A7%E8%BC%94/dp/4297108437

#2.勾配ブースティングの利点
・欠損値の補完が不要
・冗長な特徴量があっても問題ない（相関が高い説明変数があってもそのまま使える）

・ランダムフォレストとの違いは、木を直列に作っている点。

上記の様な特徴があり、勾配ブースティングはよく使われるようです。

#3.xgboostを使ってみる
今回はkaggleのHousepriceを使用して実装してみる。

https://www.kaggle.com/c/house-prices-advanced-regression-techniques

##(1)前処理

###(ⅰ)インポート
```python
import numpy as np
import pandas as pd

#データ分割用
from sklearn.model_selection import train_test_split

#XGBoost
import xgboost as xgb
```

###(ⅱ)データ読み込み・結合
```python
#データ読み込み
df_train = pd.read_csv("train.csv")
df_test = pd.read_csv("test.csv")

#データ結合
df_train["TrainFlag"] = True
df_test["TrainFlag"] = False

df_all = df_train.append(df_test)
df_all.index = df_all["Id"]
df_all.drop("Id", axis = 1, inplace = True)
```

###(ⅲ)ダミー変数化

```python
df_all = pd.get_dummies(df_all, drop_first=True)
```

###(ⅳ)データ分割

```python
#df_allを訓練データとテストデータに再度分ける
df_train = df_all[df_all["TrainFlag"] == True]
df_train = df_train.drop(["TrainFlag"], axis = 1)

df_test = df_all[df_all["TrainFlag"] == False]
df_test = df_test.drop(["TrainFlag"], axis = 1)
df_test = df_test.drop(["SalePrice"], axis = 1)
```

```python
#データ分割
y = df_train["SalePrice"].values
X = df_train.drop("SalePrice", axis=1).values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1234)
```

##(2)xgboostを使ってみる

###(ⅰ)xgboostのデータ作成

```python
dtrain = xgb.DMatrix(X_train, label=y_train)
dvalid = xgb.DMatrix(X_test, label=y_test)
dtest = xgb.DMatrix(df_test.values)
```

xgboostを使うには、それ専用のデータを「xgb.DMatrix」で加工する必要がある。

####※注意点※
3行目で「df_test.values」にしている。
これは、df_testはDataFrame形式のため、.valuesで値（Numpy配列）にしておかないと、後々のモデル訓練でエラーになるので注意。

###(ⅱ)パラメータ設定

```python
params = {
        'objective': 'reg:squarederror','silent':1, 'random_state':1234, 
        # 学習用の指標 (RMSE)
        'eval_metric': 'rmse',
    }
num_round = 500
watchlist = [(dtrain, 'train'), (dvalid, 'eval')]#訓練データはdtrain、評価用のテストデータはdvalidと設定
```

####※パラメータの説明※
・objective：最小化させるべき損失関数の指定。デフォルトはlinear。
・silent：モデル実行のログのはき方の指定。デフォルトは0（ログを出力する）。
・eval_metric：データの評価指標。rmseやloglossがある。
・num_round：最大の学習回数。


###(ⅲ)モデル訓練

```python
model = xgb.train(params,
                    dtrain,#訓練データ
                    num_round,#設定した学習回数
                    early_stopping_rounds=20,
                    evals=watchlist,
                    )
```

・early_stopping_rounds：連続で20回精度が向上しなければ、学習を打ち切るという意味。num_roundで最大学習回数を設定しているが、その前にここで設定したearly_stopping_roundsの回数分精度が向上されなければ打ち切る。

###(ⅳ)予測

```python
#予測
prediction_XG = model.predict(dtest, ntree_limit = model.best_ntree_limit)

#小数を丸めている
prediction_XG = np.round(prediction_XG)
```

・ntree_limitについて
model.best_ntree_limitにすることで、最も良い精度の木の数を設定できる

###(ⅴ)提出用ファイル作成

```python
submission = pd.DataFrame({"id": df_test.index, "SalePrice": prediction_XG})
```

以上で終了です！

#4.結び
いかがでしたでしょうか。
コードをコピペすれば実装できますが、各コードがどんな意味を持っているのかざっくりでいいので知ることは非常に重要だと感じます。

少しでも理解の深化の一助になりますと幸いです。