数据挖掘算法---KNN(附python代码)
2016-05-15 21:56
706 查看
首先本文只是介绍一下算法的思想以及里面涉及的关键的步骤,至于其所以然,大家可以看些专业的讲义或者视频,在此强烈推荐July的文章,虽然对于一些基础不好的人来说看完july的一篇长文是很费劲的,但是此人有传道精神,解惑品质,日后定成大师。希望以后大家多多支持。
KNN中文名字是K近邻,可以用于分类和回归,下面以分类为例进行讲解:
**
相似度如何计算?
一般的相似性计算有余弦相似度、皮尔十森系数、欧氏距离。。。。具体采用哪个要看具体的情景。
K的选取有何原则?
如果K选的过大,就不能很好的利用训练数据的有效的信息,也就是那些真正相似的数据,极端的例子是K取训练数据的总数;另一方面K选的过小,容易造成模型变得复杂,结果变得十分敏感,且出现错误的概率也增大,比如噪声恰好和目标数据很相似,极端的例子就是K=1,这时候就叫做最近邻。
共同投票的原则是什么?
投票多采用多数投票决定,因为多数投票其实等价于经验风险最小化。当然也可以做一些花样,比如很久距离的远近做带权重的投票。
如何快速的找到相似的数据?
KNN的搜索是一个十分关键的步骤,当数据量很大的时候,算法的搜索效率变得十分关键,常用的改善搜索效率的方案是使用kd树这种结构进行搜索。
关于kd树的构造及如何搜索,请参考july的文章,里面讲的很明白,在此不过多叙述。
KNN中文名字是K近邻,可以用于分类和回归,下面以分类为例进行讲解:
算法思想:
基于最相似的算法思想,类似协同过滤。比如说已知了训练集的一些数据的标签,要预测测试集的数据的标签,只需要计算预测集的每一个数据和训练集的数据的相似度,然后选取最相似的k个,再然后让着k个数据的类标签共同投票要预测的数据的类标签。**
几个问题:
**相似度如何计算?
一般的相似性计算有余弦相似度、皮尔十森系数、欧氏距离。。。。具体采用哪个要看具体的情景。
K的选取有何原则?
如果K选的过大,就不能很好的利用训练数据的有效的信息,也就是那些真正相似的数据,极端的例子是K取训练数据的总数;另一方面K选的过小,容易造成模型变得复杂,结果变得十分敏感,且出现错误的概率也增大,比如噪声恰好和目标数据很相似,极端的例子就是K=1,这时候就叫做最近邻。
共同投票的原则是什么?
投票多采用多数投票决定,因为多数投票其实等价于经验风险最小化。当然也可以做一些花样,比如很久距离的远近做带权重的投票。
如何快速的找到相似的数据?
KNN的搜索是一个十分关键的步骤,当数据量很大的时候,算法的搜索效率变得十分关键,常用的改善搜索效率的方案是使用kd树这种结构进行搜索。
关于kd树的构造及如何搜索,请参考july的文章,里面讲的很明白,在此不过多叙述。
适用场景
KNN算法适合样本容量比较大的类域的自动分类,而那些样本容量较小的类域不适合采用该算法。python代码:
# coding=utf-8 from __future__ import division from numpy import * import operator # 训练数据 def createDataset(): group = array([[9, 400], [10, 350], [100, 30], [120, 20]]) labels = ['1', '1', '0', '0'] return group, labels def classify(inX, dataSet, labels, k): # 选择训练样本数据集中前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] # 归一化 def autoNorm(dataSet): minVals = dataSet.min(0) maxVals = dataSet.max(0) ranges = maxVals - minVals normDataSet = zeros(shape(dataSet)) m = dataSet.shape[0] normDataSet = dataSet - tile(minVals, (m, 1)) normDataSet = normDataSet / tile(ranges, (m, 1)) # element wise divide return normDataSet, ranges, minVals # 训练模型并进行预测 def result(): datingDataMat, datingLabels = createDataset() # load dataset from file normMat, ranges, minVals = autoNorm(datingDataMat) # 需要预测的数据 datain = [[9, 405], [110, 30]] k = 3 for i in datain: print classify(i, normMat, datingLabels, k) if __name__ == '__main__': result()
相关文章推荐
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析
- C++实现汉诺塔算法经典实例
- PHP实现克鲁斯卡尔算法实例解析