世間は久々の天気の中、3連休ですが、みなさんイカがお過ごしでしょうか。
ある人はバイトに勤しみ、ある人はロブズ・10・プラーでフードを買い、
ある人はバッテラストリートに出かけて塗りたくっているでしょう。
そう、スプラトゥーン2の話です。

スプラトゥーンは、言わずとも知れたNintendo WiiUおよび、Switchにおける超人気ゲームでして、
インクを打ち合うアクションシューティングゲームで、
シリーズ累計で国内270万本、世界590万本の売上本数(2017年9月時点)となるようです。



私の職場のデータサイエンス系の部署でも、80%以上の人がやっておりまして、
もはやSQL、Python、Splatoonが必須のスキルの部署になってしまいました。

さて、スプラトゥーンは対戦ゲームのため、
公式・非公式含め、大会が頻繁に開催されております。
先日、私も初めて大会に参加してきました。

結果は、初戦敗退でした。圧倒的な経験不足の差が出た形となりまして、
なぜ、SQLでデータ集計したり、Pythonでコーディングしていたあの時間を
スプラトゥーンに捧げることができなかったのかと、今でも悔やまれます。


しかし、同時に、こう思いました。
スプラトゥーンを、ガムシャラに練習するのではなく、
機械学習、特にdeeplearningを駆使して
データに基づいて最短で上手くなりたい
、と。


そこで本稿では、スプラトゥーン2をdeep learningで解析・攻略していきます。
※私は、現在A-のウデマエで、データ収集時点はB帯がメインであったため、以降の分析はあくまでB帯メインの話だとお考えくださいませ。
 おそらくS帯などでは、通用しない結果もあるかと思います。
※2017年9月〜10月時点のデータを主に使用しております。


| (1) データの取得
IkaLogなど、各種対戦データを取得する方法がすでにありますが、
今回は自前でプレイデータを収集してみたいと思います。
スプラトゥーン2は1ゲームごとに、2つの結果が表示されます。
「ステージのインク塗り結果」と「各プレイヤーのパラメータ」となります。

ステージのインク塗り結果

各プレイヤーのパラメータ


Nintendo Switchにはコントローラーに画面キャプチャボタンがありまして、
SDカードに保存できるため、この2つの画像をひたすらキャプチャしていきます。


今回、573試合分の1146枚のキャプチャを実際にプレーして収集いたしました。



ちなみに収集した試合の内訳は下記となります。
ステージ・ルールによっては、分析するには十分な数が足りないところがあります。
また、Bバスパークは、今回の分析に間に合いませんでした。
目的によって都度ガチエリア、ガチホコ、ガチヤグラなどルールごとにまとめて解析することにします。
areahocoyagura
total246160167
海女美術大学9258
バッテラストリート54433
チョウザメ造船20254
フジツボスポーツクラブ182434
ガンガゼ野外音楽堂15109
ホッケふ頭331314
コンブトラック20138
マンタマリア26427
タチウオパーキング331913
モズク農園51715
エンガワ河川敷1362



| (2) データの抽出
収集したキャプチャ画像のうち「各プレイヤーのパラメータ」画像からデータを抽出していきます。
この画像からは、「勝敗」および各プレイヤーごとの「ランク」「ブキ」「kill数」「SP使用回数」を抽出していきます。


データ抽出はPythonで実装しておりまして、
OpenCVによって判定区画を区切ったのち、
画像判定、文字認識に、deep learningを用いております。(Kerasで実装)
元のテンプレ画像をあらかじめ用意することで、精度は、ほぼ100%となります。

また、ブキを画像から判定したのち、そのブキに紐づく、スペシャル、サブを紐付けて集計しておきます。



最終的に、各試合ごとのデータとして、下記のようなcsvを得ることができます。




| (3) データのサマリー
得られたデータを機械学習にかける前に、まずはデータの概要を確認しておきます。

ランクの分布
最小値:10
最大値:50
平均:33.8


kill数の分布
最小値:0
最大値:27
平均:7.2


sp使用回数の分布
最小値:0
最大値:11
平均:2.0


まあまあ、肌感通りの分布となっております。
kill数の最大値27は嗚咽ですね、。

また、使用ブキのランキング上位も確認しておきます。
シューター系が多い印象ですね。
もしかしたらB帯メインのデータであるためかもしれません。

