エンジニア

2018.06.26

見よう見まねで機械学習をやってみた(ポケモン編)

見よう見まねで機械学習をやってみた(ポケモン編)

こんにちは!新卒の清水です。
最近、勉強または趣味でやっていたPyQの機械学習・初級をやり終えたので自分でもやってみました。

題材

以前Kaggleのチュートリアルはやったことはありますが、用意されているデータの説明がやはり英語だったのでそれなりにハードルがありました。
なので今回はネットを放浪中にポケモンのcsvデータがあったので、これを使用して行きたいと思います。

何をする?

個人的にみずタイプのポケモンが好みなのでステータスからみずタイプかどうか判定しようと思います。

環境

OS: macOS High Sierra 10.13.5
Python: 3.6.5
scikit-learn : 0.19.1
jupyter notebook

とりあえずデータをみてみる

pandasを使用してcsvデータを読み込みます。

pip3 install pandas
import pandas as pd
df = pd.read_csv('pokemon_status.csv')
df.head(10)

df.info()


ポケモンが909体(メガ進化も含む)なのでどうやら第七世代(サン・ムーン)までのデータのようです。

データの選別

ポケモンの各ステータス(HP, こうげき, ぼうぎょ, とくこう, とくぼう, すばやさ)を説明変数X、タイプを目的変数yとして学習させていこうと思います。
みずタイプであるのか、そうでないのかで判断したいのでみずタイプのポケモンには1をそうでないものには0を付与します。
関数を用意

def type_to_num(type):
    if type == 'みず':
        return 1
    else:
        return 0
# type_numの列を作成
df['type_num'] = df['タイプ1'].apply(type_to_num)

applyメソッドを使用すると指定した列データ全てに関数を実行してくれます。
データをみてみましょう。

df.iloc[9:15]


みずタイプが含まれている行を出してみました。みずタイプには1が振られています。

学習させる

もちろんscikit-learnを使用して学習させます。
今回は目的変数が2値なのでロジスティック回帰で行います。
トレーニングデータとテストデータの割合は7:3で分割します。

pip install scikit-learn

C = 1000としていますがこのCはハイパーパラメータと呼び、Cの値が大きすぎるほど過学習しやすくなり、小さすぎると学習にならない問題があります。
今回はCの値を0.01, 0.1, 1, 10, 100, 1000とパラメータを変えて影響があるか確認し、特に影響がなかったので1000のまま放置してます。


X = df.iloc[:,7:12]
y = df['type_num']
# トレーニングデータとテストデータに分ける
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
# ロジスティック回帰の呼び出し
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression(C=1000)
# データを学習させる
lr.fit(X_train, y_train)
# スコアを表示
lr.score(X_test, y_test)


およそ87%の割合で判定することができました。
ほぼ自分一人の力で機械学習をしたのは初めてなのでまぁまぁいいのではないかと思います。

考察

判定に失敗した例としてオーダイルをみずタイプではないと判定しました。
そんなにポケモンを知らなくても、見れば多くの人はみずタイプだろうと判断するでしょう。

しかし、オーダイルの進化前のアリゲイツはみずタイプと判定しました

改善案としてはステータスの族ごとに学習をさせることで改善することはできると思います。
ですが、より高い精度を求めるならポケモンの画像データを使用するのがいいと思いました(全体的に青っぽいとか)。

最後に

ポケモンの知識がないと難しいところがあるのでやはりデータのリサーチは必要だということを感じました。
全体的な機械学習の流れは覚えられてきたのでこれから色々と試していきたいと思います。

一覧に戻る