はじめに
私はこのゲームをプレイしたことがなく、ドメイン知識が全くなかったので、オライリー本の「Python機械学習クックブック」を使って、掲載されている手法をいろいろ勉強するつもりで、取り組みました。
結果としては、PublicLBでは4位だったのですが、Shake downして9位となり、汎用性をもったモデルの構築の難しさを改めて実感しました。
1.全体構成
今回は、前述の通り、ゲーム自体の知識がなかったので、データ自体の分析はそこそこに、とにかく、いろんな手法を使ってみました。
初めて使ったモデルもあり非常に勉強になりました。
全体像としては、以下のとおり3つの前処理をした特徴量を使った6種類の予測結果を加重平均したモデルが最もprivateスコアが高かったモデルとなりました。
2.前処理
【前処理①】
こちらは、Probspace のトピックで公開させていただいた[ベースライン](https://prob.space/competitions/game_winner/discussions/Oregin-Post344b005eb605a8777141) で使用している前処理になります。
欠損値には、全て-1を設定しています。
また、カテゴリ変数は全てターゲットエンコードしています。
【前処理②】
上記、前処理①で作成した特徴量を、feature tools を利用して、水増ししました。
具体的には、それぞれの特徴量を足し算、引き算、掛け算した特徴量を追加しました。
【前処理③】
こちらは、カテゴリ変数のうち、武器関係の特徴量はOne-Hotベクトルに変換して、それ以外の変数はラベルごとの数値に変換しています。
欠損値については、どちらも欠損値を表す文字列に変換しておいて、1つのカテゴリとして上記の変換を行いました。
武器関係のOne-Hotベクトルに変換については、Python機械学習クックブックの「レシピ5.1 名義カテゴリ特徴量の数値化」にあった複数クラスのエンコーダー MultiLabelBinarizer() を利用しました。
また、それ以外のカテゴリ変数はの数値に変換については、Pandasのfactorize()を使用しました。
3.モデル構築
モデル構築についても、前述の通りPython機械学習クックブックのモデルをいろいろと組み合わせて試していきました。
試した中で、privateスコアが最も高かったのは、以下の6つ入力とモデルの組み合わせからの出力を加重平均したもとなりました。
前処理①の特徴量→GaussianNBを1層目、BernoulliNBを2層目にしたStacking
1つ目は、ガウシアンナイーブベイズクラス分類器(GaussianNB())と、ベルヌーイナイーブベイズクラス分類器(BernoulliNB())をStackingした構成になります。
ナイーブベイス分類機は、ベイズの定理を利用した、単純ベイズ確率モデルとのことです。
ガウシアンナイーブベイズクラス分類器(GaussianNB())は、分布が正規分布になることを前提として分類する分類機で、Python機械学習クックブックの「レシピ18.1 連続値特徴量に対するクラス分類器の訓練」にあった、GaussianNB()を利用しました。
ベルヌーイナイーブベイズクラス分類器(BernoulliNB())は、分布がベルヌーイ分布になることを前提として分類する分類機で、Python機械学習クックブックの「レシピ18.3 2クラス特徴量に対するナイーブベイズクラス分類器の訓練」にあった、GaussianNB()を利用しました。
前処理②の特徴量→LogisticRegression
2つ目は、ロジスティック回帰(LogisticRegression)を利用した構成となります。
言わずとしれた2値分類のモデルになります。「回帰」と名前がついていますが、分類モデルに使えるモデルです。
Python機械学習クックブックの「レシピ16.1 2クラス分類器の訓練」にあった、LogisticRegression()を利用しました。
3つ目以降は、定番の勾配ブースティング決定木 (Gradient Boosting Decision Tree) の精度が良かったので採用しています。
前処理③の特徴量→XGboost
3つ目は、勾配ブースティング決定木 (Gradient Boosting Decision Tree) の一つである、XGboostになります。
前処理①の特徴量、前処理②の特徴量、前処理③の特徴量:LightGBM
4つ目から6つ目は、前処理①から③をそれぞれLightGBMで学習したモデルになります。
それぞれの予測結果の加重平均を最終的なサブミットとすることで、Publicスコアが0.567396、Privateスコアが0.564008の精度を得ることができました。
4.まとめ
今回は、ゲームの勝敗予測ということで、ドメイン知識がなく辛いなと考えていたのですが、Python機械学習クックブックを活用させていただき、いろいろなレシピを活用させていただくことで、なんとか1桁台の順位を獲得することができました。
欲を言えば、今回もまたShakeDownしてしまったので、PublicとPrivateの精度を同等にできる汎用的なモデルを作成できなかったところが反省点です。こちらについては、続いているので、対策を勉強していきたいと思います。
5.謝辞
コンペを運営してくださいました、ProbSpaceの運営の皆様、コンペに参加してくださった皆様に心より感謝申し上げます。
ご参考
以下のブログで、これまでのコンペへの参加に関する記事も掲載しております。ご参考まで。
[【9位解法】ProbSpace開催「対戦ゲームデータ分析甲子園」(スプラトゥーンコンペ)の振り返り](https://oregin-ai.hatenablog.com/entry/2020/10/20/123619)