基於Python的機器學習實戰:KNN


1.KNN原理:

存在一個樣本數據集合,也稱作訓練樣本集,並且樣本集中每個數據都存在標簽,即我們知道樣本集中每一個數據與所屬分類的對應關系。輸入沒有標簽的新數據后,將新數據的每個特征與樣本集中數據對應的特征進行比較,然后算法提取樣本集中最相似數據(最近鄰)的分類標簽。一般來說,只選擇樣本數據集中前 $k$ 個最相似的數據,這就是KNN算法 $k$ 的出處, 通常 $k$ 是不大於20的整數。最后,選擇 $k$ 個最相似數據中出現次數最多的分類,作為新數據的分類。

2.實驗准備:

  • Python
  • scikit-learn(一個基於python的機器學習庫)

3.實驗代碼:

代碼有兩個版本,一個是自己編寫的簡單的KNN算法實現,一個是基於scikit-learn庫中KNN算法實現的,數據均采用scikit-learn中的手寫體數據集。

版本1(自己編寫):

# -*- coding: utf-8 -*-
""" This script is an exercise on KNN. Created on Tue Nov 03 21:21:39 2015 @author: 90Zeng """

import numpy as np from sklearn import datasets import operator #-----------------function classify-------------------------------------- 
def classify0(inX, dataSet, labels, k): dataSetSize = dataSet.shape[ 0 ] # 計算輸入的向量inX與所有樣本的距離
    diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet sqDiffMat = diffMat ** 2 sqDistances = sqDiffMat.sum(axis = 1) distances = sqDistances ** 0.5
    # 對距離大小進行排序
    sortedDistIndices = distances.argsort() classCount = {} # 選擇距離最小的 K 個點
    for i in range(k): voteLabel = labels[ sortedDistIndices[i] ] classCount[ voteLabel ] = classCount.get(voteLabel, 0) + 1  
    # 按照類別的數量多少進行排序
    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) return sortedClassCount[0][0]  # 返回類別數最多的類別名稱 #-------------------end of function classify--------------------------------


def handwritingClassTest(): # 導入數據
    digits = datasets.load_digits() totalNum = len(digits.data) # 選出90%樣本作為訓練樣本,其余10%測試
    trainNum = int(0.8 * totalNum) trainX = digits.data[0 : trainNum] trainY = digits.target[0 : trainNum] testX = digits.data[trainNum:] testY = digits.target[trainNum:] errorCount = 0 testExampleNum = len( testX ) for i in range( testExampleNum ): # 測試樣本在測試集中真實的類別
        trueLabel = testY[i] classifierResult = classify0( testX[ i, : ], trainX, trainY, 5 ) print "\nThe classifier came back with: %d, the real answer is: %d"\ % ( classifierResult, trueLabel ) if trueLabel != classifierResult: errorCount += 1
        else: pass
    print "\nThe total number of errors is: %d" % errorCount print "\nthe total error rate is: %f" % ( errorCount / float( testExampleNum) ) if __name__ == '__main__': print "start..." handwritingClassTest() 

運行結果:

版本2(使用庫函數):

# -*- coding: utf-8 -*-
""" This script is an exercise on KNN. Created on Tue Nov 06 21:26:39 2015 @author: ZengJiulin """
print(__doc__) import numpy as np from sklearn import neighbors, datasets digits = datasets.load_digits() totalNum = len(digits.data) # 選出90%樣本作為訓練樣本,其余10%測試
trainNum = int(0.8 * totalNum) trainX = digits.data[0 : trainNum] trainY = digits.target[0 : trainNum] testX = digits.data[trainNum:] testY = digits.target[trainNum:] n_neighbors = 10 clf = neighbors.KNeighborsClassifier(n_neighbors, weights='uniform') clf.fit(trainX, trainY) Z = clf.predict(testX) print "\nthe total error rate is: %f" % ( 1 - np.sum(Z==testY) / float(len(testX)) )

運行結果:

 

4.總結

KNN的優點:精度高、對異常值不敏感,無數據輸入假定

缺點:計算復雜度高(要計算待分類樣本與所有已知類別樣本的距離),空間復雜度高(存儲所有樣本點和目標樣本的距離)

 

 


免責聲明!

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



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