---
# System prepended metadata

title: KNN分類演算法(K-nearest neighbors algorithm)
tags: [ml, data_mining]

---

# KNN分類演算法(K-nearest neighbors algorithm)
[TOC]

###### tags: `data_mining` `ml`
---

### 演算法定義
* 假設欲預測點是 i
  找出離 i最近的 k 筆資料多數是哪一類，預測 i 的類型
   * Given a test instance i, find the k closest neighbors and their labels
Predict i’s label as the majority of the labels of the k nearest neighbors
![](https://i.imgur.com/y3j5JtR.png =x300)
* KNN屬於機器學習中的監督式學習(Supervised learning)，不過一般來說監督式學習是透過資料訓練(training)出一個model，但是在KNN其實並沒有做training的動作。
* KNN一般用來做資料的分類，如果你已經有一群分好類別的資料，後來加進去點就可以透過KNN的方式指定新增加資料的分類。K表示一個常數，簡單的來說就是KNN就是看離你最近的K的點，然後看哪個類別的點最多就把自己也當成那個類別。你如果只看3個點，就是3NN囉。
---
### How to select k?
![](https://i.imgur.com/kvMFgF8.png)
* 選擇一個好的k會讓training出來的model有足夠的彈性
  * k=1--->overfitting
    * ==參數過多==導致過度符合Training set的資料特性
---
#### What if k is an even number?

* 有可能碰到無法直接決定類別的時候
　　需要再去針對該情況作==exception handling==
----
#### What if k equals the number of the training instances?
* k=n的話，預測結果一定是資料數量最多的那一類
  等於喪失kNN預測的效果
* underfitting
  
----
### 實作
* 如何用==sklearn==完成KNN
* 資料切分
   * KNN分類
   * KNN預測
#### 程式碼說明
* sklearn
``` python=
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import numpy as np

``` 
* dataset--->
  * load_iris
``` python=
iris = datasets.load_iris()
``` 
* 可以得到安德森鳶尾花卉數據集
![](https://i.imgur.com/ZWiPWCh.png =x300)

* 定義特徵資料
iris_data = iris.data
iris_label = iris.target

* 可以印出前三筆資料檢查
``` python=
iris_data[0:3]

```
* 可以看到結果
``` python=
array([[ 5.1,  3.5,  1.4,  0.2],
       [ 4.9,  3. ,  1.4,  0.2],
       [ 4.7,  3.2,  1.3,  0.2]])
``` 
##### train_test_split
``` python=
train_data , test_data , train_label , test_label = train_test_split(iris_data,iris_label,test_size=0.2)
``` 
* training set:0.8
* testing set:0.2
##### sklearn KNeighborsClassifier()
``` python=
knn = KNeighborsClassifier()
``` 
* 將資料做訓練
 ``` python=
knn.fit(train_data,train_label)
``` 
* 預測我們剛剛切分出來的test_data資料
``` python=
print(knn.predict(test_data))
``` 
``` python=
print(test_label)
``` 
![](https://i.imgur.com/GGGNCDp.png =x110)
##### 結果
預測結果--->
test_data和test_label 只有差一筆


---
### 參考資料
[colab連結](https://colab.research.google.com/drive/1qkVQp4s--XzjwEqIYgd_vz25Tgia-Duc?usp=sharing)
[colab參考他人code](https://colab.research.google.com/github/teliofm/Minerando/blob/master/Scikit_Learn_KNN_Best_Practices.ipynb#scrollTo=lvSqHS1nKZJJ)