ブキ使用のべプレイヤー数
スプラシューターコラボ520
スプラシューター513
わかばシューター254
プロモデラーMG197
スプラスピナー186
もみじシューター172
ホクサイ157
スパッタリー145
プロモデラーRG143
ボールドマーカー136


| (4) 機械学習による勝敗結果の予測(Xgboost / deep learning)
それでは、いよいよ得られたデータから勝敗予測をしていきます。
deep learningのほか、
今回、比較対象として、Xgboost(*)を用います。
※近年のデータ分析コンペ(Kaggleなど)で非常に多く用いられている決定木系の実装。

また、元のデータそのままを用いた場合と、前処理を行ったデータを用いた場合、の2つを比較してみます。
前処理データは、各データを合計したり、差をとったりしたものとなります。
意図としては、たとえば合計kill数が多いのが、プレイヤー1、プレイヤー2であることの違いはなく、
とにかく、チーム合計でどのくらいkillしたのか、それが相手より上回ったかが重要であると判断したためです。
ただし、スペシャル使用回数はブキによって、意味合いが異なると思われるため、
単純なスペシャル使用回数合計のほか、各スペシャル(アメフラシ、イカスフィア、など)ごとの合計も集計しておきます。



各手法によるパラメータからの勝敗予測結果は、下記の通りとなりました。

Xgboostdeep learning
元データ前処理データ元データ前処理データ
ガチエリア0.8290.8490.8200.800
ガチホコ0.8590.8990.9360.719
ガチヤグラ0.8680.8910.8530.765

Xgboostでは、どのルールも0.8以上の精度で勝敗予測できております。
また、データの前処理をすることで、各ルールとも精度が向上しております。
deep learningも、元データの時点で0.8以上の精度となり、特にガチホコでは、0.9以上の精度で予測することができました。

ちなみに下記がdeep learningにおける1000回の試行によるガチホコの予測精度の推移となります。
400回くらいの試行で徐々に精度0.9を超え始めております。



一方、deep learningにおいてはデータの前処理をすることでむしろ精度は下がってしまいました。
ここら辺は、レイヤーの組み方次第なのかもしれませんが、
むしろdeep learning側に処理を投げてしまったほうがよい(中間レイヤーで前処理的なことが結果的に行われる)のかもしれません。


さて、このような結果を見ただけでは、今後のプレイの示唆が得られないため、
Xgboostによる、今回の判定に用いられた各パラメータの重要度を下記に示します。

ガチエリア
Xgboostでの勝敗予測における上位重要度ランキング
パラメータ重要度
味方プレイヤーのランク最大値47
敵プレイヤーのkill数合計42
味方プレイヤーのkill数合計38
味方プレイヤーのkill数最小値38
敵プレイヤーのランク合計38
味方プレイヤーのランク合計34
敵プレイヤーのスペシャル回数合計31
味方プレイヤーのスペシャル回数合計31

Xgboostでの勝敗予測における上位重要度ランキング(スペシャル上位)
パラメータ重要度
味方のスーパーチャクチ使用回数23
敵のスーパーチャクチ使用回数15
敵のカーリングボムピッチャー使用回数15
味方のイカスフィア使用回数14
敵のイカスフィア使用回数13


ガチホコ
Xgboostでの勝敗予測における上位重要度ランキング
パラメータ重要度
味方プレイヤーのkill数合計102
敵プレイヤーのランク最小値99
敵プレイヤーのランク合計96
敵プレイヤーのkill数合計92
敵プレイヤーのkill数最大値86

Xgboostでの勝敗予測における上位重要度ランキング(スペシャル上位)
パラメータ重要度
敵のマルチミサイル使用回数28
味方のスーパーチャクチ使用回数25
味方のマルチミサイル使用回数19
敵のインクアーマー使用回数18
味方のアメフラシ使用回数16


ガチヤグラ
Xgboostでの勝敗予測における上位重要度ランキング
パラメータ重要度
敵プレイヤーのランク合計35
敵プレイヤーのkill数合計27
味方プレイヤーのスペシャル回数合計22

Xgboostでの勝敗予測における上位重要度ランキング(スペシャル上位)
パラメータ重要度
味方のスーパーチャクチ使用回数15
敵のスーパーチャクチ使用回数12
敵のマルチミサイル使用回数11
味方のジェットパック使用回数9
敵のハイパープレッサー使用回数8


