初心者のXGBoostを使った実装と説明

#はじめに
Kaggleによく出てくるXGBoost。
コードを読んでも分からない箇所が多かったので、初心者なりに調べてまとめてみました。
なるべくわかりやすく、難しい言葉をかみ砕いて書いているため、正確性に欠けているのでご了承ください。
加筆、修正等あれば遠慮なく教えてください。
今回は実装しながらXGBoostについて説明していきます。


#本記事の内容
##目次
1.XGBoostとは
2.XGBoostをインポートする。
3.データセットをインポート
4.データセットの分割、形式の変換
5.モデルの定義と訓練
6.モデルの評価
7.特徴量の重要度を確認
##動作環境
Windows: 10
Anaconda
Python: 3.7.4
pandas: 0.25.1
numpy: 1.16.5
scikit-learn: 0.21.2
XGBoost: 0.90
##この記事で使用するデータセット
今回はscikit-learnの乳がんデータセット（Breast cancer wisconsin [diagnostic] dataset）を利用します。
データセットには乳癌の細胞核に関する特徴データが入っており、今回は乳癌が「悪性腫瘍」か「良性腫瘍」かを判定します。
##注意点
本記事はXGBoostの細かいパラメータ等は説明しておりません。
##ソースについて
本記事のソースは以下に上げています。
https://github.com/Bacchan0718/qiita/blob/master/xgb_breast_cancer_wisconsin.ipynb

#1.XGBoostとは
XGBoost (eXtreme Gradient Boosting) は決定木の勾配ブースティングアルゴリズムを実装したものです。
決定木は以下の図のような樹木状のモデルを使いデータセットを分類し、その結果に影響を与えた要因を分析し、その分類結果を利用して将来の予測を行う手法です。
![決定木.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620484/9d56ce89-7806-6ef4-92ad-f1e2a0bb7fd2.png)

勾配ブースティングアルゴリズムは「勾配」と「ブースティング」を分けて説明します。
勾配とは、２つの値の差を最小にし、予測誤差を小さくすることです。
ブースティングは弱識別機（精度のよくない判断する処理）を直列的に結合し、
予測の正確性を高めるアルゴリズムです。
（ここでの弱識別機は決定木のことです。）
![ブースティング.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620484/d026fc45-dcb3-caa0-f232-054579f3101c.png)
参照リンク
XGBoost: https://logmi.jp/tech/articles/322734
XGBoost: http://kamonohashiperry.com/archives/209
勾配法: https://to-kei.net/basic-study/neural-network/optimizer/
損失関数: https://qiita.com/mine820/items/f8a8c03ef1a7b390e372
決定木: https://enterprisezine.jp/iti/detail/6323

#2.XGBoostインストール
**(1)Anaconda Promptを開く**
スタート>Anaconda 3 (64-bit)>Anaconda Prompt
から開きます。
![XGBoostインストール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620484/8ce65b8f-92ac-aa8e-6452-1d9fc6398bd4.png)

**(2)conda install -c anaconda py-xgboostを実行**

**(3)AnacondaからTerminalを開く**
AnacondaNavigator>インストールする仮想環境のさんかくをクリック>Open Terminal
から開きます。
![XGBoostインストール2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620484/f9c18097-fea7-72ac-8663-5483972eca9a.png)

**(4)conda install py-xgboostを実行**
実行中にProceed ([y]/n)?と表示されるので「y]を入力しEnterを押します。

これでjupyter notebookでimport xgboost as xgbとすれば使えます。

**注意点**
XGBoostは動作環境によってインストール方法が異なります。
本記事と異なる環境の場合、この方法だとインストールできないかもしれないです。

#3.データセット読み込み

scikit-learnのデータセットは以下の方法でインポートできます。

```python:xgb_breast_cancer_wisconsin.ipynb
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
cancer = load_breast_cancer()
```
変数cancerはBunch型（dictionaryのサブクラス）で、
説明変数がdata、目的変数がtargetに格納されています。

```python:xgb_breast_cancer_wisconsin.ipynb
X = cancer.data
y = cancer.target
```
目的変数は腫瘍が癌細胞か良性の細胞かの判定結果になります。
癌細胞の場合0、良性の場合1になります。

概要はDSCRに格納されています。

```python:xgb_breast_cancer_wisconsin.ipynb
print(cancer.DESCR)
```
データセットの詳しい説明は以下にあります。
https://ensekitt.hatenablog.com/entry/2018/08/22/200000

#4.データセットの分割、形式の変換
訓練データとテストデータに分割します。

```python:xgb_breast_cancer_wisconsin.ipynb
import numpy as np
X_train, X_test, Y_train, Y_test = train_test_split(X, y, test_size=0.2)
```
分割後、XGBoostが扱うデータセットの形式にします。
feature_namesには特徴量の可視化のため、カラム名を渡しておきます。

