knn算法

什麼是knn

​ kNN(k-NearestNeighbor),也就是k最近鄰算法。顧名思義,所謂K最近鄰,就是k個最近的鄰居的意思。也就是在數據集中,認爲每個樣本可以用離他最距離近的k個鄰居來代表。

​ 它是一種常用的監督學習方法,在分類任務中可以採用“投票法”,在迴歸任務中可以採用“平均法”,以及基於距離遠近進行加權平均或加權投票,距離越近的樣本權重越大。

​ 簡單來說就是“近朱者赤近墨者黑”思想的直觀體現。

​ 注:這裏的距離可能是歐式距離或曼哈頓距離

kNN算法流程

通過理解算法思想,可以將其簡化爲“找鄰居+投票”。K近鄰法使用的模型,實際上是特徵空間的劃分。模型由三個基本要素決定:

  • 距離度量
  • k值
  • 分類決策規則

其中兩個實例點之間的距離反映了相似程度。一般來說使用歐氏距離來計算。

梳理kNN算法流程如下:

  1. 計算測試對象到訓練集中每個對象的距離

  2. 按照距離的遠近排序

  3. 選取與當前測試對象最近的k的訓練對象,作爲該測試對象的鄰居

  4. 統計這k個鄰居的類別頻次

  5. k個鄰居里頻次最高的類別,即爲測試對象的類別

簡單來說,如下圖,當k=3,那麼數據樣本應該是屬於classB,當k=6時,那麼數據樣本應該是屬於classA,當然,如果k=1的話,那麼就能確定唯一隻,但是這樣的話很容易變成異常值干擾,所以,只要距離類別選擇合適,數據樣本越大,準確度應該是增高的

在這裏插入圖片描述

KNN算法在python的中實現

python中關於knn的算法實在sklearn包下的neighbors下的KNeighborsClassifier,具體的使用案例如下:

import numpy as np
from sklearn.neighbors import KNeighborsClassifier
# 創建kNN_classifier實例
kNN_classifier = KNeighborsClassifier(n_neighbors=6)

# raw_data_x是特徵(x,y 座標),raw_data_y是標籤,0爲良性,1爲惡性
raw_data_x = [[3.393533211, 2.331273381], [3.110073483, 1.781539638], [1.343853454, 3.368312451],
              [3.582294121, 4.679917921], [2.280362211, 2.866990212], [7.423436752, 4.685324231],
              [5.745231231, 3.532131321], [9.172112222, 2.511113104], [7.927841231, 3.421455345],
              [7.939831414, 0.791631213]]

raw_data_y = [0, 0, 0, 0, 0, 1, 1, 1, 1,1]
# 設置訓練組
X_train = np.array(raw_data_x)
y_train = np.array(raw_data_y)

# kNN_classifier做一遍fit(擬合)的過程,沒有返回值,模型就存儲在kNN_classifier實例中
fit = kNN_classifier.fit(X_train, y_train)
# KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
#                      metric_params=None, n_jobs=None, n_neighbors=6, p=2,
#                      weights='uniform')
print(fit)
x = [8.90933607318, 3.365731514]

# kNN進行預測predict,需要傳入一個矩陣,而不能是一個數組。reshape()成一個二維數組,
#   第一個參數是1表示只有一個數據,第二個參數-1,numpy自動決定第二維度有多少
y_predict = kNN_classifier.predict(x.reshape(1,-1))
print(y_predict)

關於KNeighborsClassifier的構造方法

對於KNeighborsClassifier的方法:

# weights(權重): str or callable(自定義類型), 可選參數(默認爲 ‘uniform’)。用於預測的權重參數,可選參數如下:
# 
# uniform : 統一的權重. 在每一個鄰居區域裏的點的權重都是一樣的。
# distance : 權重點等於他們距離的倒數。使用此函數,更近的鄰居對於所預測的點的影響更大。
# [callable] : 一個用戶自定義的方法,此方法接收一個距離的數組,然後返回一個相同形狀並且包含權重的數組。
# algorithm(算法): {‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’}, 可選參數(默認爲 'auto')。計算最近鄰居用的算法:
# 
# ball_tree 使用算法BallTree
# kd_tree 使用算法KDTree
# brute 使用暴力搜索
# auto 會基於傳入fit方法的內容,選擇最合適的算法。注意 : 如果傳入fit方法的輸入是稀疏的,將會重載參數設置,直接使用暴力搜索。
# leaf_size(葉子數量): int, 可選參數(默認爲 30)。傳入BallTree或者KDTree算法的葉子數量。此參數會影響構建、查詢BallTree或者KDTree的速度,以及存儲BallTree或者KDTree所需要的內存大小。此可選參數根據是否是問題所需選擇性使用。
# 
# p: integer, 可選參數(默認爲 2)。用於Minkowski metric(閔可夫斯基空間)的超參數。p = 1, 相當於使用曼哈頓距離,p = 2, 相當於使用歐幾里得距離],對於任何 p ,使用的是閔可夫斯基空間。
# 
# metric(矩陣): string or callable, 默認爲 ‘minkowski’。用於樹的距離矩陣。默認爲閔可夫斯基空間,如果和p=2一塊使用相當於使用標準歐幾里得矩陣. 所有可用的矩陣列表請查詢 DistanceMetric 的文檔。
# 
# metric_params(矩陣參數): dict, 可選參數(默認爲 None)。給矩陣方法使用的其他的關鍵詞參數。
# 
# n_jobs: int, 可選參數(默認爲 1)。用於搜索鄰居的,可並行運行的任務數量。如果爲-1, 任務數量設置爲CPU核的數量。不會影響fit
def __init__(self, n_neighbors=5,
             weights='uniform', algorithm='auto', leaf_size=30,
             p=2, metric='minkowski', metric_params=None, n_jobs=None,
             **kwargs):
  super().__init__(
    n_neighbors=n_neighbors,
    algorithm=algorithm,
    leaf_size=leaf_size, metric=metric, p=p,
    metric_params=metric_params,
    n_jobs=n_jobs, **kwargs)
  self.weights = _check_weights(weights)

  n_neighbors: int, 可選參數(默認爲 5)。用於kneighbors查詢的默認鄰居的數量

方法 含義
fit(X, y) 使用X作爲訓練數據,y作爲目標值(類似於標籤)來擬合模型。
get_params([deep]) 獲取估值器的參數。
neighbors([X, n_neighbors, return_distance]) 查找一個或幾個點的K個鄰居。
kneighbors_graph([X, n_neighbors, mode]) 計算在X數組中每個點的k鄰居的(權重)圖。
predict(X) 給提供的數據預測對應的標籤。
predict_proba(X) 返回測試數據X的概率估值。
score(X, y[, sample_weight]) 返回給定測試數據和標籤的平均準確值。
set_params(**params) 設置估值器的參數。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章