機器學習(二)k-近鄰分類算法(kNN)

1、k-近鄰算法概述
k-近鄰算法採用測量不同特徵值之間的距離的方法進行分類
優點:精度高、對異常值不敏感、無數據輸入假定;
缺點:計算複雜度高、空間複雜度高;
適用數據範圍:數值型和標稱型。
2、工作原理:
     存在一個樣本數據集合,也稱作訓練樣本集,並且樣本集中每個數據都存在標籤,即我們知道樣本集中每一數據與所屬分類的對應關係。輸入沒有標籤的新數據後,將新數據的每個特徵與樣本集中數據對應的特徵進行比較,然後算法提取樣本集中特徵最相似數據(最鄰近)的分類標籤。一般來說,我們只選擇樣本數據集中前k個最相似的數據,這就是k-近鄰算法中k的出處,通常k是不大於20的整數。最後,選擇k個最相似數據中出現次數最多的分類,作爲新數據的分類。
3、流程
*收集數據
*準備數據:距離計算所需要的數值,最好是結構化的數據格式。
*分析數據:
*訓練算法:此步驟不適用於k-近鄰算法
*測試算法:計算錯誤率
*使用算法:首先需要輸入樣本數據和結構化的輸出結果,然後運行k-近鄰算法判定輸入數據分別屬於哪個分類,最後應用對計算出的分類執行後續的處理。
Python實現:
# -*- coding: utf-8 -*-
'''
Created on Sun Aug 21 18:44:27 2016
kNN: k Nearest Neighbors
Input:      
    inX:用於分類的輸入向量
    dataSet:輸入的訓練樣本集
    labels:標籤向量
    k:表示用於選擇最近鄰居的數目
標籤向量的元素數目和矩陣dataSet的行數相同
Output: 分類結果
@author: GnahzNib
'''

# 導入科學計算包numpy
from numpy import *
# 導入運輸符模塊
import operator
# 導入listdir()函數(獲得目錄中的相關內容的介紹)
from os import listdir

# k-鄰近算法實現
def classify0(inX, dataSet, labels, k):
    # 已知分類的數據集(訓練集)的行數
    dataSetSize = dataSet.shape[0]
    # 1、計算歐式距離
    # tile函數將輸入點拓展成與訓練集相同維數的矩陣,再計算歐氏距離
    diffMat = tile(inX, (dataSetSize,1)) - dataSet  # 樣本與訓練集的差值矩陣
    sqDiffMat = diffMat**2  # 差值矩陣平方
    sqDistances = sqDiffMat.sum(axis=1)  # 計算每一行上元素的和
    distances = sqDistances**0.5  # 開方得到歐拉距離矩陣
    sortedDistIndicies = distances.argsort()  # 按distances中元素進行升序排序後得到的對應下標的列表     
    # 2、選擇距離最小的k個點    
    classCount={}          
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
        # 按classCount字典的第2個元素(即類別出現的次數)從大到小排序
    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]
4、示例:
1)使用Python導入數據
In [12]: from numpy import *
In [13]: import operator
In [14]: def createDataSet():
    ...:     group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
    ...:     labels = ['A', 'A', 'B', 'B']
    ...:     return group, labels
    ...:
In [15]: import kNN
In [16]: group,labels = kNN.createDataSet()
In [17]: group
Out[17]:
array([[ 1. ,  1.1],
       [ 1. ,  1. ],
       [ 0. ,  0. ],
       [ 0. ,  0.1]])
In [18]: labels
Out[18]: ['A', 'A', 'B', 'B']
2)實施kNN算法
In [19]: kNN.classify0([0, 0], group, labels, 3)
Out[19]: 'B'
In [20]: kNN.classify0([1.5, 0.5], group, labels, 3)
Out[20]: 'A'
3)測試分類器
分類器錯誤率=分類器給出錯誤結果的次數 / 測試執行的總數 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章