【Python】seabornのグラフを活用したデータ分析の手法メモ

#はじめに

Kaggleなどでデータ分析を行う際の探索的データ解析（EDA）の段階で、
自分自身がよく使うデータのビジュアル化、グラフ化に関する手法をまとめました。

今回はmatplotlibのラッパー、seabornをメインで活用していきます。
参考： https://seaborn.pydata.org/index.html


#各グラフの実装

###**■インストール/ライブラリの読み込み**

```py
#未インストールの方は
pip install seaborn
```

```py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set() 
%matplotlib inline
```

###**■データの読み込み**

データはKaggleのHousePriceのTrainデータを使用します
https://www.kaggle.com/c/house-prices-advanced-regression-techniques

```py
df = pd.read_csv('House Price/train.csv')
```
```py
df.head()
```
<img width="689" alt="Screen Shot 2019-02-10 at 21.05.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/92a18a5a-a24a-76bf-7ce5-634c568272d3.png">


81列のデータで、ここでは確認できませんが最終列の SalePrice が目的変数データです。


###**■棒グラフの活用**

項目ごとのデータの数量を把握する際に使います。

- **sns.countplot(x='列名', data = データ名)**

```py
sns.countplot(x='YrSold', data = df);
```
<img width="394" alt="Screen Shot 2019-02-10 at 19.29.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/18d033a5-ed03-5c60-c3b7-4299190e99c4.png">

###**■ヒストグラムの活用**

データの分布を把握したい際に利用します。

- **sns.distplot(データ名.列名);**

```py
sns.distplot(df.YearBuilt);
```

<img width="383" alt="Screen Shot 2019-02-10 at 19.30.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/b307093c-622f-8e56-db63-7701e8a48b77.png">


カーネル密度推定(KDE)も加えて出力してくれます。
　
###**■散布図の活用**

散布図を活用し、2つの変数間の相関関係を可視化します。

- **データ名.plot(kind='scatter', x='列名1', y='列名2')**

```py
df.plot(kind='scatter', x='LotFrontage', y='SalePrice');
```
<img width="400" alt="Screen Shot 2019-02-10 at 19.32.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/4badf4e1-405b-71e5-f2e1-a3d9b564d843.png">
　

- **sns.regplot(x=データ名.列名1, y=データ名.列名2)**

　こちらは線形回帰直線を含むタイプです。

```py
sns.regplot(x=df.LotFrontage, y=df.SalePrice);
```
<img width="404" alt="Screen Shot 2019-02-10 at 19.33.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/91c41290-d150-c258-eb5c-d178915be4bb.png">


正の相関があり、LotFrontageが上がればSalePriceも上がることが分かります。
　



###**■散布図の応用**
**複数散布図をまとめて表示**

目的変数（SalePrice）と他の数値データの相関関係をまとめて表示します。
最大表示可能数は30なので、変数が30を超える場合は全て表示できません。

```py
#数値データの列のみに絞る
df_n = df.select_dtypes(include=[np.number])

#グラフを作る
fig = plt.figure(figsize=(14,9))
for i in np.arange(30):  #30が最大
    ax = fig.add_subplot(5,6,i+1)
    sns.regplot(x=df_n.iloc[:,i], y=df_n.SalePrice)

#グラフを整えて表示
plt.tight_layout()
plt.show()
```
<img width="994" alt="Screen Shot 2019-02-10 at 19.34.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/ed90ee59-7439-08fb-4a8d-67bb9d932d8f.png">





###**■ボックスプロット(箱ひげ図)の活用**

ボックスプロットを使い、オブジェクトデータと他の変数の関係性を視覚化します。

**sns.boxplot(x="列名1", y="列名2", data=データ名)**


```py
sns.boxplot(x="SaleCondition", y="SalePrice", data=df);
```

<img width="400" alt="Screen Shot 2019-02-10 at 19.35.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/83412e8c-6185-3794-b8d6-348b2e965036.png">



###**■ボックスプロットの応用**

**全てのオブジェクトデータと目的変数(SalePrice)の関係性をまとめて表示**

dfの部分にデータ名、SalePriceの部分に目的変数を入力し直すと他のデータでも使えます。


```py
categorical_features = df.select_dtypes(include=[np.object])
for c in categorical_features:
    df[c] = df[c].astype('category')
    if df[c].isnull().any():
        df[c] = df[c].cat.add_categories(['MISSING'])
        df[c] = df[c].fillna('MISSING')

def boxplot(x, y, **kwargs):
    sns.boxplot(x=x, y=y)
    x=plt.xticks(rotation=90)
f = pd.melt(df, id_vars=['SalePrice'], value_vars=categorical_features)
g = sns.FacetGrid(f, col="variable",  col_wrap=2, sharex=False, sharey=False, size=5)
g = g.map(boxplot, "value", "SalePrice")
```
出力グラフの一部を表示
(実際には全てのオブジェクト変数のボックスプロットが表示されます)

<img width="710" alt="Screen Shot 2019-02-10 at 19.36.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/cd2ace26-8cd1-1f59-a933-de8a9463b12a.png">



###**■ヒートマップの活用**

全ての数値データ同士の相関関係をヒートマップで表示

```py
plt.figure(figsize=(13, 11))
sns.heatmap(df.corr())
plt.tight_layout();
```
<img width="858" alt="Screen Shot 2019-02-10 at 19.37.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/29cc4363-4783-0996-4e7b-cd97a4a5b980.png">


###**■ヒートマップの応用**

**目的変数列(SalePrice)と相関度の高い列ベスト10をヒートマップで表示**
どの変数が重要かがすぐに理解でき、変数を絞る際に有効です。

```py
cols = df.corr().nlargest(10,'SalePrice')['SalePrice'].index
cm = np.corrcoef(df[cols].values.T)

plt.subplots(figsize = (12,10))
sns.heatmap(cm, vmax=.8, linewidths=0.01, annot=True, cmap='viridis',
            xticklabels=cols.values, yticklabels=cols.values, annot_kws={'size':14});
```
<img width="714" alt="Screen Shot 2019-02-10 at 18.42.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/f1ce035d-f5ef-afdd-d40e-f91ad5ec6c69.png">



###**■ペアプロットの活用**

**ペアプロットで指定の数値データ列の相関関係をまとめて表示**

```py
cols = ['SalePrice', '1stFlrSF', 'PoolArea', 'OverallQual'] #任意の列を指定、さらに増やしてもよい
sns.pairplot(df[cols], size=3)
plt.tight_layout();
```

<img width="865" alt="Screen Shot 2019-02-10 at 19.13.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/2392c641-a366-45d4-0bb7-3c23b996a9f9.png">


# まとめ

分析の際によく使うデータビジュアリゼーションの手法を列記しました。
変数間の関係性を可視化し理解することで、データ分析の精度をさらに高めることが可能です。
また、seabornは視認性の高さもさることながら、背景色や色のトーン等非常にセンスがよく分析を楽しくしてくれます。

### 参考
Matplotlib&Seaborn実装ハンドブック（秀和システム）
The Python Graph Gallery ： https://python-graph-gallery.com/
　

**データ構造を把握した後の、欠損値処理のまとめ記事もよろしければご覧ください。**
https://qiita.com/ryo111/items/4177c732cc9801bccb17