k-近邻算法1——简单分类
本节主要内容来自Peter Harrington的《Machine Learning in Action》的中文版本《机器学习实战》
本文中代码
k-近邻算法的基本原理
k-近邻(k-Nearest Neighbors,kNN)算法,采用测量不同特征值之间的距离方法进行分类
- 优点:精度高、对异常值不敏感、无数据输入假定
- 缺点:
计算复杂度高(如果训练数据为n个,则针对每个实例时间复杂度为O(n))
空间复杂度高(无训练过程,所有的训练数据都需要保存)
无法给出任何数据的基础结构信息,如平均实例样本和典型实例样本具有什么特征 - 适用数据范围:数值型和标签型
k-近邻算法的一般流程
- 收集数据:可以使用任何方法
- 准备数据:距离计算所需要的数值,最好是结构化的数据格式
- 分析数据:可以使用任何方法
- 训练算法:此步骤不适合k-近邻算法
- 测试算法:计算错误率
- 使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-近邻算法判定输入数据分别属于哪个分类,最后应用计算结果进行后续处理
示例1
这是一个非常简单的案例。
准备结构化数据
创建kNN.py文件增加以下代码
from numpy import * #导入科学计算包NumPy
import operator # 运算符模块
def creatDataSet(): # 创建了数据集和标签,用于分类
group = 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
分析数据
## 使用scatter()绘制散点图
import matplotlib.pyplot as plt
import kNN
group, labels = kNN.creatDataSet()
x_coords = group[:, 0]
y_coords = group[:, 1]
# 作出散点图
plt.scatter(x_coords, y_coords, marker='s')
#添加labels
for x, y, z in zip(x_coords, y_coords, labels):
plt.annotate(
'%s' %z,
xy=(x, y),
xytext=(-8, 8),
textcoords='offset points',
ha='center',
va='top')
plt.xlim([-0.2, 1.2])
plt.ylim([-0.2, 1.2])
plt.show()
运行结果:
创建k近邻分类器
该k近邻分类器将把每组数据划分到某个类中,伪代码如下:
对未知类别属性的数据集中的每个点依次执行以下操作
- 计算当前点到已知类别数据集中的点的距离
- 按照距离从小到大排序
- 选取与当前点距离最小的k个点
- 确定前k个点所在类别出现的概率
- 返回前k个点出现频率最高的类别作为当前点的预测分类
在kNN.py中,添加代码
def classify0(inX, dataSet, labels, k):
datasetSize = dataSet.shape[0]
diffMat = tile(inX, (datasetSize, 1)) - dataSet #复制inX成多个数组与dataSet作差
squDiffMat = diffMat**2 #每个元素进行平方
squDistances = squDiffMat.sum(axis=1) #对应相加
distances = squDistances**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.items(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]
测试或使用算法
创建kNNTest.py, 写入
import kNN
group, label = kNN.creatDataSet()
# print(group)
# print(label)
inX = [[0, 0],[1, 2]]
for inx in inX:
distance = kNN.classify0(inx, group, label, 2)
print(distance)
运行结果为
B
A