精华内容
下载资源
问答
  • k临近算法
    2016-04-05 19:33:00

    K临近算法原理

    K临近算法(K-Nearest Neighbor, KNN)是最简单的监督学习分类算法之一。(有之一吗?)

    对于一个应用样本点,K临近算法寻找距它最近的k个训练样本点即K个Nearest Neighbor。

    若在K个邻居中属于某一类别的最多,则认为应用样本点也属于该类别。

    KNN算法Python实现

    KNN算法无需训练,很容易实现。

    from numpy import *
    import operator
    
    class KNNClassifier():
    
      def __init__(self):
          self.dataSet = []
          self.labels = []
    
      def loadDataSet(self,filename):
          fr = open(filename)
          for line in fr.readlines():
              lineArr = line.strip().split()
              dataLine = list()
              for i in lineArr:
                  dataLine.append(float(i))
              label = dataLine.pop() # pop the last column referring to  label
              self.dataSet.append(dataLine)
              self.labels.append(int(label))
    
      def setDataSet(self, dataSet, labels):
          self.dataSet = dataSet
          self.labels = labels
    
      def classify(self, data, k):
          self.dataSet = array(self.dataSet)
          self.labels = array(self.labels)
          self._normDataSet()
          dataSetSize = self.dataSet.shape[0]
          # get distance
          diffMat = tile(data, (dataSetSize,1)) - self.dataSet
          sqDiffMat = diffMat**2
          distances = sqDiffMat.sum(axis=1)
          # get K nearest neighbors
          sortedDistIndicies = distances.argsort()
          classCount= {}
          for i in range(k):
              voteIlabel = self.labels[sortedDistIndicies[i]]
              classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
          # get fittest label
          sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
          return sortedClassCount[0][0]
    
      def _normDataSet(self):
          minVals = self.dataSet.min(0)
          maxVals = self.dataSet.max(0)
          ranges = maxVals - minVals
          normDataSet = zeros(shape(self.dataSet))
          m = self.dataSet.shape[0]
          normDataSet = self.dataSet - tile(minVals, (m,1))
          normDataSet = normDataSet/tile(ranges, (m,1))   #element wise divide
          self.dataSet = normDataSet
    
      def test(self):
          self.dataSet = array([[1.0,1.1],[1.0,1.0],[0.9,0.9],[0,0],[0,0.1],[0,0.2]])
          self.labels = [1,1,1,2,2,2]
          print(self.classify([1.0,1.1], 2))
    
    if __name__ == '__main__':
      KNN = KNNClassifier()
      KNN.loadDataSet('testData.txt')
      print(KNN.classify([72011, 4.932976, 0.632026], 5) )
      # KNN.test()
    更多相关内容
  • K临近算法的一个简单示例,明了易懂,并添加了极其详细的中文注解,即使完全不会编程,也能理解。
  • KNN算法改进约会网站配对效果;KNN实现手写数字识别
  • K近邻(KNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。 所谓K最近邻,就是K个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。KNN算法的核心思想是如果一个样本在特征...

    K近邻(KNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。 所谓K最近邻,就是K个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。KNN算法的核心思想是如果一个样本在特征空间中的K个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特征。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。KNN方法在类别决策时,只与极少数的相邻样本有关。由于kNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或者重叠较多的待分样本集来说,kNN方法较其他方法更为适合。

    KNN算法描述:

    (1):计算测试数据与各个训练数据之间的距离

    (2):按照距离的递增关系进行排序

    (3):选取距离最小的K个点

    (4):确定前K个点所在类别的出现频率

    (5):返回前K个点中出现频率最高的类别作为测试数据的预测分类

    K临近算法优缺点:

    优点:
    • 简单,易于理解,易于实现,无需参数估计,无需训练
    • 对异常值不敏感(个别噪音数据对结果的影响不是很大)
    • 适合对稀有事件进行分类
    • 适合于多分类问题(multi-modal,对象具有多个类别标签),KNN要比SVM表现好
    缺点:
    • 对测试样本分类时的计算量大,内存开销大,因为对每个待分类的文本都要计算它到全体已知样本的距离,才能求得它的K个最近邻点,目前常用的解决方法是对已知的样本点进行剪辑,事先要去除对分类作用不大的样本
    • 可解析性差,无法告诉你哪个变量更重要,无法给出决策树那样的规则
    • k值的选择:最大的缺点是当样本不平衡时,如一个类的样本容量很大,而其他样本容量很小时候,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。该算法只计算“最近的”邻居样本,某一类的样本数量很大的时候,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。无论如何,数量并不影响运行结果,可以采用权值的方法(和该样本距离小的邻居权重大)来改进
    • KNN是一种消极学习方法,懒惰算法

    K临近算法实战–电影分类:

    在这里插入图片描述
    我们从散点图大致推断,这个红色圆点标记的电影可能属于动作片,因为距离已知的那两个动作片的圆点更近,那么k-近邻算法用什么方法进行判断呢?没错,就是距离度量,这个电影分类的例子有两个特征,也就是二维实数向量空间,可以使用我们学过的两点距离公式计算距离(欧式距离),如下图:
    在这里插入图片描述

    Python代码实现:

    1,使用Python导入数据

    from numpy import *
    import operator
    def creataDataSet():
    	group = array([[1,101],[5,89],[108,5],[115,8]])
    	labels = ['A','A','B','B']       #labels中   A代表爱情片  B代表动作片
    	return group,labels
    
    if __name__ == '__main__':
    	group,labels = creataDataSet()
    	print(group)
    	print(labels)
    	
    	测试输出结果如下:
    	[[  1 101]
    	[  5  89]
    	[108   5]
    	[115   8]]
    	['A', 'A', 'B', 'B']
    

    2,使用k-近邻算法解析数据

    import numpy as np
    def classify0(inX,dataSet,labels,k):    
    	dataSetSize = dataSet.shape[0]           # shape读取数据矩阵第一维度的长度
    
    	diffMat = np.tile(inX,(dataSetSize,1)) - dataSet      # tile重复数组inX,有dataSet行 1个dataSet列,减法计算差值
    
    	sqDiffMat = diffMat ** 2         # 进行幂运算
    
    	sqDistances = sqDiffMat.sum(axis=1)     # 普通sum默认参数为axis=0为普通相加,axis=1为一行的行向量相加
    	
    	distances = sqDistances ** 0.5            #开方得欧氏距离
    
    	sortedDistIndicies = distances.argsort()           # argsort返回数值从小到大的索引值(数组索引0,1,2,3)
    
    	classCount = {}
    	for i in range(k):             # 选择距离最小的k个点
        	voteLabel = labels[sortedDistIndicies[i]]         # 根据排序结果的索引值返回靠近的前k个标签        
        	classCount[voteLabel] = classCount.get(voteLabel,0) +1          # 统计各个标签出现频率
    
    
    	sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)             # reverse默认升序,此时按逆序, key关键字排序itemgetter(1)按第一个域的值排序,即频数
                            
    return sortedClassCount[0][0]
    

    classify0()函数有4个输入参数:用于分类的输入向量是inX,输入的训练样本集为dataSet,标签向量为labels,最后的参数k表示用于选择最近邻居的数目,其中标签向量的元素数目和矩阵dataSet的行数相同,上面程式使用欧式距离公式。

    计算完所有点之间的距离后,可以对数据按照从小到大的次序排序。然后,确定前k个距离最小元素所在的主要分类,输入k总是正整数;最后,将classCount字典分解为元组列表,然后使用程序第二行导入运算符模块的itemgetter方法,按照第二个元素的次序对元组进行排序。此处的排序是逆序,即按照从最大到最小次序排序,最后返回发生频率最高的元素标签。

    3,进行预测

    if __name__ == '__main__':
    	group,labels = creataDataSet()
    	knn = classify0([101,20],group,labels,3)
    	print(knn)
    	结果:
    	B
    

    K临近算法实战进阶—约会网站匹配

    James一直使用在线约会网站寻找适合自己的约会对象。尽管约会网站会推荐不同的人选,但是他从来没有选中喜欢的人,经过一番总结,他发现曾交往过三种类型的人:

    • 不喜欢的人
    • 魅力一般的人
    • 极具魅力的人
    1.在约会网站上使用k-近邻算法流程

    (1)收集数据:提供文本文件

    (2)准备数据:使用Python解析文本文件

    (3)分析数据:使用Matplotlib画二维扩散图

    (4)训练算法:此步骤不适用于k-近邻算法

    (5)测试算法:使用James提供的部分数据作为测试样本

    测试样本和非测试样本的区别在于:测试样本是已经完成分类的数据,如果预测分类与实际类别不同,则标记为一个错误。

    (6)使用算法:产生简单的命令程序,然后James可以输入一些特征数据以判断对方是否为自己喜欢的类型。

    1,准备数据:从文本文件中解析数据

    James收集的数据有一段时间了,她将这些数据放在文本文件datingTestSet.txt中,每个样本数据占据一行,总共有1000行,James的样本主要包括以下三种特征:

    • 每年获得的飞行常客里程数
    • 玩视频游戏所消耗时间百分比
    • 每周消费的冰淇淋公升数

    在将数据特征数据输入到分类器之前,必须将待处理数据的格式改变为分类器可以接受的格式,我们首先处理输入格式问题,该函数的输入问文件名字符串,输出为训练样本矩阵和类标签向量。

    将文本记录到转换Numpy的解析程序代码如下:

    def file2Matrix(filename):
    	fr = open(filename)
    	arrayOLines = fr.readlines()
    	numberOfLines = len(arrayOLines)      #得到文件行数
    	returnMat = zeros((numberOfLines,3))    #创建返回的numpy矩阵
    	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          #返回样本矩阵和标签
    
    2,分析数据:使用Matplotlib创建散点图
    import matplotlib.pyplot as plt
    from pylab import mpl
    from matplotlib.font_manager import FontProperties 
    import numpy as np
    
    if __name__ == '__main__':
    filename = 'datingTestSet.txt'
    datingDataMat,datingLabels = file2Matrix(filename)
    mpl.rcParams['font.sans-serif'] = ['FangSong']    # 指定默认字体
    
    mpl.rcParams['axes.unicode_minus'] = False   # 解决保存图像是负号- 显示为方块的问题
    fig = plt.figure()
    ax = fig.add_subplot(111)     #画布分成一行一列,第一个位置
    
    zhfont = FontProperties(fname='C:/Windows/Fonts/simsun.ttc',size=12)
    datingLabels = np.array(datingLabels)
    idx_1 = np.where(datingLabels==1)
    p1 = ax.scatter(datingDataMat[idx_1,0],datingDataMat[idx_1,1],marker = '*',color = 'r',label='1',s=10)
    idx_2 = np.where(datingLabels==2)
    p2 = ax.scatter(datingDataMat[idx_2,0],datingDataMat[idx_2,1],marker = 'o',color ='g',label='2',s=20)
    idx_3 = np.where(datingLabels==3)
    p3 = ax.scatter(datingDataMat[idx_3,0],datingDataMat[idx_3,1],marker = '+',color ='b',label='3',s=30)
    
    plt.xlabel(u'每年获取的飞行里程数', fontproperties=zhfont)
    plt.ylabel(u'玩视频游戏所消耗的事件百分比', fontproperties=zhfont)
    ax.legend((p1, p2, p3), (u'不喜欢', u'魅力一般', u'极具魅力'), loc=2, prop=zhfont)
    plt.show()
    

    在这里插入图片描述

    3,归一化数值

    表给出了提取的四组数据,如果想要计算样本3和样本4之间的距离,可以使用下面的方法:
    在这里插入图片描述
    计算公式:
    在这里插入图片描述
    我们很容易发现,上面方程中数字差值最大的属性对计算结果的影响最大,也就是说,每年获取的飞行常客里程数对于计算结果的影响远远大于下标中其他两个特征——玩视频游戏的和每周消费冰淇淋公升数的影响。而产生这种现象的唯一原因仅仅是飞行常客里程数远大于其他特征数值。但是James认为这三种特征是同等重要的,因此作为三个等权重的特征之一,飞行常客里程数并不应该如此严重的影响到计算结果

    在处理这种不同取值范围的特征值时,我们通常采用的方法是将数值归一化,如将取值范围处理为0到1或者-1到1之间。下面的公式可以将任意取值范围的特征值转化到0到1区间内的值:

    newValue = (oldValue - min)/(max-min)
    

    其中min和max分别是数据集中的最小特征值和最大特征值。虽然改变数值取值范围增加了分类器的复杂度,但是为了得到准确结果,我们必须这样做,所以我们新增一个函数autoNorm() ,该函数可以自动将数字特征转化为0到1的区间。

    归一化特征值代码如下:

    # 归一化特征值
    #归一化公式 : (当前值 - 最小值) / range
    def autoNorm(dataSet):
    
    	minVals = dataSet.min(0)    # 存放每列最小值,参数0使得可以从列中选取最小值,而不是当前行   
    	maxVals = dataSet.max(0)    # 存放每列最大值
    	
    	ranges = maxVals - minVals
    	normDataSet = zeros(shape(dataSet))         # 初始化归一化矩阵为读取的dataSet
    	m = dataSet.shape[0]             # 保留第一行
    	normDataSet = dataSet - tile(minVals , (m,1))         # 因此采用tile将变量内容复制成输入矩阵同大小
    	normDataSet = normDataSet/tile(ranges,(m,1))          # 特征值相除,特征矩阵是3*1000 min  max range是1*3
    	return normDataSet,ranges,minVals
    
    4,测试算法

    上面我们已经将数据按照需求做了处理,本节我们将测试分类器的效果,如果分类器的正确率满足要求,James就可以使用这个软件来处理约会网站提供的约会名单了。机器学习算法一个很重要的工作就是评估算法的正确率,通常我们只提供已有数据的90%作为训练样本来训练分类器,而使用其余的10%数据来测试分类器,检测分类器的正确率。值得注意的是,10%的测试数据应该是随机选择的,由于James提供的数据并没有按照特定目的来排序,所以我们可以随意选择10%数据而不影响其随机性。

    为了测试分类器效果,我们创建了datingClassTest,该函数时自包含的,代码如下:
    分类器针对约会网站的测试代码:

    # 分类器针对约会网站的测试代码
    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
    	for i in range(numTestVecs):
        	classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],
        datingLabels[numTestVecs:m],3)
        	print('the classifier came back with:%d,the read answer is :%d '
        %(classifierResult,datingLabels[i]))
        	if (classifierResult != datingLabels[i]):
            	errorCount +=1.0
    	print("the total error rate is :%f"%(errorCount/float(numTestVecs)))
    	测试结果:
    	the total error rate is :0.050000
    

    分类器处理越活数据集的错误率是5%,这是一个相当不错的结果

    使用算法

    上面我们已经在数据上对分类器进行了测试,现在我们可以使用这个分类器为James来对人们分类,我们会给James给一小段程序,通过该程序会在约会网站上找到某个人并输入他的信息,程序会给出他对对方喜欢程序的预测值。

    约会网站预测函数代码:

    约会网站预测函数	
    def classifyPerson():
    	resultList = ['not at all','in small','in large doses']
    	percentTats = float(input("percentage of time spent playing video games ?"))
    	ffMiles = float(input("frequent flier miles earned per year?"))
        iceCream = float(input("liters od ice cream consumed per year?"))
    	dataingDataMat,datingLabels = file2Matrix('datingTestSet2.txt')
    	normMat,ranges,minVals = autoNorm(datingDataMat)
    	inArr = array([ffMiles,percentTats,iceCream])
    	classifierResult = classify0((inArr-minVals)/ranges,normMat,datingLabels,3)
    	print("You will probably like this person ",resultList[classifierResult-1])
    

    测试结果如下:

    if __name__ == '__main__':
    # datingClassTest()
    	filename = 'datingTestSet2.txt'
    	datingDataMat,datingLabels = file2Matrix(filename)
    	classifyPerson()
    
    '''
    percentage of time spent playing video games ?10
    frequent flier miles earned per year?10000
    liters od ice cream consumed per year?0.5
    You will probably like this person  in small
    '''
    
    展开全文
  • K临近算法检测异常操作(一)

    千次阅读 2021-11-23 21:03:36
    K近邻(K-Nearest Neighbor,KNN)算法是机器学习领域使用最广 泛的算法之一,所谓KNN,就是K个最近的邻居的意思,说的是每个样 本都可以用它最接近的K个邻居来代表。KNN算法的核心思想是:如果 一个样本在特征空间...

    概述

    K近邻(K-Nearest Neighbor,KNN)算法是机器学习领域使用最广 泛的算法之一,所谓KNN,就是K个最近的邻居的意思,说的是每个样 本都可以用它最接近的K个邻居来代表。KNN算法的核心思想是:如果 一个样本在特征空间中的K个最相邻的样本中的大多数属于某一个类 别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策时,只依据最邻近的一个或者 几个样本的类别来决定待分样本所属的类别。KNN方法在类别决策时, 只与极少量的相邻样本有关。由于KNN方法主要靠周围有限的邻近的样 本,而不是靠判别类域的方法来确定所属类别,因此对于类域交叉或重 叠较多的待分样本集来说,KNN方法较其他方法更为适合。

    数据来源

    Schonlau在他的个人网站:http://www.schonlau.net/上发布了训练数据。
    在这里插入图片描述
    训练数据中包括50个用户的操作日志(见图5-4),每个日志包含 15000条操作命令,其中前5000条都是正常操作,后面的10000条日志中 随机包含有异常操作。为了便于分析,数据集每100条操作作为一个操 作序列,同时进行了标注,每个操作序列只要有1条操作异常就认为这个操作序列异常。
    其中以用户名作为文件名,每个用户的操作都记录在对应的文件里 面。每个文件中,按照操作顺序依次记录了操作命令。

    代码及注释

    import numpy as np
    from nltk.probability import FreqDist
    from sklearn.neighbors import KNeighborsClassifier
    from sklearn.metrics import classification_report
    from sklearn import metrics
    
    #测试样本数
    N=100
    
    def load_user_cmd(filename):
        cmd_list=[]
        dist=[]
        dist_max=[]
        dist_min=[]
    #依次读取每行操作命令,每100个命令组成一个操作序列,保存在列表里面:
        with open(filename) as f:
            i=0
            x=[]
            for line in f:
                line=line.strip('\n')
                x.append(line)
                dist.append(line)
                i+=1
                if i == 100:
                    cmd_list.append(x)
                    x=[]
                    i=0
    #统计最频繁使用的前50个命令和最不频繁的前50个命令:
        fdist = FreqDist(dist).keys()
        dist_max=set(list(fdist)[0:50])
        dist_min = set(list(fdist)[-50:])
        return cmd_list,dist_max,dist_min
    #特征化
    def get_user_cmd_feature(user_cmd_list,dist_max,dist_min):
        user_cmd_feature=[]
        for cmd_block in user_cmd_list:
    #去重操作命令的个数。
    #以100个命令为统计单元,作为一个操作序列,去重后的操作命令个数作为特征。
            f1=len(set(cmd_block))
            fdist = FreqDist(cmd_block).keys()
    #最频繁使用的前10个操作
            f2=list(fdist)[0:10]
    #最不常使用的前10个操作
            f3=list(fdist)[-10:]
    #统计的最频繁使用的前50个命令以及最不频繁使用的前50 个命令计算重合程度
            f2 = len(set(f2) & set(dist_max))
            f3=len(set(f3)&set(dist_min))
            x=[f1,f2,f3]
            user_cmd_feature.append(x)
        return user_cmd_feature
    #标识文件的内容:每行50列,分别代表每个用户的当前操作序列, 正常操作标识为0,异常操作标识为1。
    def get_label(filename,index=0):
        x=[]
        with open(filename) as f:
            for line in f:
                line=line.strip('\n')
                x.append( int(line.split()[index]))
        return x
    
    if __name__ == '__main__':
        user_cmd_list,user_cmd_dist_max,user_cmd_dist_min=load_user_cmd("data/MasqueradeDat/User3")
    #加载user3的操作数据,并将前120个操作序列作为训练序列,后30 个操作序列作为测试序列。  
     	user_cmd_feature=get_user_cmd_feature(user_cmd_list,user_cmd_dist_max,user_cmd_dist_min)
        
        labels=get_label("data/MasqueradeDat/label.txt",2)
        y=[0]*50+labels
    
        x_train=user_cmd_feature[0:N]
        y_train=y[0:N]
    
        x_test=user_cmd_feature[N:150]
        y_test=y[N:150]
    
        neigh = KNeighborsClassifier(n_neighbors=3)
        neigh.fit(x_train, y_train)
        y_predict=neigh.predict(x_test)
    
        score=np.mean(y_test==y_predict)*100
    
        #print y
        #print y_train
        print(y_test)
        print(y_predict)
        print(score)
    
        print(classification_report(y_test, y_predict))
    
        print(metrics.confusion_matrix(y_test, y_predict))
    
    展开全文
  • k近邻,k近邻算法,matlab

    2021-09-10 17:44:55
    K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。
  • 【机器学习】实验一 K临近算法

    千次阅读 2021-10-05 10:46:51
    K临近算法 1.什么是K临近算法? 所谓K近邻算法,即是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例(也就是上面所说的K个邻居), 这K个实例的多数属于某个类,就把该输入实例...

    K临近算法

    1.什么是K临近算法?

    所谓K近邻算法,即是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例(也就是上面所说的K个邻居), 这K个实例的多数属于某个类,就把该输入实例分类到这个类中。

    2.算法实例

    在这里插入图片描述
    有两类不同的样本数据,分别用蓝色的小正方形和红色的小三角形表示,而图正中间的那个绿色的圆所标示的数据则是待分类的数据。我们要做的是给绿色的小圆分类。

    如果K=3,绿色圆点的最近的3个邻居是2个红色小三角形和1个蓝色小正方形,少数从属于多数,基于统计的方法,判定绿色的这个待分类点属于红色的三角形一类。
    如果K=5,绿色圆点的最近的5个邻居是2个红色三角形和3个蓝色的正方形,还是少数从属于多数,基于统计的方法,判定绿色的这个待分类点属于蓝色的正方形一类。

    当无法判定当前待分类点是从属于已知分类中的哪一类时,我们可以依据统计学的理论看它所处的位置特征,衡量它周围邻居的权重,而把它归为(或分配)到权重更大的那一类。这就是K近邻算法的核心思想。

    3.算法特点

    KNN 算法本身简单有效,分类器不需要使用训练集进行训练,训练时间复杂度为0。KNN 分类的计算复杂度和训练集中的文档数目成正比,也就是说,如果训练集中文档总数为 n,那么 KNN 的分类时间复杂度为O(n)。KNN方法虽然从原理上也依赖于极限定理,但在类别决策时,只与极少量的相邻样本有关。由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。

    4.算法流程

    首先计算出已知类别的数据集当中所有点与当前点的距离
    然后按照距离的大小按递增次序排列
    之后选取与当前点距离最小的n个点
    确定出那n个点所在类别出现的频率
    最后返回n个点出现频率最高的类别作为当前点的预测分类

    5.测试算法实现手写体识别

    书中的k-临近算法,classify()函数有四个输入参数:用于分类的输入向量inX,输入的训练样本集为dataSet,标签向量为labele,最后的参数k表示用于选择最近邻居的数目,其中标签向量的元素数目和矩阵dataSet的行数相同。代码使用欧式距离公式来计算两个向量点之间的距离,计算完成之后对数据按照从小到大的次序排列。然后确定前k个距离最小元素所在额主要分类,将classCount字典分解为元组列表,然后使用程序第二行导入运算符模块的itemgetter方法,按照第二个元素的次序对元组进行逆序排列,最后返回发生频率最高的标签。

    #书中的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={}	#创建一个用于存储前k个点和对应类别的字典
        for i in range(k):
            voteIlabel = labels[sortedDistIndicies[i]]	#依次取得前k个点对应的分类
            classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1	#使用get函数取得上一步中得到分类的已有得分数,若无则取0,并将结果+1保存至classCount字典内
        sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)	#对结果进行排序
        return sortedClassCount[0][0]	#返回结果
    
    

    书中的转换函数,创建一个1*1024的NumPy数组,然后打开给定的文件,循环读出文件的前32行,并将每行的头32个字符值储存在NumPy数据中,最后返回数组

    #书中的测试函数
    def img2vector(filename):
        returnVect = zeros((1,1024))	#新建并初始化一个初值赋0的矩阵
        fr = open(filename)		#打开传入文件
        for i in range(32):
            lineStr = fr.readline()		#读取文本文件
            for j in range(32):
                returnVect[0,32*i+j] = int(lineStr[j])		#将32*32的矩阵依次赋值给1*1024的矩阵
        return returnVect 	#返回结果
    

    书中给出的数字识别系统测试代码,错误率在1.2%。改变k的值或者修改函数handwriting-classTest随机选取训练样本或者改变训练样本的数目,都会使得k-临近算法的错误率产生变化。实际使用过程中算法的执行效率不高,原因是需要为每个测试向量做2000次距离计算,每个距离计算包括了1024个维度浮点运算,总计要执行900次。

    #书中的测试代码
    def handwritingClassTest():
        hwLabels = []	#设定用于存储的列表
        trainingFileList = listdir('trainingDigits')	#读取样本集 
        m = len(trainingFileList)	
        trainingMat = zeros((m,1024))	
        for i in range(m):
            fileNameStr = trainingFileList[i]	#读取一个样本
            fileStr = fileNameStr.split('.')[0]		
            classNumStr = int(fileStr.split('_')[0])	
            hwLabels.append(classNumStr)	#将类别并入
            trainingMat[i,:] = img2vector('trainingDigits/%s' % fileNameStr)	#将32*32转换为1*1024
        testFileList = listdir('testDigits')	#读取测试集
        errorCount = 0.0	#初始化错误率
        mTest = len(testFileList)	#读取测试集长度
        for i in range(mTest):
            fileNameStr = testFileList[i]	#读取一个测试样本
            fileStr = fileNameStr.split('.')[0]		
            classNumStr = int(fileStr.split('_')[0])	
            vectorUnderTest = img2vector('testDigits/%s' %fileNameStr)	#将32*32转换为1*1024
            classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)		#将转化后的结果丢入kNN分类器
            print ('the classifier came back with: %d, the real answer is: %d' %(classifierResult, classNumStr))	#输出分类结果
            if (classifierResult != classNumStr): errorCount += 1.0		#将错误的结果记录
        print ('\nthe total number of errors is: %d' %errorCount)	#输入总错误数
        print ('\nthe total error rate is: %f' %(errorCount/float(mTest)))	#输入错误率
    

    上述的函数和代码用于实现手写数字识别,
    所作的操作是首先将样本集依次读入,并依其所属的数字分类将他们进行格式转换。完成格式转换后再依次读入测试数据,然后使用kNN分类算法来得出预测值,并与真实值进行比较,最后将不符合的错误结果进行记录,从而得出最终的错误率。
    k-临近算法是分类数据最简单有效的算法,是基于实例的学习,在使用算法时必须有接近实际数据的训练样本数据,k-临近算法必须保存全部数据集,如果训练数据集很大,必须使用大量的存储空间,此外必须最数据集中每个数据进行距离计算,可能会很耗时间。k-临近算法的另一个缺点是无法给出任何数据的基础结构信息,我们也就无法知晓平均实例样本和典型实例样本有什么特征了。

    展开全文
  • K-means算法和K临近算法

    千次阅读 2017-02-28 17:16:28
    设定k个质心 repeat 遍历所有元素,选择最近的质心为一个簇 重新计算每个簇的质心 until 簇稳定不再变化或者到达最大迭代次数 实践复杂度为O(tkn),t为迭代次数,k为质心个数
  • 数据挖掘K临近算法

    2014-07-06 07:44:31
    数据仓库与数据挖掘课程作业K临近算法。很简单的代码容易修改。
  • Scikit-learn K临近算法

    2018-05-28 20:57:32
    K近邻算法是一种基本的分类与回归的方法。 简单来讲,这个算法就是遵循近朱者赤近墨者黑...这个算法是没有显示的学习过程,只是利用了训练集的特征向量空间进行划分,其实这个就是K临近算法的模型了。 对于这个K临...
  • #生成sin散点数据,然后加上扰动,用k临近回归去预测 #进行回归时,找到临近的k个样本,采用普通的算术平均算法或考虑距离差异的加权平均等输出 from sklearn.neighbors import KNeighborsRegressor import ...
  • K邻近算法

    2022-06-08 16:51:59
    K邻近算法是一种常用的分类或回归算法K邻近算法的思想非常简单:对于分类问题,k邻近算法从所有训练集中找到与x样本相邻的k个样本,然后通过投票选择这k个样本中出现类型最多的类别作为x的预测结果;对于回归问题...
  • K临近算法-KNN

    2018-10-27 18:19:26
    K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个...
  • k-近邻算法实例及数据集,包含测试集和训练集,代码中knn.py为主体代码,test.py为画散点图详细代码,example_1为test.py生产的散点图
  • K临近算法学习笔记

    2022-09-15 22:07:33
    K临近算法学习笔记
  • knn算法也叫K临近算法 简单举个例子,如上图所示,坐标轴内随机分布这红色和绿色两种属性的图形,现在新加入了一个点,怎么来判断这个点可能是红色还是绿色呢? 我们取一个值K1=1,发现在离新加入这个点最近的K1...
  • 通俗易懂之k临近算法

    2021-03-24 10:02:46
    k近邻法(k-nearest neighbor, k-NN)是1967年由Cover T和Hart P提出的一种基本分类与回归方法。...举个简单的例子,我们可以使用k-近邻算法分类一个电影是爱情片还是动作片。 距离度量: 我们已经知道k-近邻算
  • 主要介绍了Python实现KNN(K-近邻)算法的示例代码,它主要用于对事物进行分类。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • KNN模型分类:K近邻算法的主要思想是用离测试集数据点最近的训练集点(称为其邻居)的输出来估计测试集数据点的输出,参数K代表用多少个邻居来估计。超参数K通常设置为奇数来防止平局现象。其中对邻居的判定:我们可以...
  • 用make_blobs函数生成类似聚类数据,然后用k临近去预测 import matplotlib.pyplot as plt import numpy as np from sklearn.datasets.samples_generator import make_blobs from sklearn.neighbors import ...
  • from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=123)
  • 机器学习之K临近算法

    2019-07-24 22:01:42
    什么是K临近算法,其实可以根据字面上了解,若我现在有一堆点,根据它们的特征我把它们分成若干类,现在再加入一个点,求出这个点是属于哪一个类,我们可以取K个点,然后我们再计算所有点到这个点的欧式距离或者某...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,810
精华内容 3,924
关键字:

k临近算法