【機器學習實戰】knn演算法手寫
首先初始化資料
def createDataSet():
group = np.array([[1.0, 1.1], [1.0, 1.0], [0.0,0.0], [0.0,0.1]])
labels = ['A', 'A', 'B', 'B']
return group, labels
然後實現分類,定義方法classify0
def classify0(inX, dataSet, labels, k):
inX:預測點 dataSet:樣本點 labels:樣本標籤 k:選擇最近鄰居數量
dataSetSize = dataSet.shape[0]
獲取樣本行數。 然後計算預測點和樣本點的距離
diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet
sqDiffMat = diffMat ** 2
sqDistances = sqDiffMat.sum(axis=1)
distances = sqDistances ** 0.5
首先將樣本擴充套件成shape=(dataSetSize, 1)的矩陣。舉個栗子,我們的預測點是(0, 1),我們樣本的行數是4,name最後np.tile之後的結果就是 [[0, 1] [0, 1] [0, 1] [0, 1]] 然後是矩陣的減法(不知道怎麼在這裡插入數學公式,只能意思一下) np.array([[0, 1], [0, 1], [0, 1], [0, 1]])-np.array([[1.0, 1.1], [1.0, 1.0], [0.0,0.0], [0.0,0.1]]) = np.array([[-1.0, -0.1], [-1.0, 0], [0.0, 1.0], [0.0,1.0]])
在對昨晚差值的矩陣做平方和,計算出來的結果在做開根號,也就是我們通常計算標準差的方法。 這裡通過矩陣的方法實現很巧妙的解決了我們不需要是關心維度的問題。
對計算出來的標準差進行排序
sortedDistIndicies = distances.argsort()
sortedDistIndicies返回的結果不是排序的結果,而是按順序排序完成之後index的結果,例如一個list[9, 6, 7, 3] 那麼返回的結果應該是[3, 1, 2, 0]分別表示的是按順序排列下來的index的值。 選取距離最近的k個點,並將結果存入classCount這個字典中,key表示label,value表示接近這個值得點的個數
for i in range(k):
voteIlabale = labels[sortedDistIndicies[i]]
classCount[voteIlabale] = classCount.get(voteIlabale, 0) + 1
最後取結果個數最多的label值作為預測點的標籤。
完整程式碼如下: def classify0(inX, dataSet, labels, k): dataSetSize = dataSet.shape[0]
# 距離計算
tileMat = np.tile(inX, (dataSetSize, 1))
diffMat = tileMat - dataSet
sqDiffMat = diffMat ** 2
sqDistances = sqDiffMat.sum(axis=1)
distances = sqDistances ** 0.5
sortedDistIndicies = distances.argsort()
classCount = {}
# 選擇距離最小的k個點
for i in range(k):
voteIlabale = labels[sortedDistIndicies[i]]
classCount[voteIlabale] = classCount.get(voteIlabale, 0) + 1
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]