【python+機器學習1】python 實現 KNN

歡迎關注哈希大數據微信公眾號【哈希大數據】

1 KNN算法基本介紹
K-Nearest Neighbor(k最鄰近分類算法),簡稱KNN,是最簡單的一種有監督的機器學習算法。也是一種懶惰學習算法,即開始訓練僅僅是保存所有樣本集的信息,直到測試樣本到達才開始進行分類決策。

KNN算法的核心思想:要想確定測試樣本屬于哪一類,就先尋找所有訓練樣本中與該測試樣本“距離”最近的前K個樣本,然后判斷這K個樣本中大部分所屬的類型,就認為是該測試樣本的類型。也就是所謂的“近朱者赤近墨者黑”,根據與其最近的k個樣本的類型決定其自身的類型。因此K的確定和測算距離的方式是影響樣本最終分類準確率的重要因素。

常用的測算距離的方法是多維空間的歐式距離法。

其優點為:易于理解,實現簡單,無需估計參數,無需訓練。

缺點為:需要保存所有的訓練數據,內存開銷大,而且訓練數據較多時會導致很高的算法復雜度,訓練數據類型不均勻可能會導致預測準確率下降。

2 標準數據集介紹
我們將采用scikit-learn庫中自帶的鳶尾花數據集進行測試。可以在D:\anaconda python\pkgs\scikit-learn-0.19.0-np113py36_0\Lib\site-packages\sklearn\datasets\data路徑下查看元數據,部分數據實例如下圖(共計150條數據)。

image

鳶尾花數據集包括鳶尾花的測量數據(特征屬性)以及其所屬的類別。

測量數據特征包括: 萼片長度、萼片寬度、花瓣長度、花瓣寬度

所屬類別有三類: Iris Setosa,Iris Versicolour,Iris Virginica ,用數字0,1,2表示。

#通過python加載鳶尾花數據集

from sklearn import datasetsiris = datasets.load_iris()

# 獲取鳶尾花屬性數據并查看數據特征

iris_X = iris.dataprint(iris.data.shape)

# 獲取鳶尾花類別數據

iris_y = iris.target

拆分****數據集****為訓練數據和測試數據:

# 方法一:使用python的train_test_split庫進行數據集拆分

iris_train_X , iris_test_X, iris_train_y ,iris_test_y = train_test_split(iris_X, iris_y, test_size=0.2,random_state=0)

# 方法二:隨機選擇部分數據(20%)作為測試集(適用于少量數據)

np.random.seed(0)
select = np.random.permutation(len(iris_y))
iris_X_train = iris_X[select[:-30]]
iris_y_train = iris_y[indices[:-30]]
iris_X_test = iris_X[indices[-30:]]
iris_y_test = iris_y[indices[-30:]]

3 KNN算法python實現

在此我們將直接使用python的scikit-learn 庫中的 neighbors.KNeighborsClassifier類,通過KNN算法對測試集中鳶尾花進行分類。

首先進行類的初始化

knn =KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski', metric_params=None, n_jobs=1, n_neighbors=5, p=2, weights='uniform')

參數介紹

l n_neighbors=5,就是KNN中的k,默認為5。

l weights='uniform',是距離計算中使用的權重,默認為'uniform' 是等權加權,也可以選'distance'是按照距離的倒數進行加權,也可以自己設置其他加權方式。(給距離增加權重,如果越近的距離權重越高,能在一定程度上避免樣本分布不平均的問題)

l metric='minkowski'、p=2,表示采用的是歐氏距離的計算。

計算距離的方式默認為閔可夫斯基距離,是一組距離的定義。

兩個n維變量a(x11,x12,…,x1n)與 b(x21,x22,…,x2n)間的閔可夫斯基距離:

image

其中p=1時,為曼哈頓距離;p=2時,為歐氏距離;p→∞時,為切比雪夫距離。根據變參數p的不同,閔氏距離可以表示一類的距離。

l algorithm='auto',是分類時采取的算法,有'brute'、'kd_tree'和'ball_tree',三種默認按照數據特征從這三種中選擇最合適的。其中kd-tree基于歐氏距離的特性可以快速處理20維以內的數據集,balltree基于更一般的距離特性,適合處理高維數據。(三種算法的具體實現之后會進行詳細介紹)

l leaf_size=30,是kd_tree或ball_tree生成的樹的樹葉(二叉樹中未分枝的節點)的大小。

l n_job=1,是并行計算的線程數量,默認是1,輸入-1則設為CPU的內核數。

# ****提供數據集進行訓練

knn.fit(iris_X_train, iris_y_train)

# ****預測測試集數據鳶尾花類型

predict_result = knn.predict(iris_X_test)print(predict_result)

# ****計算預測的準確率

print(knn.score(iris_X_test, iris_y_test))

4 完整源碼及輸出結果

!/usr/bin/python
-- coding: utf-8 --
KNN調用
import numpy as np
from sklearn import datasets
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn import datasets

導入鳶尾花數據并查看數據特征
iris = datasets.load_iris()
print('數據量',iris.data.shape)

拆分屬性數據
iris_X = iris.data

拆分類別數據
iris_y = iris.target

方法一:拆分測試集和訓練集,并進行預測
iris_train_X , iris_test_X, iris_train_y ,iris_test_y = train_test_split(iris_X, iris_y, test_size=0.2,random_state=0)
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(iris_train_X, iris_train_y)
knn.predict(iris_test_X)

方法二:拆分測試集和訓練集
np.random.seed(0)
permutation隨機生成0-150的系列
indices = np.random.permutation(len(iris_y))
iris_X_train = iris_X[indices[:-30]]
iris_y_train = iris_y[indices[:-30]]
iris_X_test = iris_X[indices[-30:]]
iris_y_test = iris_y[indices[-30:]]
knn = KNeighborsClassifier()

提供訓練集進行順利
knn.fit(iris_X_train, iris_y_train)

預測測試集鳶尾花類型
predict_result = knn.predict(iris_X_test)
print('預測結果',predict_result)

計算預測的準確率
print('預測準確率',knn.score(iris_X_test, iris_y_test))

輸出結果
"D:\anaconda python\python3.6.exe" D:/machine_learning/coding/knntest.py
數據量 (150, 4)
預測結果 [0 2 0 0 2 0 2 1 1 1 2 2 2 1 0 1 2 2 0 1 1 2 1 0 0 0 2 1 2 0]
預測準確率 0.933333333333
Process finished with exit code 0

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容