k-近邻算法的优缺点
k-近邻算法的工作原理:存在一个样本数据集合,即训练样本集,并且样本集中每个数据都存在标签。输入没有标签的新数据之后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据的分类标签。通常选择样本数据集中前k个最相似的数据,通常k是不大于20的整数。最后,选择k个最相似数据中出现次数最多的分类,作为新数据的分类。
k-近邻算法的处理流程:
(1) 收集数据:可以使用任何方法。
(2) 准备数据:距离计算所需要的数值,最好是结构化的数据格式。
(3) 分析数据:可以使用任何方法。
(4) 训练算法:此步骤不适用于k近邻算法。
(5) 测试算法:计算错误率。
(6) 使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-近邻算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续的处理。
import kNN
group, labels = kNN.createDataSet()
group
labels
import numpy as np
groupMat = np.mat(group)
groupMat
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
mat0 = groupMat[np.nonzero(groupMat[:,0] == 1)[0],:]
mat1 = groupMat[np.nonzero(groupMat[:,0] != 1)[0],:]
mat0
mat1
mat0[:,0] - 0.1
ax.scatter(mat0[:,0].flatten().A[0], mat0[:,1].flatten().A[0], s=8, c='red')
ax.scatter(mat1[:,0].flatten().A[0], mat1[:,1].flatten().A[0], s=8, c='blue')
(mat0[:,0] - 0.1).flatten().A[0]
bias = 0.04
bias1 = 0.02
for i in range(mat0.shape[0]):
ax.text(mat0[i,0] - bias, mat0[i,1] - bias1, 'A')
for i in range(mat1.shape[0]):
ax.text(mat1[i,0] + bias1, mat1[i,1] - bias1, 'B')
plt.show()
伪代码如下:
对未知类别属性的数据集中的每个点依次执行以下操作:
(1) 计算已知类别数据集中的点与当前点之间的距离
(2) 按照距离递增次序排序
(3) 选取与当前点距离最小的k个点
(4) 确定前k个点所在类别的出现概率
(5) 返回前k个点出现频率最高的类别作为当前点的预测分类
在kNN.py的classify0函数中距离计算使用到的是欧式距离公式,计算两个点xA和xB的距离为:
$$d = \sqrt{(xA_{0} - xB_{0})^{2} + (xA_{1} - xB_{1})^{2}}$$
kNN.classify0([0,0], group, labels, 3)
reload(kNN)
datingDataMat, datingLabels = kNN.file2matrix('datingTestSet.txt')
datingDataMat
datingLabels[0:20]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(datingDataMat[:,1], datingDataMat[:,2], 15.0*np.array(datingLabels), 15.0*np.array(datingLabels))
plt.show()
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(datingDataMat[:,0], datingDataMat[:,1], 15.0*np.array(datingLabels), 15.0*np.array(datingLabels))
plt.show()
归一化数值的方法可以利用如下的公式:
$$newValue = (oldValue - min) / (max - min)$$
reload(kNN)
normMat, ranges, minVals = kNN.autoNorm(datingDataMat)
normMat
ranges
minVals
#kNN.datingClassTest() #输出结果太长了,所以注释掉
reload(kNN)
kNN.classifyPerson()
使用k-近邻算法的手写识别系统步骤:
(1) 收集数据:提供文本文件。
(2) 准备数据:编写函数classify0(),将图像格式转换成分类器使用的list格式。
(3) 分析数据:在python命令提示符中检查数据,确保它符合要求。
(4) 训练算法:此步骤不适用于k-近邻算法。
(5) 测试算法:编写函数使用提供的部分数据集作为测试样本,测试样本与非测试样本的区别在于测试样本是已经完成分类的数据,如果预测分类与实际分类不同,则标记为一个错误。
testVector = kNN.img2vector('testDigits/0_13.txt')
testVector[0,0:31]
testVector[0,32:63]
#kNN.handwritingClassTest() #输出结果太长了,所以注释掉