機器學習演算法之K近鄰演算法

Dark1nt發表於2021-06-06

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 輸出被分在不同標籤中的概率。

相關文章