beginning

  盆友们都喜爱看电影的叭?咱们都喜爱什么体裁的片呢?爱情片、喜剧片仍是动作片?那咱们有没有想过这些体裁自身是怎么定义的呢?也就是说同一体裁的电影有哪些公共特征?动作片中也会存在接吻镜头,爱情片中也会有打架场景,咱们不能单纯依靠是否存在打架或亲吻来判别影片类型。可是爱情片中亲吻镜头更多,动作片中的打架场景也更频繁,所以咱们能够基于此类场景在某部电影中出现的次数,运用K-近邻(KNN)算法构造程序,实现自动区分电影的体裁。说到这你是不是对KNN感兴趣了呢,那就跟我一起看下去叭


1.原理

  kNN 的工作原理\color{blue}{工作原理}是:存在一个数据样本集合,也称为训练样本集,其中每个数据都带有标签,这意味着咱们知道每个数据与其所属分类之间的对应关系。当咱们输入新的未带标签的数据时,算法会将该数据的每个特征与样本会集数据的特征进行比较,并提取与样本会集最相似数据(即最近邻)的分类标签。通常情况下,咱们只考虑样本数据会集前k个最相似的数据,其中k是不大于20的整数,这也是k-近邻算法命名的来历。最终,咱们挑选k个最相似数据中出现次数最多的分类作为新数据的分类。

  咱们现已了解到k-近邻算法的原理,现在让咱们回到之前提到的电影分类的例子中,运用这种算法来区分爱情片和动作片。有人曾经对许多电影的打架镜头和接吻镜头进行了核算,并记载在下表中。假设咱们现在面对一个从未见过的电影,咱们该怎么确认它是归于爱情片仍是动作片呢?咱们能够运用kNN算法来处理这个问题

小白也能一看就懂的KNN算法——原理+实例+代码

  即使不知道不知道电影归于哪种类型,咱们也能够经过某种办法核算出来。首要核算不知道电影与样本会集其他电影的间隔,如下表所示。此处呢咱们暂且先不要关怀怎么核算得到这些间隔值,运用Python实现电影分类应用时,会供给详细的核算办法滴

小白也能一看就懂的KNN算法——原理+实例+代码

  现在咱们得到了样本会集一切电影与不知道电影的间隔,依照间隔递增排序,能够找到k个间隔最近的电影。假定k=3,则三个最靠近的电影顺次是He’s Not Really into Dudes、Beautiful Woman和California Man。k-近邻算法依照间隔最近的三部电影的类型,决定不知道电影的类型,而这三部电影全是爱情片,因此咱们就能够判定不知道电影归于爱情片片啦

2.实例(包括代码)

总结一下kNN算法的一般流程\color{blue}{一般流程}叭:

  1. 搜集数据:能够运用任何的办法
  2. 预备数据:间隔核算所需求的数值,数据格式最好是结构化的
  3. 剖析数据:能够运用任何的办法
  4. 训练算法:此过程不适用于咱们的k-近邻算法
  5. 测验算法:来核算过错率
  6. 运用算法:首要需求输入样本数据和结构化的输出成果,然后运用k-近邻算法对输入数据进行分类判别,并确认其所属类别,最终依据分类成果对数据进行进一步的处理。

2.1预备数据

首要创立kNN.py文件:

from numpy import * # 科学核算包numpy
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,labels

为了方便运用createDataSet()函数,咱们顺次履行以下过程哈:保存kNN.py文件,改动当时途径到存储kNN.py文件的位置,翻开Python开发环境。

进入Python交互式开发环境后,输入下列指令导入上面编辑的程序模块:

 >>>import kNN

导入之后,在Python指令提示符下输入下列指令:

group,labels = kNN.createDataSet()

这一指令创立了变量group和labels,在Python指令提示符下输入变量的姓名以查验是否正确的定义变量:

>>>group
array([[1. , 1.1],
      [1. , 1. ],
      [0. , 0. ],
      [0. , 0.1]])
