机器学习实战笔记(二):K邻近算法

来源:互联网 发布:网络是把双刃剑英语 编辑:程序博客网 时间:2024/04/30 03:49
<span style="font-size:12px;">from numpy import *import operatordef classify0(inX,dataSet,labels,k):   #inX:用于分类的输入向量;dataSet:输入的训练样本集;labels:标签向量(labels的数目与dataSet行数相同);k:选择的最近邻居的数目 dataSetSize=dataSet.shape[0]                   #dataSet.shape[0]:读取dataSet矩阵第一维度的长度diffMat=tile(inX,(dataSetSize,1))-dataSet     #tile():重复某个数组,这里(dataSetSize,1),是一个元组让inX这个数组重复dataSetSize个变为一个矩阵  分别减去dataSet的sqDiffMat=diffMat**2sqDistances=sqDiffMat.sum(axis=1)                                   #sum(axis=1)将矩阵的每一行向量相加distances=sqDistances**0.5                                             #计算距离sortedDistIndicies=distances.argsort()                                  #argsort()返回数组中从小到大的索引值,确定前k个距离的元素所在的分类classCount={}for i in range(k):voteIlabel=labels[sortedDistIndicies[i]]            #输入k总是正整数,sorted()产生一个新的列表,存放前k个距离元素的分类 放到vootellabel中classCount[voteIlabel]=classCount.get(voteIlabel,0)+1#在classCount字典中存放这个分类数组,再查看字典中是否有相同的分类,没有返回0,有就返回那个类+1sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)return sortedClassCount[0][0]                   #将classCount分解为元组列表,按照第二个元素(即元素的类出现的次数)从大到小排列,返回频率最高的元素标签def creatDataSet():group=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])                  labels=['A','A','B','B']return group,labels                                                       #第一个例子,导入group元组和labels列表,并测试def file2matrix(filename):                                                   #第二个例子,约会分类器,有一个参数:需要导入的文件名fr=open(filename)                                                       #打开文件,保存在fr中arrayOLine=fr.readlines()                       #.readlines()读去整个文件,并自动将文件内容分析成一个行的列表,该列表可以由 Python 的 for... in ... 结构进行处理numberOfLines=len(arrayOLine)returnMat=zeros((numberOfLines,3))         #创建一个numberOfLine*3的0矩阵,保存在returnMat中,3是因为要配合样本的大小classLabelVector=[]index=0for line in arrayOLine:line=line.strip()                                                     #使用strip()街去掉所有的回车字符listFromLine=line.split('\t')                                       #使用tab字符将上一步得到的数据分割行,成为一个元素列表returnMat[index,:]=listFromLine[0:3]                           #取该行前三个元素,储存在特征矩阵(训练样本)中classLabelVector.append(listFromLine[-1])                      #取改行标签数据存入标签矩阵index+=1return returnMat,classLabelVector                                    #返回训练样本矩阵和标签矩阵def autoNurm(dataSet):                                                      #数据归一化,公式:newvalue=(oldvalue-min)/(max-min)minVals=dataSet.min(0)                                                #获得每列最小值maxVals=dataSet.max(0)                                               #获得每列最大值ranges=maxVals-minVals                                               #获得每列特征的取值范围normDataSet=zeros(shape(dataSet))                                   #构建形同dataSet的0矩阵m=dataSet.shape[0]                                                     #读取dataSet矩阵第一维度的长度normDataSet=dataSet-tile(minVals,(m,1))                           #构建一个重复m次的由每行最小值重复形成的数组,用dataSet,即每行数据对应相减normDataSet=normDataSet/tile(ranges,(m,1))                      #构建一个重复m次的由每行最大最小值之差重复形成的数组,对应相除,得到归一化后的数组return normDataSet,ranges,minVals                                   #返回归一化后的数组,每行最大最小值之差形成的数组,每行最小值形成的数组def datingClassTest():hoRatio=0.10datingDataMat,datingLabels=file2matrix('datingTestSet2.txt')normMat,ranges,minVals=autoNurm(datingDataMat)m=normMat.shape[0]numTestVecs=int(m*hoRatio)                                         #设置测试个数errorCount=0.0                                                           #计算错误数量for i in range(numTestVecs):classifierResult=classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)print "the classifier came back with: %s,the real answer is: %s" % (classifierResult,datingLabels[i])if (classifierResult!=datingLabels[i]):errorCount+=1.0                                 #计算错误率print "the total error rate is %f" % (errorCount/float(numTestVecs))print errorCountdef classifyPerson():resultList=['not at all','in small doses','in large doses']percentTats=float(raw_input("percentage of time spent playing vadio games?"))ffMiles=float(raw_input("frequent flier miles earned per year?"))iceCream=float(raw_input("liters of ice cream consumed per year?"))datingDataMat,datingLabels=file2matrix('datingTestSet.txt')normMat,ranges,minVals=autoNurm(datingDataMat)inArr=array([ffMiles,percentTats,iceCream])</span>

1.优点:精度高,对异常值不敏感,无数据输入假定

  缺点:计算复杂度和空间复杂度高

  适用数据类型:数值型和标称型

2.工作原理:存在一个样本数据集合,也称训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与对应所属分类的关系。输入没有标签的新数据后,将新数据的每个特征与样本集中的数据的对应特征进行比较,算法提取出样本集中特征最相似(最邻近)的数据的分类标签,一般取前K个最相似数据(K<=20)

3.算法中所需要的计算公式:

   1>向量点之间的距离:(多维向量以此类推)

   2>归一化数据:(可将任意取值范围的数据转化为0-1区间内的值)

0 1
原创粉丝点击