#はじめに
データ分析をしてみたいけど、どのデータを分析しよう…
と途方に暮れていたところkaggleサイトにて馴染みのあるポケモンのデータセットを見つけました。
なんか面白そう。とりあえずやってみるか。
やってみたい方はこちらへ
https://www.kaggle.com/abcsds/pokemon
#主成分分析ってなに?
ビッグデータは“多変量”が当たり前。
たくさんのデータ項目(変数)を横断的に見て解釈することが求められる。
こんな時、情報の損失を最小限にしつつ、できるだけ少ない変数に置き換えられる素晴らしい手法が存在している。
それが主成分分析!
つまり、
たくさんの変数(特徴)があるときに、それをごく少数の(たいていは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()
**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)
緑の点が伝説ポケモン。青の点が普通のポケモン。
##考察
このグラフから**2変数「HP」と「Attack」**だけでは、全然分類できないことが分かる。(緑の点と青の点を分ける線を綺麗に引けないなぁ…)
#相関関係
#相関関係を数値化
df.loc[:, 'HP':'Speed'].corr()
#相関関係を可視化
sns.pairplot(df.loc[:, 'HP':'Speed'])
##考察
- 「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()
#寄与率(~主成分は全体のデータの内の何%の情報を表しているか)
pca.explained_variance_ratio_
#累積寄与率を可視化
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()
##考察
第一主成分~第三主成分までで**オリジナルデータ(「HP」「Attack」「Defense」「Sp.Atk」「Sp.Def」「Speed」)の6つの情報(データ)を約80%**表せていることが分かる。
##主成分分析の負荷量ベクトル
スコアのばらつき度合いが最大になる時のベクトル。
つまり、情報をより蓄えている時のベクトルを表している。
#各主成分負荷量を数値化
pca.components_
#各主成分の負荷率を可視化
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'])
##考察
-
第一主成分は**「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)
#横軸:第一主成分,縦軸:第三主成分
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)
##考察
- 上図から、第一主成分の値が大きいほど伝説ポケモンが、小さいほど普通のポケモンであると分類できていることが分かる。
- 第二主成分,第三主成分は第一主成分ほどきれいに分類できておらず、伝説ポケモンの特徴を掴むことは難しいと分かる。
#まとめ
伝説ポケモンの特徴は総合値が高いことが改めて分かった。
特定のスキルが高いからといって、伝説ポケモンであると言えることは難しいことも分かった。
実際に伝説ポケモンのデータをみてみると…
総合値高いですね…
今回は**「ポケモンの世代」,「属性」を考慮していなかったのでこの2変数**も分析に加えてみようと思う。
因みに上記の4匹伝説ポケモンは知りませんでした…