kNN--近邻算法
kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。
在机器学习中常用于分类。
数学内容:
欧氏距离公式,矩阵运算,归一化数值
python模块:
numpy,operator(用其中的itemgetter做排序),listdir(列出目录中的文件),matplotlib.pyplot(可视化数据分析数据),
PIL(对图片进行处理)
from numpy import * import operator from os import listdir def createDataSet(): groups=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]]) lables=['A','A','B','B'] return groups,lables #k-近邻算法 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 #按距离递增排列,返回样本集中的index sortedDistances=distances.argsort() classCount={} for i in range(k): #根据距离递增的顺序,获取与其对应的类别(即目标变量) voteIlabel=labels[sortedDistances[i]] #为k个元素所在的分类计数 classCount[voteIlabel]=classCount.get(voteIlabel,0)+1 #通过对比每个类别出现的次数(即classCount value),以递减的顺序排序 sortedCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True) #返回计数最大的那个类别的值 return sortedCount[0][0] #准备数据 def file2matrix(filename): fr=open(filename) arrayOLines=fr.readlines() #获取文件行数 numberOflines=len(arrayOLines) #创建一个以文件行数为行,3列的矩阵 returnMatrix=zeros((numberOflines,3)) #定义一个存放目标变量(类别)的数组 classLabelVector=[] index=0 #遍历文件 for line in arrayOLines: line=line.strip() listFromLine=line.split(' ') #把文件前三列添加到返回的矩阵中 returnMatrix[index:]=listFromLine[0:3] #文件最后一列(对应的类别)添加到类别数组中 classLabelVector.append(int(listFromLine[-1])) index+=1 #返回数据特征矩阵和类别数组 return returnMatrix,classLabelVector #通过公式 "newValue=(oldValue-min)/(max-min)" 将任意取值范围的特征值转化为0到1区间内的值 def autoNorm(dataset): #返回每列的最小值 minVals=dataset.min(0) #返回每列的最大值 maxVals=dataset.max(0) #返回最大值与最小值的差 ranges=maxVals-minVals #创建与dataset同行同列的0矩阵 normDataset=zeros(shape(dataset)) #返回dataset的行数 m=dataset.shape[0] #创建一个重复m次的minVals矩阵,并与dataset相减 normDataset=dataset-tile(minVals,(m,1)) #newValue=(oldValue-min)/(max-min) normDataset=normDataset/tile(ranges,(m,1)) return normDataset,ranges,minVals #测试算法 def datingClassTest(): #设定测试数据比例 hoRatio=0.10 #返回格式化后的数据和其标签 datingDataMat,datingLabels=file2matrix('datingTestSet2.txt') #归一化数据值 normMat,ranges,minVals=autoNorm(datingDataMat) #数据的行数 m=normMat.shape[0] #测试数据的行数 numTestVecs=int(m*hoRatio) #设置错误预测计数器 errorCount=0.0 #向k-近邻算法中传numTestVecs个测试数据,并把返回的预测数据与真实数据比较返回,若错误,计数器加1 for i in range(numTestVecs): """ 调用k-近邻算法,为其传入参数, normMat[i]:第i个测试数据, normMat[numTestVecs:m,:]:从numTestVecs到m个样本数据,(m可以不写,相当于从numTestVecs索引开始,取剩下所有的normMat数据) datingLabels[numTestVecs:m]:从numTestVecs到m个样本数据对应的标签 3:k的值 """ classifierResult=classify0(normMat[i],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3) #判断预测数据与真实数据,如果是错误的,则以红字体输出,并错误预测计数器加1 if (classifierResult!=datingLabels[i]): print("