歡迎關(guān)注哈希大數(shù)據(jù)微信公眾號【哈希大數(shù)據(jù)】
1 KNN算法基本介紹
K-Nearest Neighbor(k最鄰近分類算法)咆蒿,簡稱KNN,是最簡單的一種有監(jiān)督的機器學(xué)習(xí)算法缭黔。也是一種懶惰學(xué)習(xí)算法蒂破,即開始訓(xùn)練僅僅是保存所有樣本集的信息,直到測試樣本到達才開始進行分類決策惧互。
KNN算法的核心思想:要想確定測試樣本屬于哪一類喇伯,就先尋找所有訓(xùn)練樣本中與該測試樣本“距離”最近的前K個樣本,然后判斷這K個樣本中大部分所屬的類型艾猜,就認為是該測試樣本的類型攀甚。也就是所謂的“近朱者赤近墨者黑”秋度,根據(jù)與其最近的k個樣本的類型決定其自身的類型钱床。因此K的確定和測算距離的方式是影響樣本最終分類準確率的重要因素。
常用的測算距離的方法是多維空間的歐式距離法事期。
其優(yōu)點為:易于理解纸颜,實現(xiàn)簡單,無需估計參數(shù)唠倦,無需訓(xùn)練涮较。
缺點為:需要保存所有的訓(xùn)練數(shù)據(jù),內(nèi)存開銷大候齿,而且訓(xùn)練數(shù)據(jù)較多時會導(dǎo)致很高的算法復(fù)雜度,訓(xùn)練數(shù)據(jù)類型不均勻可能會導(dǎo)致預(yù)測準確率下降周霉。
2 標準數(shù)據(jù)集介紹
我們將采用scikit-learn庫中自帶的鳶尾花數(shù)據(jù)集進行測試润匙≡谢洌可以在D:\anaconda python\pkgs\scikit-learn-0.19.0-np113py36_0\Lib\site-packages\sklearn\datasets\data路徑下查看元數(shù)據(jù),部分數(shù)據(jù)實例如下圖(共計150條數(shù)據(jù))厂财。
鳶尾花數(shù)據(jù)集包括鳶尾花的測量數(shù)據(jù)(特征屬性)以及其所屬的類別璃饱。
測量數(shù)據(jù)特征包括: 萼片長度荚恶、萼片寬度、花瓣長度谒撼、花瓣寬度
所屬類別有三類: Iris Setosa廓潜,Iris Versicolour,Iris Virginica 呻畸,用數(shù)字0,1,2表示悼院。
#通過python加載鳶尾花數(shù)據(jù)集
from sklearn import datasetsiris = datasets.load_iris()
# 獲取鳶尾花屬性數(shù)據(jù)并查看數(shù)據(jù)特征
iris_X = iris.dataprint(iris.data.shape)
# 獲取鳶尾花類別數(shù)據(jù)
iris_y = iris.target
拆分****數(shù)據(jù)集****為訓(xùn)練數(shù)據(jù)和測試數(shù)據(jù):
# 方法一:使用python的train_test_split庫進行數(shù)據(jù)集拆分
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)
# 方法二:隨機選擇部分數(shù)據(jù)(20%)作為測試集(適用于少量數(shù)據(jù))
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實現(xiàn)
在此我們將直接使用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')
參數(shù)介紹
l n_neighbors=5爽醋,就是KNN中的k便脊,默認為5。
l weights='uniform'遂赠,是距離計算中使用的權(quán)重,默認為'uniform' 是等權(quán)加權(quán)筷弦,也可以選'distance'是按照距離的倒數(shù)進行加權(quán)抑诸,也可以自己設(shè)置其他加權(quán)方式。(給距離增加權(quán)重奸绷,如果越近的距離權(quán)重越高层玲,能在一定程度上避免樣本分布不平均的問題)
l metric='minkowski'辛块、p=2,表示采用的是歐氏距離的計算润绵。
計算距離的方式默認為閔可夫斯基距離,是一組距離的定義授药。
兩個n維變量a(x11,x12,…,x1n)與 b(x21,x22,…,x2n)間的閔可夫斯基距離:
悔叽。
其中p=1時娇澎,為曼哈頓距離睹晒;p=2時,為歐氏距離戚啥;p→∞時锉试,為切比雪夫距離。根據(jù)變參數(shù)p的不同拖云,閔氏距離可以表示一類的距離。
l algorithm='auto'乏苦,是分類時采取的算法尤筐,有'brute'、'kd_tree'和'ball_tree'拢驾,三種默認按照數(shù)據(jù)特征從這三種中選擇最合適的改基。其中kd-tree基于歐氏距離的特性可以快速處理20維以內(nèi)的數(shù)據(jù)集,balltree基于更一般的距離特性稠腊,適合處理高維數(shù)據(jù)鸣哀。(三種算法的具體實現(xiàn)之后會進行詳細介紹)
l leaf_size=30我衬,是kd_tree或ball_tree生成的樹的樹葉(二叉樹中未分枝的節(jié)點)的大小。
l n_job=1井仰,是并行計算的線程數(shù)量破加,默認是1,輸入-1則設(shè)為CPU的內(nèi)核數(shù)合是。
# ****提供數(shù)據(jù)集進行訓(xùn)練
knn.fit(iris_X_train, iris_y_train)
# ****預(yù)測測試集數(shù)據(jù)鳶尾花類型
predict_result = knn.predict(iris_X_test)print(predict_result)
# ****計算預(yù)測的準確率
print(knn.score(iris_X_test, iris_y_test))
4 完整源碼及輸出結(jié)果
!/usr/bin/python
-- coding: utf-8 --
KNN調(diào)用
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
導(dǎo)入鳶尾花數(shù)據(jù)并查看數(shù)據(jù)特征
iris = datasets.load_iris()
print('數(shù)據(jù)量',iris.data.shape)
拆分屬性數(shù)據(jù)
iris_X = iris.data
拆分類別數(shù)據(jù)
iris_y = iris.target
方法一:拆分測試集和訓(xùn)練集,并進行預(yù)測
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)
方法二:拆分測試集和訓(xùn)練集
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()
提供訓(xùn)練集進行順利
knn.fit(iris_X_train, iris_y_train)
預(yù)測測試集鳶尾花類型
predict_result = knn.predict(iris_X_test)
print('預(yù)測結(jié)果',predict_result)
計算預(yù)測的準確率
print('預(yù)測準確率'聪全,knn.score(iris_X_test, iris_y_test))
輸出結(jié)果
"D:\anaconda python\python3.6.exe" D:/machine_learning/coding/knntest.py
數(shù)據(jù)量 (150, 4)
預(yù)測結(jié)果 [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]
預(yù)測準確率 0.933333333333
Process finished with exit code 0