sklearn 學習 第三篇:knn分類


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個樣本的分類情況;
  • 把出現次數最多的類別作為待分類數據的類別。

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都會運行。

三,觀察數據

由於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)

使用函數把已標記的數據拆分成訓練集和測試集:

sklearn.model_selection.train_test_split(*arrays, test_size ,train_size ,random_state ,shuffle ,stratify )

test_size:拆分的測試集數據所占的百分比,如果test_size和train_size都是none,那么默認值是test_size=0.25
train_size:拆分的訓練集數據所占的百分比,
random_state:如果是int,那么參數用於指定隨機數產生的種子;如果是None,使用np.random作為隨機數產生器
shuffle:布爾值,默認值是True,表示在拆分之前對數據進行洗牌;如果shuffle = False,則分層必須為None。
stratify:如果不是None,則數據以分層方式拆分,使用此作為類標簽。

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]))

五,模型評估

knn分類有2個重要的參數:鄰居個數和數據點之間距離的度量方法。在實踐中,使用較小的奇數個鄰居,比如,3和5,往往可以得到比較好的結果,但是,這是經驗之談,你應該根據數據來調節這個參數。

1,模型的正確率

在使用模型之前,應該使用測試集來評估模型,所謂模型的正確率,就是使用已標記的數據,根據數據預測的結果和標記的結果進行比對,計算比對成功的占比:

assess_model_socre=knn.score(x_test,y_test)
print('Test set score:{:2f}'.format(assess_model_socre))

使用模型的score()函數,使用測試集進行評分,分數越高,模型越好。

2,鄰居個數

如何確定鄰居的個數,下面使用枚舉法,逐個測試鄰居的個數,並根據模型的score()函數查看模型的正確率。

import mglearn
import matplotlib.pyplot as plt from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier cancer=load_breast_cancer() x_train,x_test,y_train,y_test=train_test_split(cancer.data,cancer.target,random_state=66) training_accuracy=[] test_accuracy=[] neighbors_settings=range(1,11) for n_neighbors in neighbors_settings: knn=KNeighborsClassifier(n_neighbors) knn.fit(x_train,y_train) training_accuracy.append(knn.score(x_train,y_train)) test_accuracy.append(knn.score(x_test,y_test)) plt.plot(neighbors_settings,training_accuracy,label='Training Accuracy') plt.plot(neighbors_settings,test_accuracy,label='Test Accuracy') plt.ylabel('Accuracy') plt.xlabel('n_neighbors') plt.legend()

3,距離選擇

 數據點之間的距離,計算距離的方法有:"euclidean"(歐氏距離),”minkowski”(明科夫斯基距離), "maximum"(切比雪夫距離), "manhattan"(絕對值距離),"canberra"(蘭式距離), 或 "minkowski"(馬氏距離)等。

4,預測的不確定度估計

查看分類的不確定度估計,使用模型的predict_prob()函數來查看模型預測的概率。

 

 

參考文檔:

sklearn.neighbors.KNeighborsClassifier

sklearn的基本使用

Python之Sklearn使用教程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM