简单地说,k-近邻算法采用测量不同特征值之间的距离方法进行分类。
实施 kNN 分类算法(使用k-近邻算法将每组数据划分到某个类中)
其伪代码如下:
对未知类别属性的数据集中的每个点依次执行以下操作:
(1)计算已知类别数据集中的点与当前点之间的距离;
(2)按照距离递增次序排序;
(3)选取与当前点距离最小的k个点;
(4)确定k个点所在类别的出现频率;
(5)返回前k个点出现频率最高的类别作为当前点的预测分类。
python函数classify0()程序
def classify0 (inX, dataset, labels, k):
dataSetSize = dataSet.shape[0]
diffMat = tile(inX, (dataSetSize,1))-dataSet
sqDiffMat = diffMat**2
sqDistances = sqDiffMat.sum(axis=1)
distances = sqDistances ** 0.5
sortedDistIndicies = distances.argsort()
classCount = {}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0)+1
sortedClassCount = sorted(classCount.iteritems(),
key = operator.itemgetter(1),reverse = True)
return sortedClassCount[0][0]
下面一一解释以上代码
classify0 (inX, dataset, labels, k)
函数classify()有四个输入参数:inX表示用于分类的输入向量,dataSet表示输入的训练样本集,labels表示标签向量,k表示选取的与输入向量距离最相近的样本点的个数。
dataSetSize = dataSet.shape[0]
先来解释试一下 .shape()函数
.shape()函数的功能读取矩阵的长度
e.shape[0] 读取e的第一维度长度
由此可知,dataSet.shape[0]此时为获取训练样本集dataSet的行数。
diffMat = tile(inX, (dataSetSize,1))-dataSet
又出现一个新的函数 tile()函数
.tile()函数 功能是重复某个数组
例如:tile(A,n),功能是将数组A重复n次,构成一个新数组
a = [0,1,2]
b = tile(a,2)
b
array ([0,1,2,0,1,2])#将a数组重复2次
a = [0,1,2]
b = tile(a,(1,2))
b
array ([0,1,2,0,1,2])#将a数组重复2次构成一个数组
a = [0,1,2]
b = tile(a,(2,1))
b
array([0,1,2],[0,1,2])#将a数组重复一次构成两个数组
由此可见,此处得到测试元素与训练样本集中所有点的差
sqDiffMat = diffMat**2
本步骤是对上一步求平方
sqDistances = sqDiffMat.sum(axis=1)
(axis=1)表示沿着每一行或者列标签模向执行对应的方法
(axis=0)表示沿着每一列或行标签\索引值向下执行方法
此处表示对应行相加,得到测试点与样本集中每一个点距离的平方。
distances = sqDistances ** 0.5
对上述距离的平方开方,得出测试点与样本集中每一个点的距离。
sortedDistIndicies = distances.argsort()
对上一行代码得出的距离进行升序排列。
classCount = {}#字典的声明
for i in range(k):#选出距离最小的k个点
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0)+1
sortedDistIndicies[0]返回的是距离最小的数据样本的序号
labels[sortedDistIndicies[0]]距离最小的数据样本的标签
sortedClassCount = sorted(classCount.iteritems(),
key= operator.itemgetter(1),reverse = True)#给该字典排序,sortedClassCount[0][0]是K中支持的标签数最大的
return sortedClassCount[0][0]#返回发生频率最高的标签
字典的iteritems方法作用:与items方法相比作用大致相同,只是它的返回值不是列表,而是一个迭代器.
operator模块提供的itemgetter函数用于获取对象的哪些维的数据.