```python:xgb_breast_cancer_wisconsin.ipynb
import xgboost as xgb
xgb_train = xgb.DMatrix(X_train, label=Y_train, feature_names=cancer.feature_names)
xgb_test = xgb.DMatrix(X_test, label=Y_test, feature_names=cancer.feature_names)
```

# 5.モデルの定義と訓練
パラメータの定義をします。
今回は細かいパラメータを設定せずに、Learning Parameters(学習タスクパラメータ)の
objectiveに「binary:logistic」引数を設定します。
この引数は2項分類であてはまる確率を返します。

```python:xgb_breast_cancer_wisconsin.ipynb
param = {
    # 二値分類問題
    'objective': 'binary:logistic',  
} 
```
モデルを学習します。

```python:xgb_breast_cancer_wisconsin.ipynb
model = xgb.train(param, xgb_train)
```
参照リンク: https://blog.amedama.jp/entry/2019/01/29/235642
#6.モデルの評価
学習したモデルを用いて、検証用データが各クラスに分類される確率を計算します。

```python:xgb_breast_cancer_wisconsin.ipynb
y_pred_proba = model.predict(xgb_test)
```
y_pred_probaの中身を確認します。

```python:xgb_breast_cancer_wisconsin.ipynb
print(y_pred_proba)
```
中身は以下になります。

```
[0.974865   0.974865   0.974865   0.974865   0.02652072 0.02652072
 0.02652072 0.93469375 0.15752992 0.9459383  0.05494327 0.974865
 0.974865   0.793823   0.95098037 0.974865   0.93770874 0.02652072
 0.92342764 0.96573967 0.92566985 0.95829874 0.9485401  0.974865
 0.96885294 0.974865   0.9670915  0.9495995  0.9719596  0.9671308
 0.974865   0.974865   0.9671308  0.974865   0.974865   0.974865
 0.96525717 0.9248287  0.4881295  0.974865   0.9670915  0.02652072
 0.974865   0.04612969 0.9459383  0.7825349  0.974865   0.02652072
 0.04585124 0.974865   0.1232813  0.974865   0.974865   0.3750245
 0.9522517  0.974865   0.05884887 0.02652072 0.02652072 0.02652072
 0.974865   0.94800293 0.9533147  0.974865   0.9177746  0.9665209
 0.9459383  0.02652072 0.974865   0.974865   0.974865   0.974865
 0.6874632  0.72485    0.31191444 0.02912194 0.96525717 0.09619693
 0.02652072 0.9719596  0.9346858  0.02652072 0.974865   0.02652072
 0.0688739  0.974865   0.64381874 0.97141886 0.974865   0.974865
 0.974865   0.1619863  0.974865   0.02652072 0.02652072 0.974865
 0.9670915  0.45661741 0.02652072 0.02652072 0.974865   0.03072577
 0.9670915  0.974865   0.9142289  0.7509865  0.9670915  0.02652072
 0.02652072 0.9670915  0.02652072 0.78484446 0.974865   0.974865  ]
```
データセットの目的変数は2項分類のため、値を0か1にする必要があります。
しきい値（基準となる値）を0.5以上の時は1、0.5未満の時は0となるようにし、
0と1に変換します。

```python:xgb_breast_cancer_wisconsin.ipynb
y_pred = np.where(y_pred_proba > 0.5, 1, 0)
```
精度を検証します。
今回はAccuracyを使って正解率を検証します。

```python:xgb_breast_cancer_wisconsin.ipynb
from sklearn.metrics import accuracy_score
acc = accuracy_score(Y_test, y_pred)
```
精度は0.9912280701754386となりました。

#7.特徴量の確認
特徴量とは、学習の入力に使う測定可能な特性のことです。
説明変数のなかで、強い関連がある特徴量は何があるかグラフで確認します。
参照リンク: https://qiita.com/daichildren98/items/ebabef57bc19d5624682
グラフはfig.savefigでpngで保存できます。

```python:xgb_breast_cancer_wisconsin.ipynb
import matplotlib.pyplot as plt
fig, ax1 = plt.subplots(figsize=(8,15))
xgb.plot_importance(model, ax=ax1)
plt.show()
fig.savefig("FeatureImportance.png")
```
![FeatureImportance.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620484/caa177ae-fe6f-1937-5b9f-6011b2f62fec.png)

グラフを見ると、worst textureに強い関連があることが分かりました。

#おわりに
KaggleでよくXGBoostが出てくるのですが、はじめて見たときは全く分からなかったので調べてまとめてみました。
パラメータについてはまた調べてまとめようと思います。