【Python】スプラトゥーン２のリーグマッチデータを相関係数表を使って分析する

# はじめに

スプラトゥーン2の戦績データは任天堂のサーバーに直近50試合分が保管され、公式アプリ「イカリング2」で確認することが出来る。後述する「ikaWidget2」では、この戦績データをダウンロード・保存し、キルやデスの平均値や、ステージ毎の勝率等の統計データが取得できる。「スプラデータクラブ」等のWebサイトでは、「ikaWidget2」に保存されたデータを用いることで、より詳細な統計データを得ることが出来る。しかし、こういった統計データの多くは各個人の戦績に基づいたものであり、**4人用モード「リーグマッチ」における自チーム内の相互作用に着目した解析ツールはほとんどない**。本記事では「リーグマッチ」における自チーム内スコアの相関係数表を計算するライブラリを作成し、それを利用して試合の分析を行う。

# スプラトゥーン2とは

## 概要
![a23d1ef3b585f79db54f5797e1f5173db5b04ee5d149d8db7ed0f1db44cd3794.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550487/5073dab6-6a5a-e6d1-af84-9dbfde334c85.jpeg)
スプラトゥーン2は任天堂より2017年7月21日に発売されたアクションシューティングゲームである。2020年10月現在1000万本以上が販売されている。発売から3年以上が経過した今でも定期的にアップデートがされる大人気ゲームである。

## 仕様

プレイヤーはイカ（orタコ）に扮したキャラクターとなり、水鉄砲やローラー等の武器でインクを塗りあって戦う。インクを敵に浴びせれば倒すこともできる（キル）。倒されたプレイヤーは約10秒程度で復活する。どのルールも4対４のチーム戦であるため、チーム内の連携が重要になる。ステージを自チームのインクで塗るとスペシャルポイントが溜まり、強力な「スペシャルウェポン」が使えるようになる。ただし、敵に倒されるとスペシャルポイントが半分になってしまう。

## ルール

### ナワバリバトル

制限時間内に相手より広く地面を塗ったチームが勝利となる。スプラトゥーンにおける基本ルール。

### ガチエリア

ステージ内に配置された「ガチエリア」を自陣のインクで占拠した時間を競う。ナワバリバトルを局所化して、占拠時間による勝敗を設けたゲーム。

### ガチヤグラ

「ガチヤグラ」に乗り込み、制限時間内に相手チームのゴールまで近づけたチームが勝利となる。上に乗ることで「ガチヤグラ」を進めることが出来るが、敵からは格好の的になってしまう。

### ガチホコバトル

「ガチホコ」と呼ばれる巨大な水鉄砲を拾い、制限時間内に相手チームのゴールまで近づけたチームが勝利となる。「ガチホコ」を持ったプレイヤーは強力な「ガチホコショット」を放つことが出来るようになるが、敵チームから位置がバレてしまい、狙われやすくなる。

### ガチアサリ

ステージに散らばった「アサリ」を拾い、相手チームのゴールに入れて得点を競う。ゴールは初め、バリアで守られているため、アサリを10個集めて「ガチアサリ」を作りバリアを破壊しなければならない。バリアを破壊すると一定時間相手チームのゴールにアサリを入れられるようになる。

## リーグマッチ

フレンドと4人チームを作って他のチームと対戦するモード。リーグマッチでは、「ガチエリア」「ガチヤグラ」「ガチホコバトル」「ガチアサリ」の4つの対戦ルールで遊ぶことが出来る。

# 相関係数表とは

## 相関係数

相関係数とは、2つの変数間の関係の強さを表す-1から+1の指標である。相関係数が正の時は「正の相関」が、負の時は「負の相関」があるという。正の相関がある時、2つの変数はいわゆる「正比例」のような関係になり、一方が増加する時もう一方も増加する。負の相関がある時は正の相関とは逆に、一方が増加する時もう一方は減少する。例えば、身長と体重の関係は強い正の相関を示し、国の失業率と経済成長率は負の相関を示す。

相関係数の絶対値とその相関の強さの関係は以下である。

| 相関係数 abs(r)        | 相関の強さ         |
| ----------------- | ------------------ |
| 0.7 ≦ abs(r)       | 強い相関がある     |
| 0.4 ≦ abs(r) ≦ 0.7 | 相関がある         |
| 0.2 ≦ abs(r) ≦ 0.4 | 弱い相関がある     |
| 0 ≦ abs(r) ≦ 0.2   | ほとんど相関がない |

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550487/e8475351-322e-1e4e-e8ae-bfcbd1cd06d3.png)

## 相関係数表

相関係数表は、各2変数間の相関係数をまとめた表である。
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550487/408a006d-3255-8ac5-38e5-2624aa8f1ce0.png)
上図は、変数A,B,C,Dの相関係数表である。相関係数表はその特性上、表の左下と右上の値が線対象になる。

