1. 程式人生 > >KNN(K鄰近)演算法

KNN(K鄰近)演算法

k-鄰近演算法的一般流程

  1. 收集資料:可以使用任何方法
  2. 準備資料:距離計算(應該是計算距離)所需要的數值,最好是結構化的資料格式
  3. 分析資料:可以使用任何方法
  4. 訓練演算法: 此步驟不適用與k-鄰近演算法
  5. 測試演算法:計算錯誤率
  6. 使用演算法:首先需要輸入樣本資料和結構化的輸出結果,然後執行k-鄰近演算法判定輸入資料分別屬於哪個分類,最後應用對計算出的分類執行後續的處理
# -*- coding: utf-8 -*-

# 建立名為kNN.py的Python模組
from numpy import * # 匯入科學計算包NumPy
import operator # 匯入運算子模組

# 匯入資料的函式,該函式返回 group 和 labels
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 def classify0(inX, dataSet, labels, k): dataSetSize = dataSet.shape[0] # 計算array的維度,array(4,2),array.shape=(4,2),shape[0]=4 #dataSetSize = 4 diffMat = tile(inX, (dataSetSize, 1
)) - dataSet # tile功能是重複某個陣列,tile(A,n).tile(A,(2,1))重複得到的陣列是一個二維陣列 # diffMat : # [-1. , -1.1], # [-1. , -1. ], # [ 0. , 0. ], # [ 0. , 0.1] sqDiffMat = diffMat ** 2 # 計算每個特徵值與inX點值的差值的平方 # sqDiffMat: # [1. , 1.21], # [1. , 1. ], # [0. , 0. ],
# [0. , 0.01], sqDistances = sqDiffMat.sum(axis=1) # sum of each row,if axis=0:sum of each column # sqDistances: # 該步驟的運算結果為:[ 2.21, 2. , 0. , 0.01] distances = sqDistances ** 0.5 # 計算歐式距離,即xA(xA0, xA1)和xB(xB0, xB1)之間的距離 # d = sqrt((xA0-xB0)^2) + (xA1-xB1)^2) # 例如:點(0, 0)與(1,2)之間的距離計算為: # sqrt( (1 - 0)^2 + (2 -0)^2 ) # 這一步的運算結果為:[ 1.48660687, 1.41421356, 0. , 0.1 ] sortedDistIndicies = distances.argsort() # numpy.argsort(a, axis=-1, kind='quicksort', order=None) # 這一步的運算結果為:[2, 3, 1, 0],即sortedDistIndicies[2] < sortedDistIndicies[3] < sortedDistIndicies[1] < sortedDistIndicies[0], ''' One dimensional array: >>> x = np.array([3, 1, 2]) >>> np.argsort(x) array([1, 2, 0]) Two-dimensional array: >>> x = np.array([[0, 3], [2, 2]]) >>> x array([[0, 3], [2, 2]]) ''' classCount = {} # classCount 是字典 for i in range(k): m = sortedDistIndicies[i] # 當i=0時,sortedDistIndicies[0] = 2 voteIlabel = labels[m] # voteIlabel = B classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 # dict.get(key, default=None) # key -- 字典中要查詢的鍵。 # default -- 如果指定鍵的值不存在時,返回該預設值值 # 返回指定鍵的值,如果值不在字典中返回預設值None # 迴圈結束後的結果為: # classCount = {'A': 1, 'B': 2} sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse= True) # itemgetter(1)方法按照第二個元素的次序對元組進行排序, # reverse表示逆序,結果為:[('B', 2), ('A', 1)] return sortedClassCount[0][0] if __name__ == '__main__': group, labels = createDataSet() print classify0([0, 0], group, labels, 3)

輸出的結果是: B