【MachineLearning】之 K-近鄰演算法
Topic:
- KNN 演算法原理
- 常用距離演算法
- 決策規則
- Kd 樹
一、KNN 演算法原理
什麼是最近鄰演算法(NN) ?
最近鄰演算法(Nearest Neighbor,簡稱:NN):其針對未知類別資料 ,找到與其距離最近的資料 ,將 劃入 的分類中
如上圖所示,通過計算資料 (未知樣本)和已知類別 (已知樣本)之間的距離,判斷 與不同訓練集的相似度,最終判斷 的類別。顯然,這裡將綠色未知樣本類別判定與紅色已知樣本類別相同較為合適。
什麼是K-近鄰演算法(K-NN) ?
K-近鄰(K-Nearest Neighbors,簡稱:KNN)演算法是最近鄰(NN)演算法的一個推廣。
NN 演算法中只依賴 1 個樣本進行決策,在分類時過於絕對,會造成分類效果差的情況,為解決 NN 演算法的缺陷,KNN 演算法採用 K 個相鄰樣本的方式共同決策未知樣本的類別,這樣在決策中容錯率相對於 NN 演算法就要高很多,分類效果也會更好。
對於未知測試樣本(圖中 ?所示)採用 KNN 演算法進行分類,首先計算未知樣本和訓練樣本之間的相似度,找出最近 K 個相鄰樣本(在圖中 K 值為 3,圈定距離 ?最近的 3 個樣本),再根據最近的 K 個樣本最終判斷未知樣本的類別
二、常用距離演算法
距離度量
兩個樣本的相似度 通過 樣本之間特徵值的距離進行表示。
若兩個樣本距離越大 ↑ ,兩個相似度 ↓
最常用的距離公式:曼哈頓距離 和 歐式距離
(1)曼哈頓距離
曼哈頓距離又稱馬氏距離,計程車距離,是計算距離最簡單的方式之一。
"""曼哈頓距離計算
"""
import numpy as np
def d_man(x, y):
d = np.sum(np.abs(x - y))
return d
x = np.array([3.1, 3.2])
print("x:" , x)
y = np.array([2.5, 2.8])
print("y:", y)
d_man = d_man(x, y)
print(d_man)
(2)歐式距離
歐式距離源自 維歐氏空間中兩點之間的距離公式。表示式如下:
其中:
- , :兩個資料點
- :每個資料中有 個特徵值
- :資料 的第 個特徵值
公式表示為將兩個資料 和 中的每一個對應特徵值之間差值的平方,再求和,最後開平方,便是歐式距離。
"""歐氏距離的計算
"""
import numpy as np
def d_euc(x, y):
d = np.sqrt(np.sum(np.square(x - y)))
return d
x = np.random.random(10) # 隨機生成10個數的陣列作為x特徵的值
print("x:", x)
y = np.random.random(10)
print("y:", y)
distance_euc = d_euc(x, y)
print(distance_euc)
三、決策規則
上面我們通過 K-NN
得到了 K 個相鄰的樣本,那如何通過這 K 個鄰居來判斷 未知樣本的最終類別?
可以根據資料特徵對決策規則進行選取。
- 多數表決法:多數表決法類似於投票的過程,也就是在 K 個鄰居中選擇類別最多的種類作為測試樣本的類別。
- 加權表決法:根據距離的遠近,對近鄰的投票進行加權,距離越近則權重越大,通過權重計算結果最大值的類為測試樣本的類別。
"""多數表決法
"""
import operator
def majority_voting(class_count):
sorted_class_count = sorted(
class_count.items(), key=operator.itemgetter(1), reverse=True)
return sorted_class_count
arr = {'A': 3, 'B': 2, "C": 6, "D": 5}
majority_voting(arr)
四、Kd樹
為了提高 KNN 搜尋效率,減少計算距離的次數,可以通過構建 Kd 樹的方法提高計算效率
什麼是Kd樹 ?
Kd 樹(英文:K-dimension tree)是一種對 K 維空間中的例項點進行儲存以便對其進行快速檢索的樹形資料結構。
Kd 樹是一種二叉樹
對 K 維空間的一個劃分,構造 Kd 樹相當於不斷地用垂直於座標軸的超平面將 K 維空間切分,構成一系列的 K 維超矩形區域。
Kd 樹的每個結點對應於一個 K 維超矩形區域。
利用Kd 樹可以省去對大部分資料點的搜尋,從而減少搜尋的計算量。
以下便是 Kd 樹的最鄰近搜尋步驟:
- 從根節點開始,遞迴的往下移。往左還是往右的決定方法與插入元素的方法一樣(如果輸入點在分割槽面的左邊則進入左子節點,在右邊則進入右子節點)。
- 一旦移動到葉節點,將該節點當作”目前最佳點”。
- 解開遞迴,並對每個經過的節點執行下列步驟:
- 如果目前所在點比目前最佳點更靠近輸入點,則將其變為目前最佳點。
- 檢查另一邊子樹有沒有更近的點,如果有則從該節點往下找
- 當根節點搜尋完畢後完成最鄰近搜尋
那如何 構建 Kd樹?
按 訓練集中的資料進行切分?