写在前面:
工作原理:存在一个样本数据集合(训练样本集),且样本集中每个数据都存在标签。输入没有标签的新数据后,将新数据的每个特征与样本集中数据对用的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。通常情况下,只选择前K个最相似的数据(一般来说,K是的整数)
K-近邻算法采用测量不同特征值之间的距离方法进行分类
优点:精度高、对异常值不敏感、无数输入假定
缺点:计算复杂度高、空间复杂度高
1.准备:使用Python导入数据
import numpy as np
import operator
def creatDataset():
group = np.array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
labels = ['A', 'A', 'B', 'B']
return group,labels
group, labels = creatDataset()
导入科学计算包NumPy和运算符模块(执行排序操作时将使用这个模块提供的函数)。group矩阵每行包括一个不同的数据,向量labels包含了每个数据点的标签信息,labels包含的元素个数等于 group矩阵行数。
查看定义的变量group和labels:
print("group:", group)
print("labels:", labels)
group: [[1. 1.1]
[1. 1. ]
[0. 0. ]
[0. 0.1]]
labels: ['A', 'A', 'B', 'B']
Process finished with exit code 0
2.实施kNN分类算法
def classify0(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
sorteddistindices = distances.argsort()
classcount = {}
for i in range(k):
voteilabel = labels[sorteddistindices[i]]
classcount[voteilabel] = classcount.get(voteilabel, 0) + 1
sortedclasscount = sorted(classcount.items(),
key = operator.itemgetter(1),
reverse = True)
return sortedclasscount[0][0]
参数说明:
- inX:用于分类的输入向量
- dataset:输入的训练样本集
- labels:标签向量
- k:选择最近邻居的数量
其中labels的元素数目=dataset的行数
下面将对上述代码分为三部分进行概述
2.1 K-近邻“三步走”:
①距离计算
diffmat = np.tile(inX, (datasetsize, 1))-dataset
sqdiffmat = diffmat**2
sqdistances = sqdiffmat.sum(axis = 1)
distances = sqdistances**0.5
使用欧式距离公式(),计算向两点之间的距离
②选择距离最小的K个点
计算完所有点之间的距离之后,对数据从小到大进行排序,然后前K个距离最小元素所在的主要分类,输入K为正整数。
voteilabel = labels[sorteddistindices[i]]
classcount[voteilabel] = classcount.get(voteilabel, 0) + 1
③排序
将classcount字典分解为元组列表,然后使用operator模块中的itemsgetter方法,按照第二个元素的次序对元组进行排序(此处为逆序),返回发生频率最高的元素标签。
sortedclasscount = sorted(classcount.items(),
key = operator.itemgetter(1),
reverse = True)
return sortedclasscount[0][0]
3.预测数据所在分类
print(classify0([0, 0], group, labels, 3))
输出结果为B,也可以尝试将[0,0]更改为其他值,测试程序的运行结果