kNN算法介绍
总的来说就是已经存在了一个带标签的数据库,然后输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似(最近邻)的分类标签。一般来说,只选择样本数据库中前k个最相似的数据。最后,选择k个最相似数据中出现次数最多的分类。
- 特点:所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。
- 优点:相对易于实现、可快速适应新变化、只要有相对较少的评分数据就能够得到一定的推荐质量。
- 不足:
1)当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。
改进:采用权值的方法(和该样本距离小的邻居权值大)
2)计算量较大,因为对每一个待分类的文本都要计算它到全体已知样本的距离,才能求得它的K个最近邻点。
解决:事先对已知样本点进行剪辑,事先去除对分类作用不大的样本。
- 适用:
1)样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分;
2)类域的交叉或重叠较多的待分样本集(由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的)。
- 步骤:
a.计算已知类别数据集中的点与当前点之间的距离;
b. 按照距离递增次序排序;
c.选取与当前点距离最小的k个点;
d.确定前k个点所在类别的出现频率;
e.返回前k个点出现频率最高的类别作为当前点的预测分类。
- 应用实例:
python实践
函数扫盲:
数组的大小可以通过其shape属性获得,shape[0]表示数组行数
numpy.tile(A,B):将A重复B次,这里B可以是int类型也可以是元组类型
tile([0,0],(3,1))在列方向上重复[0,0]1次行3次
sum()的参数是list,求和函数 axis=1行数为1
argsort()将数组按升序排列
{}字典类型
利用字典的get()方法从字典中获得一个值,且不需要处理字典里找不到你所需要的键值的异常。
get(voteLabel, 0)字典里没有就返回0
kNN基础实践
利用一个很小的数据库来测试算法的正确性。
首先新建一个kNN.py脚本文件,文件里包含两个函数,一个用来生成小数据库,一个实现kNN分类算法。代码如下:
# kNN
#输入: newInput:用来和已有数据比较的1*N维向量
dataSet:大小为m的已知向量集N*M维向量
labels:数据标签(1*M维向量)
k:用于比较的邻居个数
#输出: 最流行的标签类
def kNNClassify(newInput,dataSet,labels,k):
numSamples=dataSet.shape[0] #shape[0] stands for the sum of row
#kNN的核心算法就是计算欧式距离,下面计算待分类点和训练集中的任一点的欧式距离
diff=tile(newInput,(numSamples,1))-dataSet
squaredDiff=diff**2
squaredDist=sum(squaredDiff,axis=1)
distance=squaredDist**0.5
#接下来做一些统计
sortedDisIndices=argsort(distance)
classCount={}
for i in xrange(k):
voteLable = labels[sortedDisIndices[i]]
classCount[voteLable]=classCount.get(voteLable,0)+1
maxCount=0
for key,value in classCount.items():
if value>maxCount:
maxCount=value
maxIndex=key
return maxIndex
再建一个kNNtest.py文件:
import kNN
from numpy import *
dataSet,lables=kNN.creatDataSet()
textX=array([1.2,1.0])
k=3
outputLable=kNN.kNNClassify(textX,dataSet,lables,3)
print "Your input is:",textX,"and classified to class:",outputLable
textX=array([0.1,0.3])
outputLable=kNN.kNNClassify(textX,dataSet,lables,3)
print "Yourinput is:",textX,"and classified to class:",outputLable
得到的结果如下: