k近鄰法(k-nearest neighbor, kNN)
是一種基本分類與回歸方法,其基本做法是:給定測試實例,基於某種距離度量找出訓練集中與其最靠近的k個實例點,然后基於這k個最近鄰的信息來進行預測。
通常,在分類任務中可使用“投票法”,即選擇這k個實例中出現最多的標記類別作為預測結果;在回歸任務中可使用“平均法”,即將這k個實例的實值輸出標記的平均值作為預測結果;還可基於距離遠近進行加權平均或加權投票,距離越近的實例權重越大。
k近鄰法用於分類的函數:https://scikit-learn.org/stable/modules/classes.html#module-sklearn.neighbors
class sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, *, weights='uniform', algorithm='auto', leaf_size=30, p=2, metric='minkowski', metric_params=None, n_jobs=None, **kwargs)
參數:
- n_neighbors:尋找的鄰居數,默認是5。也就是K值
- weights:預測中使用的權重函數。可能的取值:‘uniform’:統一權重,即每個鄰域中的所有點均被加權。‘distance’:權重點與其距離的倒數,在這種情況下,查詢點的近鄰比遠處的近鄰具有更大的影響力。[callable]:用戶定義的函數,該函數接受距離數組,並返回包含權重的相同形狀的數組。
- algorithm:用於計算最近鄰居的算法:“ ball_tree”將使用BallTree,“ kd_tree”將使用KDTree,“brute”將使用暴力搜索。“auto”將嘗試根據傳遞給fit方法的值來決定最合適的算法。注意:在稀疏輸入上進行擬合將使用蠻力覆蓋此參數的設置。
- leaf_size:葉大小傳遞給BallTree或KDTree。這會影響構造和查詢的速度,以及存儲樹所需的內存。最佳值取決於問題的性質。默認30。
- p:Minkowski距離的指標的功率參數。當p = 1時,等效於使用manhattan_distance(l1)和p=2時使用euclidean_distance(l2)。對於任意p,使用minkowski_distance(l_p)。默認是2。
- metric:樹使用的距離度量。默認度量標准為minkowski,p = 2等於標准歐幾里德度量標准。
- metric_params:度量函數的其他關鍵字參數。
- n_jobs:並行計算數
屬性:
- classes_:類別
- effective_metric_:使用的距離度量。它將與度量參數相同或與其相同,例如如果metric參數設置為“ minkowski”,而p參數設置為2,則為“ euclidean”。
- effective_metric_params_:度量功能的其他關鍵字參數。對於大多數指標而言,它與metric_params參數相同,但是,如果將valid_metric_屬性設置為“ minkowski”,則也可能包含p參數值。
- outputs_2d_:在擬合的時候,當y的形狀為(n_samples,)或(n_samples,1)時為False,否則為True。
方法:
- fit(X, y):使用X作為訓練數據和y作為目標值擬合模型
- get_params([deep]): 獲取此估計量的參數。
- kneighbors([X, n_neighbors, return_distance]) :查找點的K鄰居。查找點的K鄰居。返回每個點的鄰居的索引和與之的距離
- kneighbors_graph([X, n_neighbors, mode]):計算X中點的k鄰居的(加權)圖
- predict(X):預測提供的數據的類標簽。
- predict_proba(X):測試數據X的返回概率估計。
- score(X, y[, sample_weight]):返回給定測試數據和標簽上的平均准確度
- set_params(**params):設置此估算器的參數
方法中kneighbors例子:https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html
#kneighbors(X = None,n_neighbors = None,return_distance = True ) samples = [[0., 0., 0.], [0., .5, 0.], [1., 1., .5]] from sklearn.neighbors import NearestNeighbors neigh = NearestNeighbors(n_neighbors=1) neigh.fit(samples) #NearestNeighbors(n_neighbors=1) print(neigh.kneighbors([[1., 1., 1.]])) #(array([[0.5]]), array([[2]])) #如您所見,它返回[[0.5]]和[[2]],這意味着該元素位於距離0.5處,並且是樣本的第三個元素(索引從0開始)
值得注意的是:KNN容易過擬合,因為在高維空間上,隨着維數越來越大,特征空間越來越稀疏,大家可以想象在一個球體里面,大部分的信息集中在球面,那KNN需要找最近的點就會十分困難,那么也就無法合適進行估計
鳶尾花例子:
import numpy as np import matplotlib.pyplot as plt # 導入KNN分類器 from sklearn.neighbors import KNeighborsClassifier from sklearn import datasets from sklearn.model_selection import train_test_split # 載入鳶尾花數據集 # iris是一個對象類型的數據,其中包括了data(鳶尾花的特征)和target(也就是分類標簽) iris = datasets.load_iris() # 將樣本與標簽分開 x = iris['data'] y = iris['target'] print(x.shape, y.shape) # (150, 4) (150,) # 划分數據集 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2) # 8:2 print(x_train.shape, x_test.shape, y_train.shape, y_test.shape) # (120, 4) (30, 4) (120,) (30,) #使用KNeighborsClassifier來訓練模型,這里我們設置參數k(n_neighbors)=5, 使用歐式距離(metric=minkowski & p=2): clf = KNeighborsClassifier(n_neighbors=5, p=2, metric="minkowski") clf.fit(x_train, y_train) # fit可以簡單的認為是表格存儲 # KNeighborsClassifier() y_predict = clf.predict(x_test) y_predict.shape # (30,) acc = sum(y_predict == y_test) / y_test.shape[0] acc #0.933
K近鄰用於回歸
class sklearn.neighbors.KNeighborsRegressor(n_neighbors=5, *, weights='uniform', algorithm='auto', leaf_size=30, p=2, metric='minkowski', metric_params=None, n_jobs=None, **kwargs)
可以看出參數和用於分類基本一致 ,這里就不贅述了
注意:建模時可以多搜索超參數k值和algorithm =[' auto ', ' ball_tree ', ' kd_tree ', ' brute ']