LoginSignup
9
6

More than 3 years have passed since last update.

伝説ポケモンの特徴ってなんだ?~主成分分析(教師なし学習)で解き明かす~

Last updated at Posted at 2020-06-16

はじめに

データ分析をしてみたいけど、どのデータを分析しよう…
と途方に暮れていたところkaggleサイトにて馴染みのあるポケモンのデータセットを見つけました。
なんか面白そう。とりあえずやってみるか。

やってみたい方はこちらへ
https://www.kaggle.com/abcsds/pokemon

image.png

主成分分析ってなに?

ビッグデータは“多変量”が当たり前。
たくさんのデータ項目(変数)を横断的に見て解釈することが求められる。
こんな時、情報の損失を最小限にしつつ、できるだけ少ない変数に置き換えられる素晴らしい手法が存在している。
それが主成分分析!

つまり、
たくさんの変数(特徴)があるときに、それをごく少数の(たいていは1~3の)項目に置き換えることで、データを解釈しやすくできる分析手法。

データセット


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('whitegrid')

df = pd.read_csv('Pokemon.csv')
df.head()

image.png

出力の1行目をみると、
フシギダネ

Bulbasaur(フシギダネ)

  • 属性はGrass(草),Poison(毒)

  • Total=HP+攻撃力+防御力+特攻+特防+素早さ

  • HP=49

  • 攻撃力=49

  • 防御力=49

  • 特攻=65

  • 特防=65

  • 素早さ=45

  • 第一世代のポケモン

  • 伝説ポケモンではない

以上の特徴が分かる。

型名,欠損値確認

df.info()

データ型

考察

「Type2」には欠損値が386個あることが分かる。
これは「Type1」には欠損値がないことから、属性が一つのみのポケモンが800匹中387匹にいると推定できる。

説明変数、目的変数

今回は「HP」「Attack」「Defense」「Sp.Atk」「Sp.Def」「Speed」を説明変数、「Legendary」を目的変数として分析してみようと思う。

#カラム「Legendary」の値をbool型からint型へ変更
df['Legendary'] = df['Legendary'].astype(int)
#不要カラム削除
df= df.drop(['Name', 'Type 1','Type 2'], axis=1)

試しに2変数を説明変数に

#とりあえず「HP」と「Attack」からLegendaryを可視化
fig, ax = plt.subplots(figsize=(12 , 8))
df.plot(kind='scatter', x='HP', y='Attack', s=100, 
        c='Legendary', cmap='winter', alpha=0.5, ax=ax)

image.png

緑の点伝説ポケモン青の点普通のポケモン

考察

このグラフから2変数「HP」と「Attack」だけでは、全然分類できないことが分かる。(緑の点と青の点を分ける線を綺麗に引けないなぁ…)

相関関係

#相関関係を数値化
df.loc[:, 'HP':'Speed'].corr()

image.png

#相関関係を可視化
sns.pairplot(df.loc[:, 'HP':'Speed'])

image.png

考察

  • 「Deffense」と「Sp.Def」=「0.510747」
  • 「Sp.Atk」と「Sp.Def」=「0.516121」
  • 上記の変数に相関関係がありそうなので、主成分分析データを圧縮できそう!

主成分分析

from sklearn.decomposition import PCA
# 元の特徴量と同じ数で主成分分析
pca = PCA(n_components=6)#PCAインタンス生成
X_pca = pca.fit_transform(df.loc[:, 'HP':'Speed'])
df_pca = pd.DataFrame(X_pca, columns=['1st', '2nd', '3rd', '4th', '5th', '6th'])
df_pca.head()

image.png

#寄与率(~主成分は全体のデータの内の何%の情報を表しているか)
pca.explained_variance_ratio_

image.png

#累積寄与率を可視化
plt.figure(figsize=(10, 8))
plt.plot(np.hstack([0, pca.explained_variance_ratio_.cumsum()]))
plt.xlabel("n_components", fontsize=15)
plt.ylabel("explained_variance_ratio_", fontsize=15)
plt.show()

image.png

考察

第一主成分~第三主成分まででオリジナルデータ(「HP」「Attack」「Defense」「Sp.Atk」「Sp.Def」「Speed」)の6つの情報(データ)約80%表せていることが分かる。

主成分分析の負荷量ベクトル

スコアのばらつき度合い最大になる時のベクトル。
つまり、情報をより蓄えている時のベクトルを表している。

#各主成分負荷量を数値化
pca.components_

image.png

#各主成分の負荷率を可視化
plt.figure(figsize=(14, 12))
sns.heatmap(pca.components_, 
            cmap='Blues', 
            annot=True, 
            annot_kws={"size": 20},
            fmt="1.1f",
            xticklabels=df.loc[:, 'HP':'Speed'].columns,
            yticklabels=['1st', '2nd', '3rd', '4th', '5th', '6th'])

image.png

考察

  • 第一主成分「HP,Attack,Defense,Sp.Atk,Sp.Def,Speedが高い」 vs 「それらが低い」でデータを散らばせていることが分かる。つまり総合力の差

  • 第二主成分「Defenseが高く、そしてSp.Atk,Speedが低い」vs 「Defenseが低く,Sp.Atk,Speedが高い」でデータを散らばせていることが分かる。

  • 第三主成分「Attackが低く,そしてSp.Atk,Sp.Defが高い」 vs 「Attackが高く,そしてSp.Atk,Sp.Defが低い」でデータを散らばせていることが分かる。

可視化

#横軸:第一主成分,縦軸:第二主成分
df_pca['Legendary'] = df['Legendary']

fig, ax = plt.subplots(figsize=(12 , 8))
df_pca.plot(kind='scatter', x='1st', y='2nd', s=100, 
            c='Legendary', cmap='winter', alpha=0.5, ax=ax)

image.png

#横軸:第一主成分,縦軸:第三主成分
df_pca['Legendary'] = df['Legendary']

fig, ax = plt.subplots(figsize=(12 , 8))
df_pca.plot(kind='scatter', x='1st', y='3rd', s=100, 
            c='Legendary', cmap='winter', alpha=0.5, ax=ax)

image.png

考察

  • 上図から、第一主成分の値大きいほど伝説ポケモンが、小さいほど普通のポケモンであると分類できていることが分かる。
  • 第二主成分,第三主成分は第一主成分ほどきれいに分類できておらず、伝説ポケモンの特徴を掴むことは難しいと分かる。

まとめ

伝説ポケモンの特徴総合値が高いことが改めて分かった。
特定のスキルが高いからといって、伝説ポケモンであると言えることは難しいことも分かった。
実際に伝説ポケモンのデータをみてみると…
image.png

フシギダネ フシギダネ フシギダネ フシギダネ 

総合値高いですね…
今回は「ポケモンの世代」,「属性」を考慮していなかったのでこの2変数も分析に加えてみようと思う。
因みに上記の4匹伝説ポケモンは知りませんでした…

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6