正直、ランクはそこまで関係ないのではと思っておりましたが、
B帯では、勝敗に重要なパラメータとなっているようです。S帯では、あまり関係ないかもしれません。
kill数、スペシャル使用回数が上位に来るのは納得です。
スペシャル使用回数の中での重要度では、
ガチエリアにおいて、カーリングボムピッチャー、およびイカスフィアの使用回数が上位に来ております。
イカスフィアは特に9月時点(修正前)では、みんな使ってましたね、。


さて、ここまで、Xgboostとdeep learningでの勝敗予測および、
勝敗予測に重要なパラメータを特定してきました。

しかしdeep learningは画像解析においてこそ、真価を発揮するものです。
そこで、次にパラメータではなく、「ステージのインク塗り結果」のキャプチャ画像を用いて、
deep learningで勝敗予測をし、さらに、そこから重要な塗りポイントを特定してみます。


| (5) deep learningによる、画像からの勝敗結果の予測
さて、インク塗り結果画像とは、下記のようなものでした。


こちらをdeep learningで解析していきますが、deep learningは、データ量が少ないと高い精度を出せません。
そこで、元画像を拡大縮小、回転するなどしてバリエーションを増やし、画像を水増ししていきます。


結果、元画像573枚から5,730枚の画像を生成しました。

こちらの画像を用いて、deep learningで勝敗予測を解析した結果が下記となります。
なお、元の画像数(水増し前の)があまりに少ないものは集計外としております。

areahocoyagura
海女美術大学0.780.90
バッテラストリート0.990.99
チョウザメ造船0.980.90
フジツボスポーツクラブ0.800.970.94
ガンガゼ野外音楽堂0.790.76
ホッケふ頭0.890.910.80
コンブトラック0.960.97
マンタマリア0.860.91
タチウオパーキング0.890.730.97
モズク農園0.840.97
エンガワ河川敷0.64


概ね、0.8以上の精度で、インク塗り結果画像から勝敗を予測できております。

さて、しかしこのままでは、なぜ精度がよいのか、
deep learningが画像中のどこを見て判断しているのかわかりません。

そこで、”Grad-cam”という手法を用います。
Grad-camとは、ざっくり言うと、
deep learningの予測において、各判定結果の確率スコアへの影響が大きい画像箇所を、
ある画像箇所に微小変化を加えたときの確率スコアの変化の大きさによって特定する、という手法となります。


※”Grad-CAM: Visual Explanations from Deep Networks via Gradient-based Localization, 2017″より引用
参考:
https://arxiv.org/abs/1610.02391
https://github.com/jacobgil/keras-cam


先ほど学習済みのdeep learningのモデルから、Grad-camの画像を生成してみます。

まずはフジツボスポーツクラブでのガチヤグラ。
赤色でハイライトされているところが、deep learningで注目されていると判定された箇所となります。

青色側から見て、中央および、中央の坂を降りて曲がった箇所がハイライトされております。
自陣にもいくつかハイライトされている箇所がある点が気になるところです。

次に、同じフジツボスポーツクラブでもガチホコの場合は下記となります。

先ほどガチヤグラでハイライトされた箇所がガチホコではハイライトされていないことが面白いですね。
フジツボのガチホコは左右2つのルートがあるのですが、
緑色側から向かって、右から進行したとき、左から進行したとき、それぞれでハイライトされているゾーンがあるようです。

他のステージも見てみましょう。
バッテラストリートのガチエリアは下記となりました。

橋の上、およびエリアの4つの角、敵陣近くでいくつかハイライトされております。


※その他のステージ、ルールについては順次追記していきます。


イカがでしたでしょうか。
deep learningは、精度は良いが、要因がわかりづらいということがデメリットとして挙げられがちですが、
今回用いた”Grad-cam”はじめ、近年、いくつかのdeep learningの学習過程を可視化する手法が出てきておりますので、
うまく組み合わせると、面白い気づきが得られそうです。

ただ、ここを塗るべきとわかっていても、それをできるためには、
やはり身体的な修練が必要ですので、今日も腱鞘炎と戦いながらプログラミングとスプラトゥーンです。


それでは、みなさん、塗りたくるテンタクル!