Help us understand the problem. What is going on with this article?

初心者の初心者による初心者のためのデータ分析!League of Legendsで下克上を目指せ!(機械学習で代替案編)

数ある記事の中からこのページを開いてくださりありがとうございます。

就労移行支援施設でpythonなどの勉強をしています。

第2回目の投稿ということで初心者の初心者による初心者のためのデータ分析!League of Legendsで下克上を目指せ!(穴場のチャンピオン探し編)の続きをあげていきます。

League of Legends(以後lol)をテーマに分析を始めた経緯は前回の記事をご覧ください。

前回やったことと今回やること

前回はlolで採用率はあまり高くないけれども勝率の高い「穴場」のキャラクター(以後チャンピオン)チャンピオンを過去の試合データを基に分析してみました。

そこではブルーのミッドレーンを対象にし採用率の高いチャンピオン上位20位までを出したところ最も採用率の高かったチャンピオンはOriannaで採用率は約8.43%で勝率は約53.0%でした。

一方で採用率では最下位のMalzaharの採用率は約1.71%と決して高くないものの勝率は約64.1%で全20チャンピオンの中で最上位でした。

しかし何年もプレイしている人はどういったチャンピオンが使われているか把握しておりOriannaの対策は既にできている可能性があります。その対抗策としてMalzaharのようなあまり使われていないけれど勝率の高いチャンピオンを使うことで盲点をつける可能性がないかと考えたのです。

しかしこれにも弱点があります。

各プレイヤーが普段どのチャンピオンを使っているかネット上で研究できるので本番の時BANされる危険があります。

そのため第2第3候補も作っておき柔軟に対応できるようにしていく必要があります。

そこで考えたのは自分がよく選ぶチャンピオンを使うプレイヤーは他にどういったチャンピオンを使っているか明らかにすることです。

そこで出力されたチャンピオンで前回の表にも登場しているものがあれば代替案としてある程度信頼の置けるものとなります。

ではどうやってやるか

誰がどのチャンピオンを使っているか、他にどのチャンピオンを使っているか1つ1つ見ていくとなると時間がいくらあっても足りません。

そこで今回は機械学習を使います。

検証開始!

データを確認し使える状態に直す

前回と同様にデータを読み込みいらない情報はカットします。

import pandas as pd
import numpy as np
from scipy.sparse import csr_matrix
from sklearn.neighbors import NearestNeighbors

whole_data = pd.read_csv('matchinfo.csv')
player_info = whole_data[["blueMiddle", "blueMiddleChamp"]]
#今回はブルーのミッドレーンを担当したユーザーの名前と使ったチャンピオンのデータだけ使う

player_info.describe()

これでいらないデータはカットできたので概観を確認してみましょう。

総プレイヤーの数が多すぎると一人当たりの出場した試合数が少ないということになり「傾向」を掴むのが難しくなるからです。

blueMiddle blueMiddleChamp
count 7583 7620
unique 322 71
top Faker Orianna
freq 177 643

使われたチャンピオンの数は71種類。
プレイヤーの数は322人なので一人当たりの出場回数といった懸念事項は大丈夫そうです。
一方で困ったことにblueMiddleとblueMiddleChampでデータの個数が違うので欠損があると見られます。
ちょっと見てみましょう。

player_info.isnull().sum()


blueMiddle         37
blueMiddleChamp     0

isnull().sum()を使い2つの項目でどちらにどの欠損があるか調べてみました。
これによるとユーザーの名前でわからないものがあるようです。

player_info = player_info.dropna()

player_info.describe()
player_info.isnull().sum()
blueMiddle blueMiddleChamp
count 7583 7583
unique 322 71
top Faker Orianna
freq 177 643
blueMiddle         0
blueMiddleChamp    0

dropna()を用いて欠損データを除外し綺麗な状態になっているか確認しました。

これで大丈夫ですしプレイヤーやチャンピオンの種類に支障はなさそうです。

さらなるデータ加工で新しい表を作成!

次に各チャンピオンがどのユーザーに使われているかを可視化する必要があります。

アマゾンやネットフリックスを例にしましょう。

ユーザーごとに違った商品や作品が出てくるのは誰が何をどれくらい評価しているかを詳細に記録しておりそこからどれを売ればお金を落としてもらえる傾向にあるかプログラムが学習してくれているからです。

今回は評価を各ユーザーに選ばれた回数としデータ処理を進めていきます。

player_info["usage"] = 1
player_info.head()
blueMiddle blueMiddleChamp usage
0 Bjergsen Ahri 1
1 Jesiz Ahri 1
2 Pobelter Fizz 1
3 XiaoWeiXiao Leblanc 1
4 Link Lissandra 1

先程の表にusageを追加しました。

一回の試合で1つのチームから同じチャンピオンを2体以上使われることはないので一律で1としています。

次はユーザーとチャンピオンの組み合わせで全く同じものをひとまとめにしusageを2,3...とまとめていきます。

player_info = player_info.groupby(["blueMiddle", "blueMiddleChamp"])["usage"].sum().reset_index()

player_info.head(5)#最初から数え5つまで表示
blueMiddle blueMiddleChamp usage
0 Abaria Azir 3
1 Abaria Corki 1
2 Abaria Karma 2
3 Abaria Kassadin 1
4 Abaria Leblanc 2

