项目作者: GINK03

项目描述 :
fizzbuzz by xgboost
高级语言: Python
项目地址: git://github.com/GINK03/xgboost-fizzbuzz.git
创建时间: 2014-04-01T06:33:40Z
项目社区:https://github.com/GINK03/xgboost-fizzbuzz

开源协议:

下载


XGBoost fizzbuzz

XGBoostのFizzBuzzです  

勾配ブースティングでもFizzBuzzできるという例を示します

やろうと思った動機

DeepLearningならばFizzBuzzの3の倍数と5の倍数と15の倍数の時に、特定の動作をするというルールを獲得することは容易なのですが、他の機械学習アルゴリズムはどうでしょうか

XGBoostはその決定木の性質と、勾配ブースティングの学習アルゴリズムを解析的に説明した論文の内容を見ると、特定のルールを獲得することは難しくないんじゃないかと思いました[1]

ただ、FizzBuzzを数値として扱ってしまうと、かなり厄介で、連続する値が大きい小さいなどで判別するのは容易ではありません

DeepLearning時と同じように、Character Levelで入力を扱います

具体的な数値データの取り扱い

数字を文字表現として皆して、各桁の数字を一つの特徴量として扱います



図1. データの取り扱い

クラスの設定、目的関数の設定

クラスは”3の倍数の時のFizz”,”5の倍数の時のBuzz”,”15の倍数の時のFizzBuzz”,”その他”の時の4つのクラスの分類問題にしました

softmaxではなくて、softprobを用いました

ドキュメントを読むと、各クラスの所属する確率として表現されるようです(クラスの数ぶん、sigmoidが配置されていると、同じ?)

学習データ

0〜99999までの数字の各FizzBuzzを利用します  

この時、2割をランダムでテストデータに、8割を学習データに分割します  

各種パラメータ

このようにしました、もっと最適な設定があるかもしれないので、教えていただけると幸いです

etaが大きいのは、極めてroundが多いので、これ以上小さくするとまともな時間に学習が完了しません  

  1. booster = gbtree
  2. objective = multi:softprob
  3. num_class = 4
  4. eta = 1.0
  5. gamma = 1.0
  6. min_child_weight = 1
  7. max_depth = 100
  8. subsample = 0.8
  9. num_round = 100000
  10. save_period = 1000
  11. colsample_bytree = 0.9
  12. data = "svm.fmt.train"
  13. eval[test] = "svm.fmt.test"
  14. #eval_train = 1
  15. test:data = "svm.fmt.test"

プログラムの解説

githubにコードが置いてあります

データセットの準備

  1. $ python3 createDataset.py --step1 # データセットの作成
  2. $ python3 createDataset.py --step2 # 前処理
  3. $ python3 createDataset.py --step3 # libsvmフォーマットを作成

学習

(xgboost.binはubuntu linux 16.04でコンパイルしたバイナリです。環境に合わせて適宜バイナリを用意してください)
(学習には、16コアのRyzen 1700Xで2時間程度かかります)

  1. $ ./xgboost.bin fizzbuzz.train.conf

予想

(必要に応じて、使用するモデルを書き換えてください)

  1. $ ./xgboost.bin fizzbuzz.predict.conf

精度の確認

  1. $ python3 predCheck.py

精度

50000roundでテストデータで以下の精度が出ます

  1. acc 0.9492

出力はこのようになります

  1. 12518 predict class = 3 real class = 3
  2. 42645 predict class = 2 real class = 0
  3. 15296 predict class = 3 real class = 3
  4. 47712 predict class = 3 real class = 1
  5. 1073 predict class = 3 real class = 3
  6. 66924 predict class = 1 real class = 1
  7. 82852 predict class = 3 real class = 3
  8. 26043 predict class = 1 real class = 1
  9. 96556 predict class = 3 real class = 3
  10. 81672 predict class = 1 real class = 1
  11. 44018 predict class = 3 real class = 3
  12. 16622 predict class = 3 real class = 3
  13. 79924 predict class = 3 real class = 3
  14. 15290 predict class = 2 real class = 2
  15. 25276 predict class = 3 real class = 3

class 2は15の倍数なのですが、これの獲得が難しいようです

liblinear(support vector classification)との比較

一応、違う機械学習との比較ともやるべきでしょう

L2-regularized L2-loss support vector classificationで動作する、liblinearで比較しました  

  1. $ ./train -s 1 svm.fmt.train
  2. ....*.*
  3. optimization finished, #iter = 52
  4. Objective value = -56679.234880
  5. nSV = 64068
  6. .....*
  7. optimization finished, #iter = 51
  8. Objective value = -56678.857821
  9. nSV = 65083
  10. ....*.
  11. optimization finished, #iter = 50
  12. Objective value = -14306.576984
  13. nSV = 17032
  14. .....*
  15. optimization finished, #iter = 51
  16. Objective value = -14305.608585
  17. nSV = 16957
  1. $ ./predict svm.fmt.test svm.fmt.train.model output
  2. Accuracy = 66.2298% (13240/19991)

精度が66%しか出ていません

やはり、XGBoostの精度で判別をすることはできないようです

まとめ

DeepLearningでは精度100%を達成できましたが、XGBoostでは95%程度の精度です

完全なルールの獲得は怪しいですが、それでもかなりいいところまで行っているようです  

また、目的関数をうまく設計すれば、もっといけるでしょう(勾配ブースティングのマルチラベル分類、どうやるんだろう)  

参考文献

[1] XGBoost: A Scalable Tree Boosting System