#今回の目的
前回まででたくさんのゲームデータをローカルに保存するところまで実施しました。
今回はそのデータを使って簡単な機械学習をやってみます。
##必要なモジュールをインポート
import pickle
import glob
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
from sklearn.ensemble import RandomForestClassifier
ローカルに落としたファイルの操作用(pickele,glob)と機械学習用(sklern~)です。
##ファイル名を取得
gamelist = glob.glob('gamedata/*')
print(len(gamelist))
54456
前回保存したディレクトリからファイル名のリストを作成します。
##ゲームデータから必要な情報を抜き出す関数を作成
def GET_ONEGAME_DATA_LIST(game):
gameid = []
firstblood = []
firstdragon = []
firsttower = []
firstRiftHerald = []
win = []
gameid.append(game['gameId'])
if game['teams'][0]['firstBlood'] == True:
firstblood.append(1)
else:
firstblood.append(0)
if game['teams'][0]['firstDragon'] == True:
firstdragon.append(1)
else:
firstdragon.append(0)
if game['teams'][0]['firstTower'] == True:
firsttower.append(1)
else:
firsttower.append(0)
if game['teams'][0]['firstRiftHerald'] == True:
firstRiftHerald.append(1)
else:
firstRiftHerald.append(0)
win.append(game['teams'][0]['win'])
return(gameid + firstblood + firstdragon + firsttower + firstRiftHerald + win)
機械学習で必要な情報のみ取り出す関数を作成します。今回はfirstblood、firstdragon、firsttower、firstRiftHeraldの情報を特徴量として障害を予測します。
(学習のために元の値そのままでなく、各オブジェクトをとれたら1、とれなかったら0を入れる形にしています)
##データの作成
data_list =[]
for i in range(len(gamelist)):
f = open(gamelist[i],"rb")
game = pickle.load(f)
try:
one_data = GET_ONEGAME_DATA_LIST(game)
data_list.append(one_data)
except:
pass
print(len(data_list))
print(data_list[0])
54456
[209000036, 1, 0, 0, 1, 'Fail']
上で作ったファイルリストと関数からデータを作成します。
##データの分割
datalist_X = []
for i in range(len(data_list)):
X = data_list[i][1:5]
datalist_X.append(X)
print(datalist_X[0])
datalist_Y = []
for i in range(len(data_list)):
Y = data_list[i][5]
datalist_Y.append(Y)
print(datalist_Y[0])
(X_train, X_test,
y_train, y_test) = train_test_split(
datalist_X, datalist_Y, test_size=0.3, random_state=0,
)
[1, 0, 0, 1]
Fail
作成したデータを特徴量と目的変数に分割、さらに学習データとテストデータに分割します。
##学習とテストデータでの予測
forest = RandomForestClassifier(random_state=0)
forest.fit(X_train, y_train)
print('Train score: {}'.format(forest.score(X_train, y_train)))
print('Test score: {}'.format(forest.score(X_test, y_test)))
print('Confusion matrix:\n{}'.format(confusion_matrix(y_test, forest.predict(X_test))))
Train score: 0.736063380466434
Test score: 0.7348350370325029
Confusion matrix:
[[6030 1935]
[2397 5975]]
73%の正答率で予測ができました。
##どのオブジェクトの価値が高いのか
X = [[0,0,0,0]]
prob = forest.predict_proba(X)
print(prob)
[[0.8241532 0.1758468]]
X = [[1,0,0,0]]
prob = forest.predict_proba(X)
print(prob)
[[0.75712533 0.24287467]]
X = [[0,1,0,0]]
prob = forest.predict_proba(X)
print(prob)
[[0.65028517 0.34971483]]
X = [[0,0,1,0]]
prob = forest.predict_proba(X)
print(prob)
[[0.53455279 0.46544721]]
X = [[0,0,0,1]]
prob = forest.predict_proba(X)
print(prob)
[[0.77064597 0.22935403]]
いろいろな状況を想定して勝率を予測してみました(左が敗北率、右が勝率)
今回特徴量に入れたfirstblood、firstdragon、firsttower、firstRiftHeraldを全く取れなかった場合勝率は17%ほどしかないようです。
また、各ファーストオブジェクトのうち1つだけとれた(他は取られた可能性が高い)場合勝率はタワー > ドラゴン > kill => ヘラルドのようです。
##終わりに
今回は簡単に試してみるというのが目的だったので分かりやすい特徴量のみ選んで学習しました。
取り出せるデータの種類はたくさんあるのでもっと面白そうな予測方法を思いつけばやってみたいなと思います。