K臨近分類是一種監督式的分類方法,首先根據已標記的資料對模型進行訓練,然後根據模型對新的資料點進行預測,預測新資料點的標籤(label),也就是該資料所屬的分類。
一,kNN演算法的邏輯
kNN演算法的核心思想是:如果一個資料在特徵空間中最相鄰的k個資料中的大多數屬於某一個類別,則該樣本也屬於這個類別(類似投票),並具有這個類別上樣本的特性。通俗地說,對於給定的測試樣本和基於某種度量距離的方式,通過最靠近的k個訓練樣本來預測當前樣本的分類結果。
例如,借用百度的一張圖來說明kNN演算法過程,要預測圖中Xu的分類結果,先預設一個距離值,只考慮以Xu為圓心以這個距離值為半徑的圓內的已知訓練樣本,然後根據這些樣本的投票結果來預測Xu屬於w1類別,投票結果是4:1。
kNN演算法在確定分類決策上只依據最鄰近的一個或者幾個樣本的類別來決定待分樣本所屬的類別。kNN演算法在類別決策時,只與極少量的相鄰樣本有關。由於kNN演算法主要靠周圍有限的鄰近的樣本,而不是靠判別類域的方法來確定所屬類別的,因此對於類域的交叉或重疊較多的待分樣本集來說,kNN方法較其他方法更為適合。
1,kNN演算法的計算步驟
kNN演算法就是根據距離待分類樣本A最近的k個樣本資料的分類來預測A可能屬於的類別,基本的計算步驟如下:
- 對資料進行標準化,通常是進行歸一化,避免量綱對計算距離的影響;
- 計算待分類資料與訓練集中每一個樣本之間的距離;
- 找出與待分類樣本距離最近的k個樣本;
- 觀測這k個樣本的分類情況;
- 把出現次數最多的類別作為待分類資料的類別。
計算距離的方法有:"euclidean"(歐氏距離),”minkowski”(明科夫斯基距離), "maximum"(切比雪夫距離), "manhattan"(絕對值距離),"canberra"(蘭式距離), 或 "minkowski"(馬氏距離)等。
2,kNN演算法如何計算距離?
在計算距離之前,需要對每個數值屬性進行規範化,這有助於避免較大初始值域的屬性比具有較小初始值域的屬性的權重過大。
- 對於數值屬性,kNN演算法使用距離公式來計算任意兩個樣本資料之間的距離。
- 對於標稱屬性(如類別),kNN演算法使用比較法,當兩個樣本資料相等時,距離為0;當兩個樣本資料不等時,距離是1。
- 對於缺失值,通常取最大的差值,假設每個屬性都已經對映到[0,1]區間,對於標稱屬性,設定差值為1;對於數值屬性,如果兩個元組都缺失值,那麼設定差值為1;如果只有一個值缺失,另一個規範化的值是v,則取差值為 1-v 和 v 的較大者。
3,kNN演算法如何確定k的值?
k的最優值,需要通過實驗來確定。從k=1開始,使用檢驗資料集來估計分類器的錯誤率。重複該過程,每次k增加1,允許增加一個近鄰,選取產生最小錯誤率的k。一般而言,訓練資料集越多,k的值越大,使得分類預測可以基於訓練資料集的較大比例。在應用中,一般選擇較小k並且k是奇數。通常採用交叉驗證的方法來選取合適的k值。
二,KNeighborsClassifier函式
使用KNeighborsClassifier建立K臨近分類器:
sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, weights=’uniform’, algorithm=’auto’, leaf_size=30,
p=2, metric=’minkowski’, metric_params=None, n_jobs=None, **kwargs)
引數註釋:
1,n_neighbors
臨近的節點數量,預設值是5
2,weights
權重,預設值是uniform,
- uniform:表示每個資料點的權重是相同的;
- distance:離一個簇中心越近的點,權重越高;
- callable:使用者定義的函式,用於表示每個資料點的權重
3,algorithm
- auto:根據值選擇最合適的演算法
- ball_tree:使用BallTree
- kd_tree:KDTree
- brute:使用Brute-Force查詢
4,leaf_size
leaf_size傳遞給BallTree或者KDTree,表示構造樹的大小,用於影響模型構建的速度和樹需要的記憶體數量,最佳值是根據資料來確定的,預設值是30。
5,p,metric,metric_paras
- p引數用於設定Minkowski 距離的Power引數,當p=1時,等價於manhattan距離;當p=2等價於euclidean距離,當p>2時,就是Minkowski 距離。
- metric引數:設定計算距離的方法
- metric_paras:傳遞給計算距離方法的引數
6,n_jobs
併發執行的job數量,用於查詢鄰近的資料點。預設值1,選取-1佔據CPU比重會減小,但執行速度也會變慢,所有的core都會執行。
7,舉個例子
下面的程式碼是最簡單的knn分類器,可以看出,knn分類模型是由兩部分構成的:第一部分是擬合資料(fit),也就是訓練模型,第二部分是預測資料(predict)。
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=3)
x_train = [[0], [1], [2], [3]]
y_train = [0, 0, 1, 1]
knn.fit(x_train,y_train)
x_new=[[1.1]]
pred=knn.predict(x_new)
print('pred:{0}'.format(pred))
三,觀察資料
由於knn分類是監督式的分類方法之前,在構建一個複雜的分類模型之前,首先需要已標記的資料集。我們可以從sklearn的資料集中載入已有的資料進行學習:
from sklearn.datasets import load_iris iris_dataset=load_iris()
檢視iris_dataset的資料,該物件的結構和字典非常型別:
>>> iris_dataset.keys() dict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names', 'filename'])
1,樣本資料
data 是樣本資料,共4列150行,列名是由feature_names來確定的,每一列都叫做矩陣的一個特徵(屬性),前4行的資料是:
>>> iris_dataset.data[0:4] array([[5.1, 3.5, 1.4, 0.2], [4.9, 3. , 1.4, 0.2], [4.7, 3.2, 1.3, 0.2], [4.6, 3.1, 1.5, 0.2]])
2,標籤
target是標籤,用數字表示,target_names是標籤的文字表示
>>> iris_dataset.target[0:4] array([0, 0, 0, 0]) >>> iris_dataset.target_names array(['setosa', 'versicolor', 'virginica'], dtype='<U10')
3,檢視資料的散點圖
檢視資料的散點圖矩陣,按照資料的類別進行著色,觀察資料的分佈:
import pandas as pd import mglearn iris_df=pd.DataFrame(x_train,columns=iris_dataset.feature_names) pd.plotting.scatter_matrix(iris_df,c=y_train,figsize=(15,15),marker='o',hist_kwds={'bins':20} ,s=60,alpha=.8,cmap=mglearn.cm3)
四,建立模型
我們使用sklearn資料集中的鳶尾花測量資料來構建一個複雜的分類模型,並根據輸入的資料點來預測鳶尾花的類別。
1,拆分資料
把鳶尾花資料拆分為訓練集和測試集:
from sklearn.model_selection import train_test_split x_train,x_test,y_train,y_test=train_test_split(iris_dataset['data'],iris_dataset['target'],random_state=0)
2,建立分類器
使用KNeighborsClassifier建立分類器,設定引數n_neighbors為1:
from sklearn.neighbors import KNeighborsClassifier knn = KNeighborsClassifier(n_neighbors=1)
3,使用訓練集來構建模型
對於監督學習,訓練資料集包括兩部分:輸入和結果(Lable),每一行輸入都對應一行結果,結果是輸入的正確分類(標籤)。
通常,記X_train是訓練的輸入資料集,X_train對應的結果是y_train,是訓練資料集的輸出,通過fit()函式來訓練模型,構建模型:
knn.fit(x_train, y_train)
4,預測新資料
對於訓練之後的模型,使用predict()函式來預測資料的結果。
x_new=np.array([[5, 2.9, 1, 0.2]]) prediction= knn.predict(x_new) print("prediction :{0} ,classifier:{1}".format(prediction,iris_dataset["target_names"][prediction]))
5,評估模型
在使用模型之前,應該使用測試集來評估模型:
y_pred=knn.predict(x_test) assess_model_socre=knn.score(x_test,y_test) print('Test set score:{:2f}'.format(assess_model_socre))
參考文件: