歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Python實戰之KNN算法實現

Python實戰之KNN算法實現

日期:2017/3/1 9:20:27   编辑:Linux編程

用Python來實現K近鄰分類算法(KNN)已經是一個老生常談的問題,網上也已經有諸多資料,不過這裡我還是決定記錄一下自己的學習心得。

  1、配置numpy庫

  numpy庫是Python用於矩陣運算的第三方庫,大多數數學運算都會依賴這個庫來進行,關於numpy庫的配置參見:Python配置第三方庫Numpy和matplotlib的曲折之路,配置完成後將numpy庫整體導入到當前工程中。

  2、准備訓練樣本

  這裡簡單的構造四個點並配以對應標簽作為KNN的訓練樣本:

# ====================創建訓練樣本====================
def createdataset():
    group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
    labels = ['A', 'B', 'C', 'D']
    return group, labels

  這裡有一個小細節,就是通過array()函數老構造並初始化numpy的矩陣對象時,要保證只有一個參數,因此在代碼中需要將參數用中括號括起來,像下面這種調用方式是不合法的:

group = array([1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1])

  3、創建分類函數

  K近鄰算法在分類時一般是根據歐氏距離進行分類的,因此需要將輸入的數據與訓練數據在各個維度上相減再平方求和,再開方,如下:

# ====================歐氏距離分類====================
def classify(Inx, Dataset, labels, k):
    DataSetSize = Dataset.shape[0]  # 獲取數據的行數,shape[1]位列數
    diffmat = tile(Inx, (DataSetSize, 1)) - Dataset
    SqDiffMat = diffmat**2
    SqDistances = SqDiffMat.sum(axis=1)
    Distance = SqDistances**0.5
    SortedDistanceIndicies = Distance.argsort()
    ClassCount = {}

  這裡tile()函數是numpy的矩陣擴展函數,比如說這個例子中訓練樣本有四個二維坐標點,對於輸入樣本(一個二維坐標點),需要將其先擴展為一個4行1列的矩陣,然後在進行矩陣減法,在平法求和,再開平方算距離。計算完距離之後,調用矩陣對象的排序成員函數argsort()對距離進行升序排序。在這裡介紹一個Pycharm查看源碼生命的小技巧:加入在編寫這段程序的時候我們並不確定argsort()是否為array對象的成員函數,我們選中這個函數然後 右鍵 -> Go to -> Declaration,這樣就會跳轉到argsort()函數的聲明代碼片中,通過查看代碼的從屬關系能夠確認array類中確實包含這個成員函數,調用沒有問題:

  對距離排序之後,接下來就根據前K個最小距離值所對應的標簽來判斷當前樣本屬於哪一類:

    for i in range(k):
        VoteiLabel = labels[SortedDistanceIndicies[i]]
        ClassCount[VoteiLabel] = ClassCount.get(VoteiLabel, 0) + 1
    SortedClassCount = sorted(ClassCount.items(), key = operator.itemgetter(1), reverse = True)

  這裡有一個小問題就是在Python2中獲取字典元素使用的是dict.iteritems()成員函數,而在Python3中改為dict.items()函數。“key = operator.itemgetter(1)”的意思是指定函數針對字典中第二維元素進行排序,注意這裡需要在之前導入符號庫operator。這裡是通過記錄前K個距離最下值中每類標簽出現的次數來判決測試樣本的歸屬。

  4、測試

  這裡給出完整的KNN測試代碼:

# coding: utf-8
from numpy import *
import operator


# ====================創建訓練樣本====================
def createdataset():
    group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
    labels = ['A', 'B', 'C', 'D']
    return group, labels

# ====================歐氏距離分類====================
def classify(Inx, Dataset, labels, k):
    DataSetSize = Dataset.shape[0]  # 獲取數據的行數,shape[1]位列數
    diffmat = tile(Inx, (DataSetSize, 1)) - Dataset
    SqDiffMat = diffmat**2
    SqDistances = SqDiffMat.sum(axis=1)
    Distance = SqDistances**0.5
    SortedDistanceIndicies = Distance.argsort()
    ClassCount = {}
    for i in range(k):
        VoteiLabel = labels[SortedDistanceIndicies[i]]
        ClassCount[VoteiLabel] = ClassCount.get(VoteiLabel, 0) + 1
    SortedClassCount = sorted(ClassCount.items(), key = operator.itemgetter(1), reverse = True)
    return SortedClassCount[0][0]

Groups, Labels = createdataset()
Result = classify([0, 0], Groups, Labels, 1)
print(Result)

  運行代碼,程序答應結果“C”。這裡需要提一點的就是對於單訓練樣本(每類只有一個訓練樣本)的分類問題,KNN的K值應該設定為1。

下面關於Python的文章您也可能喜歡,不妨看看:

Linux下Python的安裝以及注意事項 http://www.linuxidc.com/Linux/2015-11/124861.htm

Ubuntu 14.04 下安裝使用Python rq模塊 http://www.linuxidc.com/Linux/2015-08/122441.htm

無需操作系統直接運行 Python 代碼 http://www.linuxidc.com/Linux/2015-05/117357.htm

CentOS上源碼安裝Python3.4 http://www.linuxidc.com/Linux/2015-01/111870.htm

《Python核心編程 第二版》.(Wesley J. Chun ).[高清PDF中文版] http://www.linuxidc.com/Linux/2013-06/85425.htm

《Python開發技術詳解》.( 周偉,宗傑).[高清PDF掃描版+隨書視頻+代碼] http://www.linuxidc.com/Linux/2013-11/92693.htm

Python腳本獲取Linux系���信息 http://www.linuxidc.com/Linux/2013-08/88531.htm

在Ubuntu下用Python搭建桌面算法交易研究環境 http://www.linuxidc.com/Linux/2013-11/92534.htm

Python 語言的發展簡史 http://www.linuxidc.com/Linux/2014-09/107206.htm

Python 的詳細介紹:請點這裡
Python 的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved