データサイエンスでDota2強くなるかも説(3)～試合データをプロットしてみた～

## はじめに


最近，Dota2を始めましたが全く勝てません
ハードボットにボコボコにされます．

色々と調べても「死ぬな」くらいのことしか分らず苦戦しています．

### データサイエンスでDota2強くなるかも説

そこで，データサイエンスの力を借りて，どのような状況なら勝っているか？や前回に比べてどのように振舞ったから勝てたのか？ということを数値化して分析していけば強くなるのでは！と考えました．本企画はその仮説を検証していく企画です．

![file](https://hamaruki.com/wp-content/uploads/2022/09/image-1662048158424.png)

### 前回までのあらすじ

Dota2の情報をPythonで取得できるような環境を作成し[<sup>*1</sup>](https://hamaruki.com/2022/09/02/data-science_with_dota2_03//#参考サイト)，データを取得＋定期的に保存する機構を作りました[<sup>*2</sup>](https://hamaruki.com/2022/09/02/data-science_with_dota2_03//#参考サイト)．


### 今回の概要

保存したデータを一部可視化して，試合の内容を振り返り分析してみました．



## Dota2 解析プログラム

### 使用データセット

- bot戦（ミディアム）：Chaos Knight
- bot戦（ミディアム）：Chaos Knight

2試合のデータセットを使います．2つとも`Chaos Knight`を使用しました．
僕的にはこいつが使いやすいかなと初心者ながら感じでいます．

![file](https://hamaruki.com/wp-content/uploads/2022/09/image-1662047328994.png)




### Import package

必要パッケージをインポートします．

```python
import dota2gsi
import glob
import pandas as pd

import seaborn as sns
from matplotlib import pyplot as plt
import matplotlib as mpl
```

### figure style

スタイルは`fivethirtyeight`でいきます．

```python

#sns.palplot(sns.color_palette("RdBu_r", 24))
#sns.set_palette("RdBu_r")
#sns.set(style='darkgrid')
#sns.set_style('whitegrid')
mpl.style.use('fivethirtyeight')
```

### Read csv file

今回は2試合のデータを指定します．

```python
target_log_file_list = ["log_20220901-160140.csv", "log_20220901-204148.csv"]
```

リストに入れます．

```python
df_list = []
for file_path in target_log_file_list:
    df_list.append(pd.read_csv(file_path))
```
中身はこんな感じ

```python
df_list[0].head(5)
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>Unnamed: 0</th>
      <th>alive</th>
      <th>break</th>
      <th>buyback_cost</th>
      <th>buyback_cooldown</th>
      <th>disarmed</th>
      <th>has_debuff</th>
      <th>health</th>
      <th>health_percent</th>
      <th>hexed</th>
      <th>...</th>
      <th>kills</th>
      <th>last_hits</th>
      <th>net_worth</th>
      <th>pro_name</th>
      <th>runes_activated</th>
      <th>support_gold_spent</th>
      <th>wards_destroyed</th>
      <th>wards_placed</th>
      <th>wards_purchased</th>
      <th>xpm</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>0</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>...</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
    </tr>
    <tr>
      <th>1</th>
      <td>0</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>...</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>0.0</td>
    </tr>
    <tr>
      <th>2</th>
      <td>0</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>...</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>0.0</td>
    </tr>
    <tr>
      <th>3</th>
      <td>0</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>...</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>0.0</td>
    </tr>
    <tr>
      <th>4</th>
      <td>0</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>...</td>
      <td>0.0</td>
      <td>0.0</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>NaN</td>
      <td>0.0</td>
    </tr>
  </tbody>
</table>
<p>5 rows × 67 columns</p>
</div>


取得したデータの種類はこんな感じです．

```python
df_list[0].columns
```



```bash
    Index(['Unnamed: 0', 'alive', 'break', 'buyback_cost', 'buyback_cooldown',
           'disarmed', 'has_debuff', 'health', 'health_percent', 'hexed', 'id',
           'level', 'magicimmune', 'mana', 'mana_percent', 'max_health',
           'max_mana', 'muted', 'name', 'respawn_seconds', 'selected_unit',
           'silenced', 'stunned', 'talent_1', 'talent_2', 'talent_3', 'talent_4',
           'talent_5', 'talent_6', 'talent_7', 'talent_8', 'xpos', 'ypos',
           'clock_time', 'daytime', 'dire_ward_purchase_cooldown', 'game_state',
           'game_time', 'name.1', 'matchid', 'radiant_ward_purchase_cooldown',
           'nightstalker_night', 'roshan_state', 'roshan_state_end_seconds',
           'win_team', 'customgamename', 'assists', 'camps_stacked', 'deaths',
           'denies', 'gold', 'gold_reliable', 'gold_unreliable', 'gpm',
           'hero_damage', 'kill_list:victimid_#', 'kill_streak', 'kills',
           'last_hits', 'net_worth', 'pro_name', 'runes_activated',
           'support_gold_spent', 'wards_destroyed', 'wards_placed',
           'wards_purchased', 'xpm'],
          dtype='object')
```


### Plot level section

ここから描画していきます．

#### Extract level data

`level`のデータのみを抽出し描画用の`df`に入れます．

```python
df_ex_data_list = []
for i, df in enumerate(df_list):
    target_name = 'level'
    plot_name = '{}_try{}'.format(target_name, i)
    df[plot_name] = df[target_name]
    df_ex_data_list.append(df[plot_name])

df_ex_merge = pd.concat(df_ex_data_list, axis=1)
```


データの中身はこんな感じ．
```python
df_ex_merge
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>level_try0</th>
      <th>level_try1</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>NaN</td>
      <td>NaN</td>
    </tr>
    <tr>
      <th>1</th>
      <td>NaN</td>
      <td>NaN</td>
    </tr>
    <tr>
      <th>2</th>
      <td>NaN</td>
      <td>NaN</td>
    </tr>
    <tr>
      <th>3</th>
      <td>NaN</td>
      <td>NaN</td>
    </tr>
    <tr>
      <th>4</th>
      <td>NaN</td>
      <td>NaN</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>29396</th>
      <td>18.0</td>
      <td>NaN</td>
    </tr>
    <tr>
      <th>29397</th>
      <td>18.0</td>
      <td>NaN</td>
    </tr>
    <tr>
      <th>29398</th>
      <td>18.0</td>
      <td>NaN</td>
    </tr>
    <tr>
      <th>29399</th>
      <td>18.0</td>
      <td>NaN</td>
    </tr>
    <tr>
      <th>29400</th>
      <td>18.0</td>
      <td>NaN</td>
    </tr>
  </tbody>
</table>
<p>29401 rows × 2 columns</p>
</div>



#### Plot level data

結果はこちら．

```python
plt.figure(figsize=(20,5))
sns.lineplot(data=df_ex_merge, lw=2)
#sns.lineplot(data=df_data, x='clock_time', y='level', lw=2)
```

2試合目の方が後半のレベルの伸びが悪いですね．後述する体力を見ればわかりますが，後半では集団で結構負けてしまったので，その分の経験値が入っていないためレベルが低迷していると思われます．

![](https://i.imgur.com/y6nWgMf.png)



### Plot health section

#### Extract health data


```python
df_ex_data_list = []
for i, df in enumerate(df_list):
    target_name = 'health'
    plot_name = '{}_try{}'.format(target_name, i)
    df[plot_name] = df[target_name]
    df_ex_data_list.append(df[plot_name])

df_ex_merge = pd.concat(df_ex_data_list, axis=1)
```

#### Plot health data


```python
plt.figure(figsize=(20,5))
sns.lineplot(data=df_ex_merge, lw=2)
```
後半には，集団戦で負けまくっていたので，体力の下降が激しいですね．．．

![](https://i.imgur.com/54llrUK.png)



### Plot gold data

#### Extract gold data


```python
df_ex_data_list = []
for i, df in enumerate(df_list):
    target_name = 'gold'
    plot_name = '{}_try{}'.format(target_name, i)
    df[plot_name] = df[target_name]
    df_ex_data_list.append(df[plot_name])

df_ex_merge = pd.concat(df_ex_data_list, axis=1)
```

#### Plot gold data


```python
plt.figure(figsize=(20,5))
sns.lineplot(data=df_ex_merge, lw=2)
```

１試合目は集団戦で勝ちまくっていたのでジャブジャブお金が増えていることが分かります．

![](https://i.imgur.com/BZ8Nslv.png)



## プログラム

コードはこちらです．

https://github.com/HamaruKi0303/Dota2-GSI-Science/blob/main/Dota2Analysis03.ipynb

## おわりに

今回のデータを見たところ，集団戦で勝てないことを考慮に入れて，最前線よりも少し後方で様子見しながら振舞った方がよさそうですね．
勝てそうならグイグイ行って，雲行きが怪しければ速攻退去する構えでいきます．
こんな感じでデータを活用しつつDota2の経験値を貯めていこうと思います．

<h2 id="参考サイト">参考サイト</h2>

- *1：[データサイエンスでDota2強くなるかも説(1)～環境設定～](https://hamaruki.com/2022/09/01/data-science_with_dota2_01/)
- *2：[データサイエンスでDota2強くなるかも説(2)～ビッグデータ取得&定期保存～](https://hamaruki.com/2022/09/01/data-science_with_dota2_02/)


## 最新情報

速報はTwitterやブログにて

https://hamaruki.com/category/dota2%e3%83%87%e3%83%bc%e3%82%bf%e3%82%b5%e3%82%a4%e3%82%a8%e3%83%b3%e3%82%b9/


https://twitter.com/hAru_mAki_ch/status/1569690537917140994