原理:给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的k个实例,这k个实例的多数属于某个类,就把该实例分类到这个类中
算法步骤:
- 计算已知类别数据集中的点与当前点之间的距离
- 按照距离递增排序
- 选取与当前点距离最近的k个点
- 确定前k个点所在类别出现的频率
- 返回前k个点所出现频率最高的类别作为当前点的预测分类
优点:
- 简单好用,容易理解,精度高,理论成熟,既可分类也可回归
- 可用于数值型数据和离散型数据
- 训练时间复杂度为O(n),无数据输入假定
- 对异常值不敏感
缺点:
- 计算复杂性高,空间复杂性高
- 样本不平衡问题(部分类别样本数量多,其他类别样本数量少)
- 样本太多时计算量太大;样本太少时容易误分
- 无法给出数据的内在含义
一、手动构造k近邻分类
import numpy as np
import operator
group = np.array([[1,101], [5,89], [108,5], [115,8]])
labels = ['爱情片', '爱情片', '动作片', '动作片'
#构造一个k近邻分类
def classifier(inX, dataset, labels, k):
datasize = dataset.shape[0] #得到训练集的个数
diffMat = np.tile(inX, (datasize,1)) - dataset #把待预测的点坐标扩展成与训练集一样维度的矩阵,然后相减
sqdiffMat = diffMat ** 2
sumdiffMat = sqdiffMat.sum(axis=1)
distances = sumdiffMat ** .5 #开方,计算出待预测点与所有训练集中点的距离
sorteddistindex = distances.argsort() #返回按照元素从小到大排序的索引值
classcount = {} #定义一个空字典,存放标签和对应出现的次数
for i in range(k):
votelabel = labels[sorteddistindex[i]]
classcount[votelabel] = classcount.get(votelabel,0) + 1
sortedclasscount = sorted(classcount.items(), key=operator.itemgetter(1), reverse=True) #按照出现次数降序排列
return sortedclasscount[0][0]
test = [101, 20]
test_class &