どこにでもいる30代SEの学習ブログ

主にプログラミング関連の学習内容。読んだ本の感想や株式投資についても書いてます。

【機械学習】xgboostでクロスバリデーション(Cross Validation)

f:id:predora005:20200921201315j:plain
<xgboostでクロスバリデーション(Cross Validation)>*1

※ 2020/04/06にQrunchで書いた記事を移行しました。

xgboost.cv()を使用したクロスバリデーション(交差検証)の方法を簡単にまとめました。 クロスバリデーションとは、学習データの一部を検証用データとして使用する手法です。

Wikipedaによれば次の通りです。

標本データを分割し、その一部をまず解析して、残る部分でその解析のテストを行い、解析自身の妥当性の検証・確認に当てる手法

有名なのは、K-Foldです。どの学習データも1回は検証用データに使われるように、学習と検証を複数回行います。

K-Fold以外の検証手法もありますが、下記サイトの説明が分かりやすかったです。

交差検証(cross validation/クロスバリデーション)の種類を整理してみた | AIZINE(エーアイジン)

基本的な使い方

学習データには、scikit-learnのirisデータを使用しました。多クラス分類です。

nfold=5でデータを5分割にし、verbose_eval=Trueイテレーション毎にmerror, stdを表示します。 merrorは多クラス分類のエラー率、stdは標準偏差です。

import pandas as pd
import xgboost as xgb
from sklearn.datasets import load_iris

iris= load_iris()
iris_data = pd.DataFrame(iris.data, columns=iris.feature_names)
iris_target = pd.Series(iris.target)

dtrain = xgb.DMatrix(iris_data, label=iris_target)
param = {'objective': 'multi:softmax', 'num_class': 3}
num_round = 10

xgb.cv(param, dtrain, num_round, nfold=5, verbose_eval=True)
# [0]  train-merror:0.02333+0.00972    test-merror:0.02667+0.03266
# [1]  train-merror:0.02167+0.00850    test-merror:0.02667+0.03266
# 〜〜〜 (途中省略) 〜〜〜
# [8]  train-merror:0.01000+0.00333    test-merror:0.03333+0.04216
# [9]  train-merror:0.01000+0.00333    test-merror:0.03333+0.04216

アーリーストップ

学習が改善しなくなったら学習を早期停止します。 early_stopping_rounds=10の場合、10回前と比較して評価指標が改善していなければ学習を停止します。

num_round = 100
xgb.cv(param, dtrain, num_round, nfold=5, verbose_eval=True, 
        early_stopping_rounds=10)

stratifiedとshuffleを追加

stratified=Trueにすると、学習データ・評価データに含まれるクラスの比率が同じになるように調整してくれます。

num_round = 100
xgb.cv(param, dtrain, num_round, nfold=5, verbose_eval=True, 
        early_stopping_rounds=10, stratified=True, shuffle=True)

評価指標(metric)の変更

metrics=('mlogloss')で、評価指標を'merror'から'mlogloss'に変更します。

num_round = 100  
xgb.cv(param, dtrain, num_round, nfold=5, verbose_eval=True,   
        early_stopping_rounds=10, stratified=True, shuffle=True,
        metrics=('mlogloss'), show_stdv=False)
# [0]  train-mlogloss:0.74531  test-mlogloss:0.77697
# [1]  train-mlogloss:0.53348  test-mlogloss:0.58439
# 〜〜〜 (途中省略) 〜〜〜
# [33] train-mlogloss:0.01282  test-mlogloss:0.09777
# [34] train-mlogloss:0.01275  test-mlogloss:0.09755

終わりに

よく使いそうなパラメータだけをまとめましたが、まだまだパラメータはあります。 詳しい使い方は、公式のExampleが参考になります。

[備忘録] xgboost.cvの全パラメータ

パラメータ名 内容 デフォルト値
params ハイパーパラメータ 無し
dtrain 学習データ 無し
num_boost_round 学習回数 10
nfold 分割数 3
stratified 層別サンプリングするか否か False
folds ※1 None
metrics 評価指標 ()
obj ※2 None
feval カスタムの評価関数 ※3 None
maximize fevalを最大かするか否か False
early_stopping_rounds 指定した回数毎に評価指標が改善しなければ学習を停止する None
fpreproc 前処理関数 ※4 None
as_pandas pandasのDataFrameを返すか否か True
verbose_eval 進捗状況を表示するか否か ※5 None
show_stdv 標準偏差を表示するか否か True
seed 乱数のシード 0
callbacks コールバック関数のリスト ※6 None
shuffle シャッフルするか否 True

folds (※1)

分割の仕方を自分で指定する方法で、以下のパラメータを指定できます。

  • KFoldオブジェクト(scikit-learn)
  • StratifiedKFoldsオブジェクト(scikit-learn)
  • インデックスを格納したタプルのリスト(リストの数はnfoldと一致する)

obj (※2)

目的関数(objective function)を自作するときに使用します。

paramsで指定する'objective'が目的関数に該当します。通常は'objective'に'reg:logistic'や'reg:squarederror'を指定します。

自作する場合は'obj'に自作関数を指定します。

詳細は、公式のExampleを見ると概ね分かります。 xgboost/custom_objective.py at master · dmlc/xgboost

feval (※3)

カスタムの評価関数です。(preds, dtrain)を受け取り、(metric_name, result)のペアを返します。metric_nameは評価指標の名前、resultは評価値です。

fpreproc (※4)

前処理を行う関数です。(dtrain, dtest, param)を受け取り、受け取ったオブジェクトに前処理を行います。前処理後の(dtrain, dtest, param)を返します。

verbose_eval (※5)

None, True, 整数値のいずれかを指定します。

  • None:ndarrayを Returnしたときに進捗状況を表示する
  • True:ブースティングのたびに進捗状況を表示する
  • 整数値:指定した回数のブースティング毎に進捗状況を表示する

callbacks (※6)

イテレーションの終了毎に呼ばれるコールバック関数のリストです。 xgboost側で用意されたCallback APIを利用することもできます。

参考資料

3.1. Cross-validation: evaluating estimator performance — scikit-learn 0.22.2 documentation

*1:Gerd AltmannによるPixabayからの画像