原理:
k近邻(k-Nearest Neighor,简称kNN)学习是一种常用的监督学习方法,常用来分类,其工作机制非常简单:给定测试样本,基于某种距离度量找出训练集中与其最接近的k个训练样本,然后基于这k个“邻居”的信息来进行预测.通常,在分类任务中可使用“投票法”,即选择这k个样本中出现最多的类别标记作为预测结果;在回归任务中可使用“平均法”,即将这k个样本的实值输出标记的平均值作为预测结果;还可基于距离远近进行加权平均或加权投票,距离越近的样本权重越大。
它是懒惰学习的著名代表,此类学习技术在训练阶段仅仅是把样本保存下来,训练开销为0,待收到测试样本后再进行处理;相应的,那些在训练阶段就对样本进行学习处理的方法,称为急切学习。
示例:使用k近邻算法改进约会网站的配对效果
背景介绍:
海伦一直使用在线约会网站寻找适合自己的约会对象。尽管约会网站会推荐不同的人选,但她并不是喜欢每个人。经过一番总结,她发现曾交往过三种类型的人:
1、不喜欢的人
2、魅力一般的人
3、极具魅力的人
尽管发现了上述规律,但海伦依然无法将约会网站推荐的匹配对象归入恰当的分类。她觉得可以在周一到周五约会那些魅力一般的人,而周末则更喜欢与那些极具魅力的人为伴。海伦希望我们的分类软件可以更好地帮助她匹配对象划分到确切的分类中。此外海伦还收集了一些约会网站未曾记录的数据信息,她认为这些数据更有助于匹配对象的归类。
分析:题目本质上就是,给出你一定的数据,把人的类给分好。
具体步骤:
收集数据: 点击打开链接
准备数据:使用python解析文本文件
训练算法
测试算法:使用海伦提供的部分数据作为测试样本
使用算法:产生简单的命令行程序,然后海伦可以输入一些特征数据以判断对方是否为自己喜欢的类型。
def file2matrix(filename):
fr=open(filename)
arrayolines=fr.readlines()
numberoflines=len(arrayolines)
returnmat=zeros((numberoflines,3))
classlabelvector=[]
index=0
for line in arrayolines:
line=line.strip()
listfromline=line.split('\t')
returnmat[index,:]=listfromline[0:3]
classlabelvector.append(int(listfromline[-1]))
index +=1
return returnmat,classlabelvector
//用来加载数据的
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)))
return normDataSet,ranges,minVals
//归一化特征值----这个很重要,因为,不同的特征值其值相差太大的话,会直接影响knn算法的正确性
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]
//knn算法
def datingClassTest():
hoRatio=0.10
datingDatamat,datinglabels=file2matrix('F:\\machine-learning\data\datingTestSet2.txt')
normat,ranges,minVals=autoNorm(datingDatamat)
m=normat.shape[0]
numTestVecs=int(m.hoRatio)
errorCount=0.0
for i in range(numTestVecs):
classifierResult=classify0(normat[i,:],normat[numTestVecs:m,:],datinglabels[numTestVecs:m],3)
print "the classifier came back with :%d,the real answer is :%d"%(classifierResult,datinglabels[i])
if(classifierResult!=datinglabels[i]):
errorCount+=1.0
print "the total error" % (errorCount/float(numTestVecs))
//形成分类器
个人总结:
knn算法是个很奇妙的算法,形如这种形式的还有朴素贝叶斯,虽然很简单,思路很容易想,但是却是揭开机器学习度量学习的篇章。依托“相似物”,将机器学习引入距离的学习,这种方式是和基于概率学习(贝叶斯,支持向量机),函数论(回归与神经网络),共同构成了机器学习的基础核心观。-----------------------个人观点。