【ラビットチャレンジ】要点のまとめ - 機械学習 その５

# 1. はじめに
本記事はJDLA E資格の認定プログラム「ラビットチャレンジ」における機械学習のレポート記事である。
本記事では機械学習における「アルゴリズム（k近傍法・k-平均法）」について要点をまとめている。

[【ラビットチャレンジ】要点のまとめ - 機械学習 その１](https://qiita.com/PoppeDwarf/items/92ba5a6ebd35a9f53ae0)
[【ラビットチャレンジ】要点のまとめ - 機械学習 その２](https://qiita.com/PoppeDwarf/items/80724b0b92d01c9a9421)
[【ラビットチャレンジ】要点のまとめ - 機械学習 その３](https://qiita.com/PoppeDwarf/items/30944bca17d2c7f8c5ee)
[【ラビットチャレンジ】要点のまとめ - 機械学習 その４](https://qiita.com/PoppeDwarf/items/01cc119c707fe3e26f1d)
【ラビットチャレンジ】要点のまとめ - 機械学習 その５
[【ラビットチャレンジ】要点のまとめ - 機械学習 その６](https://qiita.com/PoppeDwarf/items/83f7e350e6720e801038)

# 2. k近傍法（kNN）
## 2.1. k近傍法とは
k近傍法とは、分類問題のための機械学習手法。教師あり学習の一。
kNN、あるいはk Nearest Neighborとも言う。

## 2.2. アルゴリズム
分類するデータに関して、最近傍のデータを$k$個取得してそれらのうち最も多くのデータが所属するクラスに分類する。
$k$はハイパーパラメータであり、学習前に人が適切に値を設定しておく必要がある。
　→$k$を大きくするほど決定境界は滑らかになる。

# 3. ハンズオン
## 3.1. 課題
kNNの動作をnumpy, scikit-learn双方で確認する。

## 3.2. 演習結果
必要なモジュールのインポート。
![05_01_algorism_knn_01_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/c0a51907-4939-1c54-07b7-5428e5bbbe11.jpeg)
乱数より分類するための（分類時に参照する）データを作成する。
![05_01_algorism_knn_01_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/e1c06354-eb5c-d620-821b-4f67833daf5a.jpeg)
上図のようなデータになっている。

「距離を計算する関数」「データを予測する関数」「結果をプロットする関数」を実装する。
![05_01_algorism_knn_02_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/6344bc66-322b-ecd6-fe29-75b4cb855a80.jpeg)
numpyを用いてkNN法で検証データを分類、予測結果をプロットする。
![05_01_algorism_knn_02_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/6b3bc2f8-ddf5-60d2-e250-8bba705f559f.jpeg)
scikit-learnのKNeighborsClassifier関数を用いてkNN法で検証データを分類、予測結果をプロットする。
![05_01_algorism_knn_03_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/e37a52b1-7818-99d4-1a83-655b1bc3b3ba.jpeg)

numpyでの実装、scikit-learnでの実装ともに同様の結果が出ていることがわかる。

# 4. k-平均法（k-means）
## 4.1. k-平均法とは
k-平均法とはクラスタリング手法。教師なし学習の一。
与えられたデータを$k$個のクラスタに分類する。
k-meansとも言う。

## 4.2. アルゴリズム
k-平均法は以下のようなアルゴリズムとなっている。

  1. 各クラスタの中心の初期値を設定
  2. 各データに関して、各クラスタの中心との距離を計算し、最も距離の近いクラスタに分類する
  3. 各クラスタの中心（平均ベクトル）を計算、クラスタの再割り当てと中心の更新を行う
  4. 上記「2.」「3.」を収束するまで繰り返す

このとき、クラスタ数$k$はハイパーパラメータであり、学習前に人が適切に値を設定しておく必要がある。

- 問題  
　各クラスタの中心の初期値が近いとうまくクラスタリングできない場合がある。  
　そのため、対策として分散や確率の概念を用いて各クラスタの初期値を離して設置する「k-means++」といった手法を用いることが多い。初期値の設置での演算の分だけ時間はかかるが、精度の向上が見込まれる。


# 5. ハンズオン
## 5.1. 課題
ワインデータセットを使用してk-meansによる分類を確認する
## 5.2. 演習結果
必要なモジュールのインポート。ワインデータセットをロードする。
![05_02_algorism_kmeans_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/ed266cae-3957-9d71-5813-55d2b24fd431.jpeg)
ワインデータセットの説明を表示。
![05_02_algorism_kmeans_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/6d293ed0-7ee5-cf7e-a7d4-3576703a7b18.jpeg)
ワインデータセットから説明変数および目的変数を取得し、scikit-learnのKMeans関数で学習。
model.fit_predict(X)はクラスタ化を実行し、かつ、クラスタ化の結果であるlabel配列を返すメソッド。

参考：[scikit-learnで機械学習を行う（２） ―K-Means法を使って東京２３区のデータをクラスタに分けるー](http://ishidate.my.coocan.jp/vpy_10/vpy_10.htm)
　　　[scikit-learnのdatasetsにはどんなのが入っているのか調べてみた話【Linnerud, Wine編】](https://ensekitt.hatenablog.com/entry/2018/08/18/200000)
![05_02_algorism_kmeans_03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/34ec07bf-4821-23dd-8501-4c64942a8424.jpeg)
model.fit_predict(X)メソッドの戻り値labels（クラスタ化の結果）をDataFrame化。
目的変数から品種名を取得し、DataFrameにカラム「species」として追加する。
品種名とクラスタ化の結果でクロス集計した結果を表示すると、品種ごとにクラスタリングで分類されていることがわかる。
![05_02_algorism_kmeans_04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/f05ec14c-54c5-095c-d188-941ba46d2a30.jpeg)

## 5.3. 課題
乱数からデータを作成してk-meansによる分類を確認する
## 5.4. 演習結果
必要なモジュールのインポート。
![05_03_algorism_kmeans_01_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/64345f36-4e90-684e-a503-5b717bb59a5b.jpeg)
座標(-5,-5), (5, -5), (0, 5)をそれぞれ中心にしたあたりに正規分布に依る乱数を出力する。
![05_03_algorism_kmeans_01_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/0cc9c126-9391-ed68-1b95-39ee7d4ac9e6.jpeg)
k-meansのアルゴリズムは以下の通り。
![05_03_algorism_kmeans_02_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/c0463bbf-936d-454e-7911-9edeaacf9860.jpeg)
numpyで上記アルゴリズムの通りにk-meansを実装、クラスタリングする。
![05_03_algorism_kmeans_02_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/5dedf4c2-1a04-79a9-8960-fcbd9dff8efd.jpeg)
「データ」「データの中心」および「各クラスタの領域」をプロットする。
![05_03_algorism_kmeans_03_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/cad40699-52cc-ac47-ceef-380ad82a45d2.jpeg)
scikit-learnのk-means法の関数「KMeans」を用いてクラスタリングし、numpyで実装したk-means法と同様にプロットする。
![05_03_algorism_kmeans_04_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110108/9d2bf894-ebec-7faf-f0ab-94d17bd87a1f.jpeg)
numpyで実装したk-meansとscikit-learnのk-meansで同様の結果がプロットされていることがわかる。