>>>labels
['A','A','B','B']

这里有4组数据,每组数据有两个咱们已知的特点或者特征值。group矩阵每行包括一个不同的数据,咱们能够把它想象为某个日志文件中不同的测量点或者进口。向量labels包括了每个数据点的标签信息,labels包括的元素数据等于group矩阵行数。这里咱们将数据点(1,1.1)定义为类A,数据点(0,0.1)定义为类B。

小白也能一看就懂的KNN算法——原理+实例+代码

2.2构造KNN分类器

下面运用kNN算法将每组数据区分到某个类中,伪代码\color{blue}{伪代码}如下:

对不知道类别特点的数据会集的每个点顺次履行以下操作:

(1)\color{green}{(1)}核算已知类别数据会集的点与当时点之间的间隔;

(2)\color{green}{(2)}依照间隔递增次第排序;

(3)\color{green}{(3)}选取与当时点间隔最小的k个点;

(4)\color{green}{(4)}确认前k个点地点类别的出现频率;

(5)\color{green}{(5)}返回前k个点出现频率最高的类别作为当时点的猜测分类。

python函数classify()如下所示:

def createDataSet():
      group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
      labels = ['A','A','B','B']
      return group,labels
def classify0(inX, dataSet, labels, k): 
      #用于分类的输入向量inX,输入的训练样本集dataSet,标签向量labels,k表示用于挑选最近街坊的数目
      dataSetSize = dataSet.shape[0]
      diffMat = tile(inX, (dataSetSize,1)) - dataSet #间隔核算,运用欧式间隔公式
      aqDiffMat = diffMat ** 2
      aqDistances = aqDiffMat.sum(axis=1)
      distances = aqDistances ** 0.5
      sortedDistIndicies = distances.argsort()
      classCount = {}
      for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 #挑选间隔最小的k个点
      sortedClassCount = sorted(classCount.items(), #iteritems 用于python2
                   key = operator.itemgetter(1),reverse = True) #排序
      return sortedClassCount[0][0]
  • classify0()函数有四个输入参数:用于分类的输入向量是intX,输入的训练样本集为dataSet,标签向量为labels,k表示用于挑选最近街坊的数目。
  • 运用欧氏间隔\color{blue}{欧氏间隔}核算完一切点之间的间隔后,能够依照从小到大的次第对数据进行排序,然后确认前k个间隔最小元素地点的主要分类,输入的k总是正整数。
  • 最终需求将classCount字典分解为元组列表,然后运用程序第二行导入运算符模块的itemgetter办法,依照第二个元素的次第对元组进行排序。此处咱们运用逆序排序,即依照从最大到最小排序,最终返回出现频率最高的元素标签。

为了猜测地点分类,在Python提示符中输入下列指令:

>>>KNN.classify0([0,0],group,labels,3)
Out: 'B'

咱们能够看到输出的成果是B,也能够改动输入[0,0]为其他值,测验程序的运行成果嗷⛳⛳⛳

2.3测验分类器

  咱们现已经过k-近邻算法构建了一个分类器。此时,盆友们可能会问“该分类器的输出是否总是100%正确?”很惋惜,答案是否定的。分类器不能保证百分之百的准确率。为了评价分类器的性能,咱们能够运用包括已知答案的数据集进行测验。当然,在测验时不能向分类器供给这些答案,而是检查分类器给出的成果是否与预期成果相符。经过大量的测验数据,咱们能够核算出分类器的过错率——即分类器给出过错成果的次数除以测验履行的总数\color{blue}{分类器给出过错成果的次数除以测验履行的总数}。完美分类器的过错率为0,而最差分类器的过错率到达1.0在最差情况下,分类器根本无法找到正确的答案。


ending

关于kNN的讲解介绍就到这里啦,盆友们学废了叭,如果觉得我的共享还不错,please一键三连嗷下期见

小白也能一看就懂的KNN算法——原理+实例+代码