k-近鄰算法(KNN)
輸入沒有標(biāo)簽的新數(shù)據(jù)后,將新數(shù)據(jù)的每個特征與樣本集中數(shù)據(jù)對應(yīng)特征進行比較套鹅,然后提取樣本集中特征最相似的分類標(biāo)簽诫肠。一般來說奥务,選擇樣本集中前k個最相似的數(shù)據(jù),這k個數(shù)據(jù)中出現(xiàn)次數(shù)最多的分類就是新數(shù)據(jù)的預(yù)測分類房揭。
示例說明
預(yù)測電影類型备闲,樣本集是一系列的已知分類的電影,有兩類:
- 愛情
- 動作
這里選擇的特征是: - 接吻次數(shù)
- 打斗次數(shù)
一個樣本可以表示為(20捅暴,3恬砂,a):20次接吻鏡頭,3次打斗鏡頭的愛情電影蓬痒。
然后求(25泻骤,10,梧奢?)
用歐式距離表示相似程度狱掂,距離越近表明越相似: d=((20-25)**2 + (3-10)**2)**0.5
k-近鄰算法函數(shù)
import numpy as np
def classify_self(inX, dataSet, labels, k):
'''
自己抄一遍KNN的算法函數(shù)
inX: 輸入待預(yù)測的特征向量
dataSet: 訓(xùn)練樣本的特征值
labels: 訓(xùn)練樣本的目標(biāo)值
k: kNN的參數(shù)
'''
dataSetSize = dataSet.shape[0]
diffMat = dataSet - np.tile(inX, (dataSetSize, 1))
sqDiffMat = diffMat**2
sqDistances = sqDiffMat.sum(axis=1)
distances = sqDistances**0.5
sortedDistIndicies = distances.argsort()
classCount = {}
for i in range(k):
voteIlable = labels[sortedDistIndicies[i]]
classCount[voteIlable] = classCount.get(voteIlable, 0) + 1
sortedClassCount = sorted(classCount.items(), key= lambda x: x[1], reverse=True)
return sortedClassCount[0][0]
數(shù)值歸一化
有些特征的數(shù)值本身差異就大,不對數(shù)據(jù)處理就套用kNN就會放大這個差異大的特征的權(quán)重亲轨。
- 考察約會對象魅力程度的特征:
- 每年飛行里程
- 每周吃冰淇淋數(shù)量
- 玩游戲時間占用百分比
飛行里程本身一個樣本400公里趋惨,另一個2000公里,兩個樣本實際也就差個國際長途飛行的距離而已惦蚊。1600的平方立馬就完全可以忽略幾個冰淇淋和游戲百分比的數(shù)值差異了希柿。
而實際情況是诊沪,這幾個特征等權(quán)重(同樣重要指標(biāo))。
So曾撤,數(shù)值歸一化:
new_value = (origin_value - min)/(max - min)
- min和max表示特征的最小值和最大值
- 0 <= new_value <= 1
數(shù)值歸一化后所有特征就等權(quán)重了端姚,因為數(shù)值區(qū)間一致了。
import numpy as np
def autoNorm(dataSet):
minVals = dataSet.min(0)
maxVals = dataSet.max(0)
ranges = maxVals - minVals
normDataSet = np.zeros(shape(dataSet))
m = dataSet.shape[0]
normDataSet = dataSet - np.tile(minVals, (m,1))
normDataSet = normDataSet/tile(ranges, (m,1)) #element wise divide
return normDataSet, ranges, minVals