ゼロから始める機械学習 #2

# 最終目的

プログラミングを全くやったことがないという状態から，機械学習を行えるようになるまで，順に勉強する．

第一回目は，下記参照

https://qiita.com/t-baba-11/items/054bda7060952fc6bf74

# 第二回 目標と流れ

- 目標 : 学習データの中身を確認し，特徴量を選択する．
- 流れ : 
    - 使用するライブラリの説明
        - seaborn
        - ライブラリのインポート
    - 特徴量とは
    - データを確認する
        - カラムの説明
    - 特徴量の抽出
        - ペアプロット図
        - 相関行列
        - 抽出した特徴量での行列の作成
    - 実際に使う特徴量を決める

プログラムは前回のものに追記する形で書いていく．

# 使用するライブラリの説明
### seaborn

Pythonのデータ可視化ライブラリ


### ライブラリのインポート
```.py
import seaborn as sns
```

# 特徴量とは

特徴量とは，機械学習において，訓練を行う際に使用するデータの特徴・特性を、定量的に表した数値である．

特徴量の大切さ

- 機械学習では，特徴量を使って学習する
- 意味のある特徴量を使わなければならない
- 特徴量の決め方で，学習モデルの性能は全く違う
- 特徴量の選定は，機械学習のチューニングの中で最も大切なこと

今回は，与えられた学習データを使っているが，本来は学習データを収集する時から特徴量のことを考えなければならない．

※深層学習の場合は使用する特徴量を自動で決定してくれるので，すべての特徴量を入力しても問題ないが，目標となる答えと全く関係ない特徴量だけを入力しても，学習はできない．

まずは，学習用のデータを確認する．

 - どういった情報があるのか？
 - 本当にその情報で問題を解決できるのか？

例えば，河川水位を予測しようとする，この時

 - 雨量
 - 気温
 - 湿度
 - 交通量

のデータがあるとする．感覚的には，交通量は全く関係がなく，
気温や湿度はあまり関係がなさそうで，雨量は河川水位と関係が深そうである．
このため，特徴量として，雨量を用いるのが適当と言える．
全く関係ない交通量を特徴量として，使用しても学習できない．

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/8e689b5a-8c6c-2bab-e966-8c86e7c93c52.png" width="30%">


しかし，どのように特徴量を選択するのかが問題となる．

今回は，相関関係をもとにした特徴選択を行う．
※相関関係とは，一方が増加するとき、他方が増加もしくは減少する傾向が認められる二つの量の関係


# データを確認する

特徴選択を行うにあたり，学習データの中身を確認することは重要である．


```.py
df.head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/e868d2e3-9722-341c-9aaf-2ce3e781ab5e.png)



### カラムの説明

AhとWhは，訓練データには含まれるが，テストデータには含まれていないので，実装するときは注意．
今回は，AhとWhも含めて特徴量の抽出を行っている．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/4411fb1e-c6e7-1386-b25a-aacd1a339b82.png)



# 特徴量の抽出

### ペアプロット図

相関関係をわかりやすくするため，ペアプロット図を出力.
ここから何が分かるか考えてみる．


```.py
sns.pairplot(df)
```

![index.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/ed46e6ea-a3b9-8fe9-218b-9d38b69fb532.png)


ペアプロット図を見て，SOCと相関関係があるカラムが分かれば，その特徴の行列を作り完了．

```.py
select_cols = ["Voltage", "Ah", "Battery_Temp_degC", "Time"] #相関関係のあるカラムを選択
df_new = df.loc[:,select_cols] #行列を作成
df_new.head()
```


### 相関行列

ここから先は，ある程度分かる人だけでも良い．

ペアプロット図では，特徴量の数が増えすぎると確認できなくなるため，
相関係数を求め，相関行列に置き換える．
※相関係数とは，2つのデータ間の関係性を数値化したものである．

各，特徴量間の相関係数を求め，ヒートマップとして，表示する．


```.py
corr_matrix = df.corr() #相関係数の計算(デフォルトでは，ピアソンの積率相関係数)
print(corr_matrix)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/44ec3dfe-1ed6-5aef-6329-ab16a7e981dd.png)

ヒートマップの表示．
値が0に近いほど関係が浅く，1や-1に近いほど関係が深い．

```.py
sns.heatmap(corr_matrix, #相関係数
            square=True, #正方形で表示
            annot=True, #数値を表示
            xticklabels=corr_matrix.columns.values, #x軸のラベル
            yticklabels=corr_matrix.columns.values #y軸のラベル
          )
```

![index.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/1492c048-d34c-2553-018e-51de34fd95f1.png)



### 抽出した特徴量での行列の作成

目標値であるSOCとの相関係数だけ表示する．

```.py
df_copy = df.copy()
df_copy = df_copy.drop(["TimeStamp","Drive Cycle"], axis=1) #数値じゃない特徴量を除去

#SOCとの相関係数のみ抽出
corr_y = pd.DataFrame({"features":df_copy.columns,"corr_SOC":corr_matrix["SOC"]},index=None) 
corr_y = corr_y.reset_index(drop=True)
corr_y.style.background_gradient()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/03c43fb1-85d8-b860-accb-088af3eaa5fe.png)


相関係数の値が高いものだけを選択し，
その特徴量だけの行列に置き換える．

```.py
select_cols = corr_y[corr_y["corr_SOC"].abs()>0.5] #相関係数の絶対値が0.5より大きいものを選択
print(select_cols)
 
select_cols = list(select_cols["features"])

df_new = df.loc[:,select_cols] # 選択した特徴量の行列のみ抽出
df_new.head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/2cbd607c-422a-42c0-7816-00c0768f96d1.png)

#実際に使う特徴量を決める

今回抽出した特徴量のAhとWhはテストデータには含まれないため，実際には使用できない．
しかし，ほかの特徴量は，相関があまりなく，学習の性能が向上しない．
なので，下記のチューニング編のように特徴量を自作する必要がある．

https://qiita.com/t-baba-11/items/34f8d2f478504a339481