算法1:k-近邻
1.k-近邻算法概述
简单地说,k-近邻算法采用测量不同特征值之间的距离方法进行分类,属于监督学习。
工作原理:村爱一个样本数据集合(亦称训练样本集),并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系。输入没有标签的新数据后,将新数据每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们只选择样本数据集中前k个最相似的数据,这就是k-近邻算法中k的出处,通常k是不大于20的整数,最后,选择k个最相似数据中出现次数最多的分类,作为新数据的分类。
- 优点:精度高、对异常值不敏感,无数据输入假定;
- 缺点:时间和空间复杂度都高;
算法的一半流程:
- 收集数据:想怎么收集就怎么收集啦;
- 准备数据:最好是结构化数据格式;
- 分析数据:散点图啦等等,随意分析;
- 训练算法:本算法不需要这一步;
- 测试算法:计算错误率;
- 使用算法:准备输入的样本数据,调用算法计算分类结果等;
2.Python实现
核心代码:
def classify0(inX, dataSet, labels, k): dataSetSize = dataSet.shape[0] diffMat = tile(inX, (dataSetSize,1)) - dataSet sqDiffMat = diffMat**2 sqDistances = sqDiffMat.sum(axis=1) distances = sqDistances**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.iteritems(), key=operator.itemgetter(1), reverse=True) return sortedClassCount[0][0]
解析
- 4个输入参数:用于分类的输入向量inX,训练样本集dataSet,标签向量labels,用于选择最近邻的数目k;
-
dataSetSize = dataSet.shape[0] 这一句使用到了NumPy的shape函数,返回矩阵/数组的不同维数的长度,第一个元素(shape[0])表示第一维的长度,亦即行数,可参考numpy.shape;
-
diffMat = tile(inX, (dataSetSize,1)) - dataSet 这里用到了NumPy中的tile(A,reps)函数,用于扩充A,具体用法可以参考numpy.tile; -
sqDiffMat = diffMat**2 求平方; -
sqDistances = sqDiffMat.sum(axis=1) 求和可参考numpy.sum; -
distances = sqDistances**0.5 求开方,上面的几步是用来计算距离的; -
sortedDistIndicies = distances.argsort()使用了argsort()函数,可以参考:numpy.argsort; -
classCount={} 这是一个dict,用于存储不同标签出现的次数; -
for i in range(k):voteIlabel = labels[sortedDistIndicies[i]]classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1这里是选择距离最小的k个点, sortedDistIndicies已经排好序,只需迭代的取前k个样本点的labels(即标签),并计算该标签出现的次数,这里还用到了dict.get(key, default=None)函数,key就是dict中的键voteIlabel,如果不存在则返回一个0并存入dict,如果存在则读取当前值并+1;
-
sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) 这里使用了sorted()函数sorted(iterable, cmp=None, key=None, reverse=False),iteritems()将dict分解为元组列表,operator.itemgetter(1)表示按照第二个元素的次序对元组进行排序,注意sort()的区别,可参考numpy.sort;

浙公网安备 33010602011771号