算法執(zhí)行步驟:
對未知類別屬性的數(shù)據(jù)集中的每個點依次執(zhí)行以下操作:
1)計算已知類別數(shù)據(jù)集中的點與當前點之間的距離缰犁;
2)按照距離遞增次序進行排序;
3)選取與當前點距離最小的k個點垛叨;
4)確定前k個點所在類別的出現(xiàn)頻率迅腔;
5)返回前k個點出現(xiàn)頻率最高的類別作為當前點的預測分類装畅。
k的取值不大于20
適用于數(shù)值型和標稱型數(shù)據(jù)的分類
不需要提前訓練,即用即練沧烈。
實現(xiàn)代碼如下:
from numpy import *
import operator
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 classify(intX, dataSet, labels, k):
dataSetSize = dataSet.shape[0] #shape函數(shù)是numpy.core.fromnumeric中的函數(shù)掠兄,它的功能是查看矩陣或者數(shù)組的維數(shù)
diffMat = tile(intX, (dataSetSize, 1)) - dataSet #tile(A, B),將A按B的格式要求進行重復,B可以是int(此時在列上重復徽千,行默認重復一次)
#若B為元祖(a,b)苫费,則在行上重復a次,列上重復b次
sqDiffMat = diffMat ** 2
sqDistances = sqDiffMat.sum(axis=1) #axis=0表示按列相加双抽,axis=1表示按照行相加
distances = sqDistances ** 0.5
sortedDistIndicies = distances.argsort() #得到數(shù)組值從小到大的索引值
#print(sortedDistIndicies)
classCount = {}
for i in range(k):
voteLabel = labels[sortedDistIndicies[i]]
classCount[voteLabel] = classCount.get(voteLabel, 0) + 1 #get()返回指定鍵的值百框, 如果指定鍵的值不存在時,返回默認值值(此處為0)
#此處即為記錄每個入選標簽在所有入選標簽中出現(xiàn)的次數(shù)
sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse=True) #items() 函數(shù)以列表返回可遍歷的(鍵,值)元組
return sortedClassCount[0][0]
if __name__ == '__main__':
group, labels = createDataSet()
result = classify([0, 0], group, labels, 3)
print(result)
執(zhí)行結(jié)果
[2 3 1 0]
B
上面是k-近鄰算法的基本實現(xiàn)牍汹,為了完全理解算法在實際過程中的應(yīng)用铐维,還做了個有關(guān)約會對象是否為理想對象的實戰(zhàn)練習,源碼:https://github.com/YanniYao/algorithm_in_machine_learning/tree/master/kNN_exercise