K邻近算法
来源:互联网 发布:js工厂模式 编辑:程序博客网 时间:2024/03/29 23:21
一 、什么是K邻近算法?
K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。该方法的思路是:如果一个样本在特征空间中的k个(一般K是不大于20的整数)最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
例如:有两类不同的样本数据,分别用蓝色的小正方形和红色的小三角形表示,而图正中间的那个绿色的圆所标示的数据则是待分类的数据。也就是说,现在, 我们不知道中间那个绿色的数据是从属于哪一类(蓝色小正方形or红色小三角形),下面,我们就要解决这个问题:给这个绿色的圆分类。
如果K=3,绿色圆点的最近的3个邻居是2个红色小三角形和1个蓝色小正方形,少数从属于多数,基于统计的方法,判定绿色的这个待分类点属于红色的三角形一类。
如果K=5,绿色圆点的最近的5个邻居是2个红色三角形和3个蓝色的正方形,还是少数从属于多数,基于统计的方法,判定绿色的这个待分类点属于蓝色的正方形一类。
工作原理详细解释:一个样本数据集中每个样本都存在标签,也称作训练样本,即我们知道样本集中每一数据与所属分类的对应关系。然后输入没有标签的新数据(测试数据),将新数据的每个特征与样本集中数据对应的特征进行比较,然后用样本集中特征最享受的数据作为新数据的分类标签。
二 、算法的python编程
首先,我们创建名为kNN.py的python模块,代码如下:
# -*- coding: utf-8 -*-from numpy import *import operator def createDataSet():group=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])labels=['A','A','B','B']return group,labelsdef classify0(intX,dataSet,labels,k):dataSetSize=dataSet.shape[0] #计算dataSet行数diffMat=tile(intX,(dataSetSize,1))-dataSet #tile():对intX按(4,1)进行复制,4代表复制4行,1代表列不变sqDiffMat=diffMat**2sqDistances=sqDiffMat.sum(axis=1)#sum(axis=1)按行求和distances=sqDistances**0.5#计算两个点间的距离sortedDistIndicies=distances.argsort()#argsort()按升序排序后取索引值classCount={}for i in range(k):voteIlabel=labels[sortedDistIndicies[i]]classCount[voteIlabel]=classCount.get(voteIlabel,0)+1#统计类别出现的次数{'A': 1, 'B': 2}sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)#将无序的字典迭代为有序的元组后,itemgetter(1)取出元组第二个域,并reverse=True按降序排序return sortedClassCount[0][0]
其中createDataSet()函数是创建数据集和分类标签,classify0()函数是使用K近邻算法将每组数据划分到某个类中,其伪代码为:
1)计算测试数据与各个训练数据之间的距离;
2)按照距离的递增关系进行排序;
3)选取距离最小的K个点;
4)确定前K个点所在类别的出现频率;
5)返回前K个点中出现频率最高的类别作为测试数据的预测分类。
之后,在Python开发环境输入:
import kNN group,labels = kNN.createDataSet() kNN.classify0([0,0],group,lables,3)
便可以得到该样本数据属于B类。
三 、算法的应用
接下来我们通过一个实际的案例来更好的理解K近邻算法:约会网站的配对效果
样本数据集来源于1000行约会数据,主要包含以下三种特征:
(1)每年获得的飞行常客里程数
(2)玩视频游戏所耗时间百分比
(3)每周消费的冰淇淋公升数
首先,在数据添加到分类器前,我们要将数据处理为分类器可以接受的Numpy矩阵形式,输出为训练样本矩阵和类标签向量
def file2matrix(filename):#将分类数据转换为Numpy解析程序,这样便于分类器可接收 fr = open(filename) numberOfLines = len(fr.readlines()) #读取文件,得到行数 returnMat = zeros((numberOfLines,3)) #先创建一个1000行,3列均为0的返回矩阵,用于接下来存放样本矩阵 classLabelVector = [] #准备类标签数组 fr = open(filename) index = 0 for line in fr.readlines(): line = line.strip()#去掉首尾空格 listFromLine = line.split('\t') returnMat[index,:] = listFromLine[0:3]#取样本数据的前3列,存储到返回矩阵中 classLabelVector.append(int(listFromLine[-1]))#存储类标签到数组中
接着,因为样本特征数据的单位不统一,有的很大,有的很小,所以我们要归一化特征值,将所有特征值转化为(0,1)的数据,公式为newValue=(OldValue-min)/(max-min)
def autoNorm(dataSet):#归一化特征值,将所有特征值转化为(0,1)的数据,公式为newValue=(OldValue-min)/(max-min) 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然后,我们从训练集选取10%的样本数据来测试算法的错误率
def datingClassTest():#分类器测试代码,一般选取10%的已知类别的样本数据进行测试 hoRatio = 0.10 #hold out 10% datingDataMat,datingLabels = file2matrix('datingTestSet2.txt') #load data setfrom file normMat, ranges, minVals = autoNorm(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: %d, the real answer is: %d" % (classifierResult, datingLabels[i]) if (classifierResult != datingLabels[i]): errorCount += 1.0 print "the total error rate is: %f" % (errorCount/float(numTestVecs)) print errorCount最后,我们使用算法,构建完整的分类器
def classiyPerson(): # 定义分类结果的类别 resultList = ['not at all','in small doses','in large doses'] # 读取输入数据 percentTats = float(raw_input("percentage of time spent playing video 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('datingTestSet2.txt') # 对数据进行归一化 normMat,ranges,minVals = autoNorm(datingDataMat) # 将单个输入数据定义成一条数据 inArr =array([ffMiles,percentTats,iceCream]) # 对输入数据进行分类 classifierResult = classify0(inArr,datingDataMat,datingLabels,3) # 输出预测的分类类别 print "You will probably like this person:",resultList[classifierResult - 1]分类结果如图所示:
阅读全文
1 0
- k-邻近算法
- K-最邻近算法
- K-邻近算法
- K-邻近算法
- 1、k-邻近算法
- k邻近算法
- k-邻近算法学习
- KNN-K邻近算法
- k-邻近算法
- K邻近算法
- k-邻近算法笔记
- K邻近算法
- K邻近算法
- K邻近算法
- K-邻近算法
- K邻近算法(KNN)
- k邻近算法
- 【数据挖掘】k-邻近算法
- JavaScript实现H5游戏断线自动重连的技术
- [FAQ12506]如何实现壁纸不随着workspace的滑动而滑动
- JSP基础
- 云搜网盘助手域名更换公告
- post请求网站数据爬取!!!Python学习笔记!
- K邻近算法
- 架构探险-JavaWeb之JDBC模板方法抽取
- 编写JSP页面,计算2000~2016年中有几个闰年
- Java 继承
- ORA-12560错误
- Android 集成 FFmpeg (二) 以命令方式调用 FFmpeg
- Redis集群搭建与简单使用
- 算数运算符 比较运算符
- MFC控件工具箱