これで各ユーザーがどのチャンピオンを使っているかの回数をまとめるのに成功しました。

さらに加工し縦軸はチャンピオン名、横軸をユーザーという形の表を作っていきます。

player_info_pivot = player_info.pivot(index= 'blueMiddleChamp',columns='blueMiddle',values='usage').fillna(0) 
player_info_pivot_sparse = csr_matrix(player_info_pivot.values)
blueMiddle Abaria Abbedagge Abou222 Ace
blueMiddleChamp
Ahri 0.0 0.0 0.0 0.0
Akali 0.0 0.0 0.0 0.0
Anivia 0.0 0.0 0.0 0.0
AurelionSol 0.0 0.0 0.0 0.0
Azir 3.0 0.0 0.0 2.0

pivot()を用いて各チャンピオンに対し誰がどれくらい使っているかを表にできました。

ここで表示させているのはごく一部です。

AbariaというプレイヤーはAzirを3回使っていることがわかります。

他の項目で0.0になっているのは一度も使われていないことを意味しています。

機械学習開始!

今回作ったデータをk近傍法という機械学習の手法を使って学習させます。

簡単にいうと今回学習させた中で特定のチャンピオンを指定した時にそれと最も近い距離にあるチャンピオンを割出してくれます。

これによって指定したチャンピオンを使っているユーザーは他にどのチャンピオンを使っているか見ることができます。

前回採用率の低さに対し高い勝率を誇っていたMalzaharで見てみましょう。

knn = NearestNeighbors(n_neighbors=9,algorithm= 'brute', metric = 'cosine')
model_knn = knn.fit(player_info_pivot_sparse)

Champion = "Malzahar"
distance, indice = model_knn.kneighbors(player_info_pivot.iloc[player_info_pivot.index==Champion].values.reshape(1, -1),n_neighbors=11)
for i in range(0, len(distance.flatten())):
    if i == 0:
        print('Recommendations if you use the champion {0}:\n'.format(player_info_pivot[player_info_pivot.index== Champion].index[0]))
    else:
        print('{0}: {1} with distance: {2}'.format(i,player_info_pivot.index[indice.flatten()[i]],distance.flatten()[i]))

ここで出た結果は以下の通りです。

Recommendations if you use the champion Malzahar:

1: Viktor with distance: 0.34904342083186113
2: Taliyah with distance: 0.3723002696233345
3: Karma with distance: 0.42070673240848855
4: Azir with distance: 0.44118057612305706
5: Corki with distance: 0.4434960701685541
6: Ryze with distance: 0.47858784720918135
7: Vladimir with distance: 0.47906757547291845
8: Cassiopeia with distance: 0.4950791597239671
9: Varus with distance: 0.5029226155596387
10: AurelionSol with distance: 0.5217205327935888

学習させたものを基に指定したチャンピオンから距離の近いもの上位10位までを表すことに成功しました。
チャンピオン名の後に"with distance:"で指定したチャンピオンとの距離を表しています。 0に近いほど近い距離になります。

ここで前回の記事で作成した表と見比べてみましょう。

blueMiddleChamp Num of Selected Selected Rate Total Winning Winning Rate
Orianna 643 8.438320 341 53.032659
Viktor 621 8.149606 298 47.987118
Syndra 526 6.902887 299 56.844106
Azir 489 6.417323 285 58.282209
Corki 446 5.853018 232 52.017937
Leblanc 421 5.524934 221 52.494062
Cassiopeia 391 5.131234 217 55.498721
Taliyah 388 5.091864 236 60.824742
Ryze 366 4.803150 208 56.830601
Ahri 334 4.383202 185 55.389222
Vladimir 311 4.081365 160 51.446945
Lulu 225 2.952756 119 52.888889
Lissandra 199 2.611549 114 57.286432
Zed 183 2.401575 112 61.202186
Jayce 180 2.362205 89 49.444444
Kassadin 167 2.191601 90 53.892216
Galio 154 2.020997 81 52.597403
Karma 153 2.007874 72 47.058824
TwistedFate 153 2.007874 79 51.633987
Malzahar 131 1.719160 84 64.122137

比較してみるとレコメンドで1位になっているViktorなど前回の表と合致するものもいることがわかります。

これらを照合し「低めの採用率だけど高い勝率」「本命のチャンピオンを使っているユーザーが他に選ぶもの」を軸に複数の候補を用意することで、相手のBANで戦力を一気に削がれるというリスクを下げることができます。

おわりに

「採用率は低いけど勝率の高いチャンピオン」の続きで、自分が使おうと思っているチャンピオンがBANされた場合の代替案を見つけるプログラムを作りました。

そのために機械学習を用いており、例えばMalzaharを使っているユーザーは他にどういったチャンピオンを選んでいるかを出力させています。

そこには前回まとめた採用率の高いチャンピオン上位20位に入るものもあり照合した上でどのように第2第3候補を選んでいくかが鍵になります。

前回と今回では「チャンピオン選び」というところからの簡単な分析だったので引き続き分析をし、できたものからあげていきます。

参考記事

機械学習を使って630万件のレビューに基づいたアニメのレコメンド機能を作ってみよう(機械学習 k近傍法 初心者向け)

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away