はじめに
最近,Dota2を始めましたが全く勝てません
ハードボットにボコボコにされます.
色々と調べても「死ぬな」くらいのことしか分らず苦戦しています.
データサイエンスでDota2強くなるかも説
そこで,データサイエンスの力を借りて,どのような状況なら勝っているか?や前回に比べてどのように振舞ったから勝てたのか?ということを数値化して分析していけば強くなるのでは!と考えました.本企画はその仮説を検証していく企画です.
前回までのあらすじ
Dota2の情報をPythonで取得できるような環境を作成し*1,データを取得+定期的に保存する機構を作りました*2.
今回の概要
保存したデータを一部可視化して,試合の内容を振り返り分析してみました.
Dota2 解析プログラム
使用データセット
- bot戦(ミディアム):Chaos Knight
- bot戦(ミディアム):Chaos Knight
2試合のデータセットを使います.2つともChaos Knight
を使用しました.
僕的にはこいつが使いやすいかなと初心者ながら感じでいます.
Import package
必要パッケージをインポートします.
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
でいきます.
#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試合のデータを指定します.
target_log_file_list = ["log_20220901-160140.csv", "log_20220901-204148.csv"]
リストに入れます.
df_list = []
for file_path in target_log_file_list:
df_list.append(pd.read_csv(file_path))
中身はこんな感じ
df_list[0].head(5)
Unnamed: 0 | alive | break | buyback_cost | buyback_cooldown | disarmed | has_debuff | health | health_percent | hexed | ... | kills | last_hits | net_worth | pro_name | runes_activated | support_gold_spent | wards_destroyed | wards_placed | wards_purchased | xpm | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1 | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | 0.0 | 0.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0.0 |
2 | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | 0.0 | 0.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0.0 |
3 | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | 0.0 | 0.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0.0 |
4 | 0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | 0.0 | 0.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 0.0 |
5 rows × 67 columns
取得したデータの種類はこんな感じです.
df_list[0].columns
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
に入れます.
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)
データの中身はこんな感じ.
df_ex_merge
level_try0 | level_try1 | |
---|---|---|
0 | NaN | NaN |
1 | NaN | NaN |
2 | NaN | NaN |
3 | NaN | NaN |
4 | NaN | NaN |
... | ... | ... |
29396 | 18.0 | NaN |
29397 | 18.0 | NaN |
29398 | 18.0 | NaN |
29399 | 18.0 | NaN |
29400 | 18.0 | NaN |
29401 rows × 2 columns
Plot level data
結果はこちら.
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試合目の方が後半のレベルの伸びが悪いですね.後述する体力を見ればわかりますが,後半では集団で結構負けてしまったので,その分の経験値が入っていないためレベルが低迷していると思われます.
Plot health section
Extract health data
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
plt.figure(figsize=(20,5))
sns.lineplot(data=df_ex_merge, lw=2)
後半には,集団戦で負けまくっていたので,体力の下降が激しいですね...
Plot gold data
Extract gold data
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
plt.figure(figsize=(20,5))
sns.lineplot(data=df_ex_merge, lw=2)
1試合目は集団戦で勝ちまくっていたのでジャブジャブお金が増えていることが分かります.
プログラム
コードはこちらです.
おわりに
今回のデータを見たところ,集団戦で勝てないことを考慮に入れて,最前線よりも少し後方で様子見しながら振舞った方がよさそうですね.
勝てそうならグイグイ行って,雲行きが怪しければ速攻退去する構えでいきます.
こんな感じでデータを活用しつつDota2の経験値を貯めていこうと思います.
参考サイト
最新情報
速報はTwitterやブログにて