苛求真理的欲望讓我想要了解算法的本質(zhì)民泵,于是我開始了機(jī)械學(xué)習(xí)的算法之旅
from numpy import *
import operator
from collections import Counter
#KNN需要測(cè)試集乓旗,訓(xùn)練集,標(biāo)簽和k值
#測(cè)試集:你需要測(cè)試的數(shù)據(jù)
#訓(xùn)練集:給定的標(biāo)準(zhǔn)數(shù)據(jù)
#標(biāo)簽:每個(gè)標(biāo)準(zhǔn)數(shù)據(jù)的類別
#k值 :測(cè)試集和訓(xùn)練集相比較下前K個(gè)最相識(shí)的訓(xùn)練集的值
# 用KNN算法找出測(cè)試集的類別
#1,求出已知類別訓(xùn)練集中的點(diǎn)與當(dāng)前點(diǎn)之間的距離
#2羔挡,對(duì)所求距離以此遞增排序
#3,選取與當(dāng)前點(diǎn)距離最小的k個(gè)點(diǎn)
#4,確定前k個(gè)點(diǎn)所在類別的出現(xiàn)頻率
#5匹颤,返回前k個(gè)點(diǎn)出現(xiàn)頻率最高的類別作為當(dāng)前點(diǎn)的預(yù)測(cè)分類
def kNNClassify(testSet, trainSet, labels, k=3):
rows = trainSet.shape[0] #shape[0]得到訓(xùn)練集的行數(shù)
#求距離
distSet = tile(testSet, (rows, 1)) - trainSet #得到距離矩陣
distance = sum(distSet ** 2 , axis = 1) ** 0.5 # 求出距離
#排序
#得到排序后數(shù)據(jù)原位置的下標(biāo),排序后位置是不變的
#從而使得排序后的結(jié)果和trainSet的標(biāo)簽一一對(duì)應(yīng)
#然后就可以通過排序結(jié)果反向得到標(biāo)簽值
sortedDistIndices = argsort(distance)
#選取k個(gè)最小值
classCount = Counter()# 保存類別
#記錄k值內(nèi)相同標(biāo)簽出現(xiàn)的次數(shù)
[classCount.update([labels[sortedDistIndices[i]]]) for i in xrange(k)]
## 得到出現(xiàn)次數(shù)最多的標(biāo)簽類別
return sorted(classCount.iteritems(), key=lambda d:d[1], reverse = True )[0][0]
if __name__ == '__main__':
#然后我們?cè)诿钚兄袦y(cè)試
trainSet = array([
[1.0, 0.9],
[1.0, 1.0],
[0.1, 0.2],
[0.0, 0.1]])
labels = ['A', 'A', 'B','B'] # 4個(gè)標(biāo)簽,2種類別
testSet = array([1.2, 1.0])
label = kNNClassify(testSet, trainSet, labels, k=3)
print "輸入:", testSet, "分類: ", label
testSet = array([0.1, 0.3])
label = kNNClassify(testSet, trainSet, labels, k=3)
print "輸入:", testSet, "分類: ", label
輸入: [ 1.2 1. ] 分類: A
輸入: [ 0.1 0.3] 分類: B