ある2変数の行と列が交わった位置の値がその2変数の相関係数になる。例えば、変数BとCの相関係数は0.27になる。
![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550487/695a66a2-7b8d-8c44-f9a7-437e6da92f2a.png)
このように、取り扱う変数が多い場合には相関係数表を用いることで、各変数間の関係をわかりやすく記述することが出来る。

# ikaWidget2

ikaWidget2は、任天堂非公式のスプラトゥーン2の分析アプリである。

App Store		: https://apps.apple.com/jp/app/ikawidget-2/id1271025591
Google Play	: https://play.google.com/store/apps/details?id=com.flapg.ikawidget2&hl=ja

任天堂のサーバーに保管された直近50試合をダウンロード・保管し、キルやデスの平均値や、ステージごとの勝率等の統計データが取得できる。下図は、ikaWidget2の実際の画面である。
![S__58793988.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550487/cf2e52fc-2ca7-6c05-8635-3bac0346b144.jpeg)
ikaWidget2はデータの外部出力機能も搭載しており、jsonとcsv（拡張子.tcsv）形式に対応している。今回は、ikaWidget2から出力されたcsvを使って相関係数表の計算を行う。

# 環境

- Python
- pandas
- DateTime
- openpyxl

# 計算方法

ikaWidget2のcsvファイルの構造を以下に示す。
![図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550487/2373165f-5ecc-b31b-f3c5-8c7432b33d13.png)
共通データは試合の開始日時やステージ、ゲームモード等である。共通データ以降はキルやデス数等のプレイヤー情報が自分→味方→敵の順番に並ぶ。味方データの順番は試合ごとにバラバラであるため、このデータ群からリーグマッチの相関係数表を計算する際には、味方データとフレンド個々人の紐づけが必要になる。これをスプラトゥーン2のユーザーネームを用いて行うこともできるが、Nintendo Switchのユーザーネームを変更するとスプラトゥーン2のユーザーネームも変更されてしまうため普遍的でなく、汎用性に乏しい。ここでは「PrincipalID」を使って紐づけを行う。「PrincipalID」はユーザー固有の値であり、ユーザーネームを変更しても変わることはない。この値は内部データであるためゲーム中では確認出来ないが、ikaWidget2から出力されるファイルから取得できる。キルやデス数をフレンド毎に整理することが出来れば、後はpandasの.corr()関数で容易に相関係数表を作成することが出来る。

# ダウンロード・インストール

今回作成したスプラトゥーン2リーグマッチ相関係数表計算ライブラリ「splatoon_league_corr」はGitHub及びPyPlにアップロード済みである。

GitHub : https://github.com/JmpM-0743/splatoon_league_corr.git

PyPlからインストールする場合はpipでインストールできる。

```shell
pip install splatoon_league_corr
```

# ライブラリの使い方

splatoon_league_corrでは、以下のクラス及び関数を提供する。

## class ika_data

プレイヤーデータの格納クラス。

コンストラクタ

```python
def __init__(self,pid,jpname,usname)
```

| メンバ変数 | 説明                                                         |
| ---------- | ------------------------------------------------------------ |
| pid        | プレイヤーのPrincipalID<br />PrincipalIDは内部データなのでゲーム内では確認できないが、<br />ikaWidget2から出力されるtcsvファイル等から取得できる |
| jpname     | 相関係数表出力時に表示される名前                             |
| usname     | 戦績データ一覧出力時に表示される名前                         |

使用例

```python
player = splatoon_league_corr.ika_data('824a58fc35365d11','まるや','maruya')
```

## class team_data

4つのika_dataで構成されるチームクラス。

コンストラクタ

```python
def __init__(self,player,friend1,friend2,friend3)
```

| メンバ変数 | 説明                               |
| ---------- | ---------------------------------- |
| player     | tscvファイルを出力した本人のデータ |
| friend1～3 | 同じチームのフレンドデータ         |

使用例

```python
myteam = splatoon_league_corr.team_data(player,friend1,friend2,friend3)
```

## calc_corr_number_of_games(filename,save_dir,myteam,n)

試合数を引数にして相関係数表のエクセルファイル（result.xlsx）を出力する関数。

| 引数     | 説明                                           | 型        |
| -------- | ---------------------------------------------- | --------- |
| filename | 入力するtcsvファイルのパス                     | str       |
| save_dir | 出力データを格納するディレクトリ名（自動生成） | str       |
| myteam   | team_dataクラス                                | team_data |
| n        | 相関係数表を計算する際の試合数                 | int       |

使用例

```python
splatoon_league_corr.calc_corr_number_of_games('ikaWidgetCSV_20201009231053.tcsv','output',myteam,50)
```

