目录
1、k-近邻算法
概述
简单来说,k-近邻算法即采用测量不同特征值之间的距离方法来进行分类。
工作原理:存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系。输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们只选择样本数据集中前k个最相似的数据,这就是k-近邻算法中k的出处,通常k是不大于20的整数。最后,选择k个最相似数据中出现次数最多的分类,作为新数据的分类。
原理
KNN 的原理就是当预测一个新的值 x 的时候,根据它距离最近的 K 个点是什么类别来判断 x 属于哪个类别。
例:
图中蓝色正方形,红色三角形分别为两种类别
我们想要预测绿点x为什么类别。
假设k=3,如图实线圆圈圈出了与绿点最近的3个点,三点中红色三角形最多,我们可以把该绿点归为红色三角形。
当我们假设k=5时,如图虚线圆圈圈出了与绿点最近的5个点,五点中蓝色正方形最多,那么我们就可以把该绿点归为蓝色正方形。
基本流程
(1)收集数据:可以使用任何方法。
(2)准备数据:距离计算所需要的数值,最好是结构化的数据格式。
(3)分析数据:可以使用任何方法。
(4)训练算法:此步骤不适用于k-近邻算法。
(5)测试算法:计算错误率。
(6)使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-近邻算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续的处理。
优缺点
优点:算法简单,易于实现,因为算法的复杂性并不高。 精度高、对异常值不敏感、无数据输入假定。
缺点:参数量少,训练 KNN 算法时唯一需要的参数是 k 的值和我们想从评估指标中选择的距离度量的选择。 计算复杂度高、空间复杂度高。适用数据范围:数值型和标称型。
2、距离公式
欧氏距离(Euclidean Distance)
欧氏距离是最常见的距离度量,衡量的是多维空间中两个样本点之间的绝对距离。
曼哈顿距离(Manhattan Distance)
红线代表曼哈顿距离,绿色代表欧氏距离,也就是直线距离,而蓝色和黄色代表等价的曼哈顿距离。曼哈顿距离一一两点在南北方向上的距离加上在东西方向上的距离。
3、应用实例
import numpy as np
import operator
'''
函数说明: 创建数据集
Returns:
group - 数据集
labels - 分类标签
'''
def createDataSet():
group=np.array([[1,101],[5,89],[108,5],[115,8]]) #数据集,四组二维特征
labels=['爱情片','爱情片','动作片','动作片'] #分类标签,四组特征的标签
return group,labels
"""
函数说明:kNN算法,分类器
Parameters:
inX - 用于分类的数据(测试集)
dataSet - 用于训练的数据(训练集)
labes - 分类标签
k - kNN算法参数,选择距离最小的k个点
Returns:
sortedClassCount[0][0] - 分类结果
"""
def classify0(inX, dataSet, labels, k):
# numpy函数shape[0]返回dataSet的行数
dataSetSize = dataSet.shape[0]
# b = tile(a,(m,n)):即是把a数组里面的元素复制n次放进一个数组c中,然后再把数组c复制m次放进一个数组b中
diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet
# 二维特征相减后平方
sqDiffMat = diffMat ** 2
# sum()所有元素相加,sum(0)列相加,sum(1)行相加
sqDistances = sqDiffMat.sum(axis=1)
# 开方,计算出距离
distances = sqDistances ** 0.5
# 返回distances中元素从小到大排序后的索引值
sortedDistIndices = distances.argsort()
# 定一个记录类别次数的字典
classCount = {}
for i in range(k):
# 取出前k个元素的类别
voteIlabel = labels[sortedDistIndices[i]]
# dict.get(key,default=None),字典的get()方法,返回指定键的值,如果值不在字典中返回默认值。
# 计算类别次数
classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
# python3中用items()替换python2中的iteritems()
# key=operator.itemgetter(1)根据字典的值进行排序
# key=operator.itemgetter(0)根据字典的键进行排序
# reverse降序排序字典
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
# 返回次数最多的类别,即所要分类的类别
return sortedClassCount[0][0]
if __name__ == '__main__':
# 创建数据集
group, labels = createDataSet()
# 测试集
test = [101, 20]
# kNN分类
test_class = classify0(test, group, labels, 3)
# 打印分类结果
print(test_class)
运行结果:
4、小结
1、k-近邻算法使用起来方便快捷,但对k值要求较高,一般而言,随着的逐渐增大,K近邻算法的分类效果会逐渐提升;但在增大到某个值后,随着的进一步增大,K近邻算法的分类效果会逐渐下降。所以说,k值的选择十分重要。
2、我们在使用k-近邻算法时,必须要确保有接近实际数据的训练样本,避免误差过大。