PythonでXGBoostを使う

最近XGBoostに触れる機会がありましたので、使い方を確認します。
(今まで使わなかったことの方がどちらかというと珍しいのかもしれません。)

XGBoost

XGBoost (eXtreme Gradient Boosting) は、単純な分類器 (ex. 決定木) を組み合わせたアンサンブル学習モデルの実装 (フレームワーク) です。Pythonをはじめとした各種言語のライブラリで提供されています。

github.com

乳がんデータセットを分類する

それではPythonでXGBoostを使ってみます。予め pip install xgboost でインストールしておきます。

今回はUCI Machine Learning Repositoryの乳がんデータセットを使います。

archive.ics.uci.edu

ロードすると569行 x 32列のデータとなりますので、整形して学習データとテストデータに分離します。

  • 1列目はID (なのでここで捨ててます)
  • 2列目はラベルで、"M"が悪性、"B"が良性を意味します -> 変数y
  • 3〜32列目 (30列) は実数の特徴量となってます (細胞核の計測値のようです) -> 変数X
import pandas as pd

from sklearn.model_selection import train_test_split

# UCI Machine Learning Repositoryから乳がんデータセットをダウンロード
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/wdbc.data'
df = pd.read_csv(url, header=None)

# Mは1, Bは0に置き換える
y = df[1]
y = y.str.replace('M', '1').str.replace('B', '0').astype(int)

# 3〜32列目を特徴量として使う
X = df.iloc[:, 2:]

# 学習データとテストデータを4:1で分離
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)

それではXGBoostを使っていきます。

XGBoostはDMatrixに整形したデータとパラメータをtrainメソッドに渡してモデルを作成します。

  • DMatrix型はPandasのDataFrame以外に、numpyのarrayやCSVファイルなどを入力ソースとして扱えます
  • パラメータの詳細はこちら
    • max_depthは決定木の高さです
    • etaは学習率で、0〜1の実数で指定します
    • 0/1の予測ですので、objectiveには"binary:logistic"を渡してます
    • デフォルトでは学習過程が出力されます (パラメータsilentに1を渡すと非表示になります)
import xgboost as xgb

# 学習データからXGBoost用のデータを生成
dm_train = xgb.DMatrix(X_train, label=y_train)

# パラメータ
param = {
    'max_depth': 2, 
    'eta': 1, 
    'objective': 'binary:logistic'
}

# XGBoostで学習
model = xgb.train(param, dm_train)
# [05:48:27] /workspace/src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 6 extra nodes, 0 pruned nodes, max_depth=2
# [05:48:27] /workspace/src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 6 extra nodes, 0 pruned nodes, max_depth=2
# [05:48:27] /workspace/src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 6 extra nodes, 0 pruned nodes, max_depth=2
# [05:48:27] /workspace/src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 6 extra nodes, 0 pruned nodes, max_depth=2
# [05:48:27] /workspace/src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 4 extra nodes, 0 pruned nodes, max_depth=2
# [05:48:27] /workspace/src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 6 extra nodes, 0 pruned nodes, max_depth=2
# [05:48:27] /workspace/src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 6 extra nodes, 0 pruned nodes, max_depth=2
# [05:48:27] /workspace/src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 4 extra nodes, 0 pruned nodes, max_depth=2
# [05:48:27] /workspace/src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 6 extra nodes, 0 pruned nodes, max_depth=2
# [05:48:27] /workspace/src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 6 extra nodes, 0 pruned nodes, max_depth=2

plot_importanceメソッドで特徴量の重要度を可視化できます。

import matplotlib

# 特徴量の重要度を表示
xgb.plot_importance(model)

また、to_graphvizメソッドで学習した木も表示できます。別途graphvizをインストールしておく必要があります。
(アンサンブル学習と言いながら、木1本だけになってしまってます。上の学習過程の出力のとおりですね。)

# 木の表示
xgb.to_graphviz(model)

学習したモデルでpredictメソッドにデータを渡して予測します。精度としては95.6%でした。

  • テストデータも、忘れずにDMatrixにします
  • ロジスティック回帰の値ですので、0〜1の実数が返ってきます
# テスト用のデータを生成
dm_test = xgb.DMatrix(X_test)

# 予測
y_pred = model.predict(dm_test)
# array([2.4190381e-01, 9.9575341e-01, 3.6941297e-04, 9.9836344e-01,
#        ...

# 精度
accuracy = sum(((y_pred > 0.5) & (y_test == 1)) | ((y_pred <= 0.5) & (y_test == 0))) / len(y_pred)
# 0.956140350877193

まとめ

PythonでのXGBoostの使い方をざっくりみていきました。