首先初始化数据
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]