0x00 概述
K近鄰演算法是機器學習中非常重要的分類演算法。可利用K近鄰基於不同的特徵提取方式來檢測異常操作,比如使用K近鄰檢測Rootkit,使用K近鄰檢測webshell等。
0x01 原理
距離接近的事物具有相同屬性的可能性要大於距離相對較遠的。 這是K鄰近的核心思想。
- K鄰近 K-Nearest Neighbor,KNN 演算法,KNN指K個最近的鄰居,可認為每個樣本都能用與它最相近的K個鄰居來代表。
演算法核心思想
一個樣本在特徵空間中的K個最相鄰的樣本中的大多數屬於某一個類別,則該樣本也屬於這個類別,並且具有這個類別裡樣本的特性。
使用場合
類域交叉或重疊較多的待分樣本集
KNN演算法中細分3個小演算法
- Brute Force
- K-D Tree
- Ball Tree
0x02 程式碼詳解
0x02.1 Ball Tree 演示
-
設定初始資料集 這裡自己定義了一個小的資料集
>>> X = np.array([[-1,-1],[-2,-1],[-3,-2],[1,1],[2,1],[3,2]])
-
呼叫Scikit-Learn的KNN演算法,設定鄰居數為2,進行訓練
>>> from sklearn.neighbors import NearestNeighbors # 從呼叫sklearn庫中的neighbors模組呼叫KNN
>>> import numpy as np # 呼叫numpy庫
>>> X = np.array([[-1,-1],[-2,-1],[-3,-2],[1,1],[2,1],[3,2]]) # 設定訓練的資料集
>>> nbrs=NearestNeighbors(n_neighbors=2,algorithm='ball_tree').fit(X) # 設定鄰居數,設定訓練的演算法。
>>> distances,indices=nbrs.kneighbors(X) # 開始訓練,返回結果
>>> print(indices)
>>> print(distances)
有些不理解,查詢官方文件
URL-》https://scikit-learn.org/dev/modules/generated/sklearn.neighbors.NearestNeighbors.html?highlight=#sklearn.neighbors.NearestNeighbors
注意是先返回了距離,然後返回了下標,一開始有點懵,為什麼自己在和自己比??而不是哪資料集和某個點比
後面仔細看看就明白了
- 執行結果
直接看不好看懂,但是實際上根據鄰居數和官方文件可以這麼理解。
鄰居數就是一個點周圍離它最近的點。
針對一個點 [-1,-1] 與它對應的下標 [0 1] 表示 第1個樣本 和第2個樣本 距離 對應 [0,1] 表示第一個點與第一個點之間的距離,第一個點與第二個點之間的距離。
其餘點都是這種規律。
- 加入一行程式碼,直接抽象表示每個點的2個鄰居
>>> nbrs.kneighbors_graph(X).toarray()
可以看到用1去模擬實現了不同點的鄰居。
0x02.2 KNN下的監督學習
from sklearn.neighbors import KNeighborsClassifier
x=[[0],[1],[2],[3]]
y=[0,0,1,1]
neigh=KNeighborsClassifier(n_neighbors=3)
neigh.fit(x,y)
print(neigh.predict([[1.1]]))
print(neigh.predict_proba([[0.9]]))
程式碼審計 - 從sklear的分類演算法裡選擇KNeighborsClassifier
然後設定鄰居數 通過.fit函式 對資料集進行擬合
neigh.predict 去預測 [1.1] 會被分成什麼類
-
正常執行結果
-
修改了資料進行標籤預測後
可以看出總共只有2個標籤 一個是0 一個是1 然後根據你輸入的資料進行分類,通過neigh.predict_proba 輸出被分在不同標籤中的概率。