## calc_corr_days(filename,save_dir,myteam,datemin,datemax)

試合の期間を引数にして相関係数表のエクセルファイル（result.xlsx）を出力する関数。

| 引数             | 説明                                                         | 型        |
| ---------------- | ------------------------------------------------------------ | --------- |
| filename         | 入力するtcsvファイルのパス                                   | str       |
| save_dir         | 出力データを格納するディレクトリ名（自動生成）               | str       |
| myteam           | team_dataクラス                                              | team_data |
| datemin、datemax | 相関係数表を計算する際の試合期間（datemin～datemax）<br />YYMMDDで記述する。 | str       |

使用例

```python
splatoon_league_corr.calc_corr_days('ikaWidgetCSV_20201009231053.tcsv','output_date',myteam,'20200901','20201030')
```

# 分析結果と考察

以下に、筆者のチームのガチエリア50試合分の相関係数表を示す。
![図6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550487/017ce052-b8ff-1ed2-2901-09383945bb8b.png)
この表ではノックアウトによる値のズレを防ぐため、試合中の各変数は分当たりの値としている。

| 変数名         | 説明                                                         |
| -------------- | ------------------------------------------------------------ |
| win            | 試合の勝敗　勝利が1で敗北が0                                 |
| EnemyUdemae    | 敵チームの平均ウデマエ<br />ウデマエ : 一人用プレイモードにおけるランクのようなもの |
| Kill/min       | 分当たりのキル数                                             |
| Death/min      | 分当たりのデス数                                             |
| PaintPoint/min | 分当たりの塗りポイント                                       |
| Special/min    | 分当たりのスペシャルウェポン発動回数                         |

分析の例として、この表からわかること・わかりそうなことを述べていく。

## ① 相関係数の大きい変数ペア

フレンド2の`PaintPoint/min`と`Special/min`の相関係数が0.77と、表中で一番大きい値をとっている。これら2変数の相関係数は、プレイヤーや他のフレンドも同様に高い値をとっている。前述の通り、スペシャルウェポンは塗りポイントが一定量溜まると発動できるため、この結果は妥当といえる。
![スクリーンショット 2020-10-12 220747.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550487/156822dc-b331-ef33-9921-0c9a906f7f23.png)

## ② 勝利に影響している変数

勝利との相関が最も強い変数は、フレンド1の`Kill/min`であるが、他のプレイヤー・フレンドも同様に高く、突出はしていない。「キルが多いと勝ちやすい」ことは自明であるため、この結果も妥当である。逆に、負の相関が最も強いのはプレイヤーの`Death/min`で、相関係数-0.61である。この値は他フレンドと比較しても大きく、プレイヤーが頻繁にデスしているときは負けやすい、と言えるだろう。

![図7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550487/1061d23f-9ecb-9ee1-b24c-43294c3ef8f7.png)


## ③ 敵のウデマエに関する相関

敵の強さによって味方の立ち回りがどのように変わるのかを分析する。こちらは、先程までと比べて個々人の特色がよく表れている。例えば、敵のウデマエが高い時は「キルが減ってデスが増える」ことが自然な流れだが、フレンド1は敵のウデマエとデス数の相関がなく、フレンド3はキル数との相関がない。

フレンド1は後衛武器を持つことが多く、前衛の味方がやられた時に自陣に下がり易いためデスが増えないと考えられる。きちんと生存している一方で、キル数の負相関はチームで一番大きく、敵が強いと苦戦している様子も伺える。

プレイヤーは他のフレンドと比較して塗りポイントとスペシャルの相関が少し高い。敵が強いと中々倒せなくなるため、地面を塗ってスペシャルで対抗しようとしていることが見て取れる。
![スクリーンショット 2020-10-12 224152.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550487/33e3fb07-f6a9-b64d-db48-8ac682099a17.png)

## ④ チーム内の相関を考える

最後に、チーム内の相関を分析してみる。下図は、キル数のみに着目した相関係数表である。この表を見ると、プレイヤーのみフレンド1以外のフレンドとのキル相関がほとんどないことが確認できる。言い換えると、プレイヤーのキルは他の前衛武器のキル数に何の影響も与えていないと言える（前述の通りフレンド1は後衛武器メイン）。明確な事はこの表からだけではわからないが、プレイヤーが前線から浮いていることや、逆に前線から手前側の位置で戦っていることを示していると考えられる。
![図8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550487/0b7f13c2-d012-2d43-c9c6-e6ea16c21b1b.png)

# まとめ

- ikaWidgetとPythonを用いることで、リーグマッチデータの相関係数表の計算が可能になった。
- 相関係数表の利用により、各個人のキルやデスだけではわからなかったチーム内の相互作用や、個々人のプレイ状況まで可視化できるようになった。