机械学习算法小结1——knn算法 (K-临近算法)

KNN 概述:

Knn(k-nearestNeighbor)算法是一种基本的分类与回归的方法。是最简单易懂的机械学习算法,没有之一。

概括性的一句话就是:近朱者赤近墨者黑。

knn的应用场景大多在,字符识别,文本分类,以及图像识别当中。

该算法的核心意思即是:一个样本在数据集中于其他的K个样本相似,而其他的样本属于一类,那么这个样本也属于这个类别。

下面我们用实例分析一下:

 

序号

电影名称

搞笑镜头

拥抱镜头

打斗镜头

电影类型

1. 

宝贝当家

45

2

9

喜剧片

2. 

美人鱼

21

17

5

喜剧片

3. 

澳门风云3

54

9

11

喜剧片

4. 

功夫熊猫3

39

0

31

喜剧片

5. 

谍影重重

5

2

57

动作片

6. 

叶问3

3

2

65

动作片

7. 

伦敦陷落

2

3

55

动作片

8. 

我的特工爷爷

6

4

21

动作片

9. 

奔爱

7

46

4

爱情片

10. 

夜孔雀

9

39

8

爱情片

11. 

代理情人

9

38

2

爱情片

12. 

新步步惊心

8

34

17

爱情片

13. 

唐人街探案

23

3

17

我们首先简单的构思一下:上面的13部影片中,其中1-4部中的搞笑镜头占每部戏全部镜头成分的比重较大,所以我们给他们划分到喜剧片的类别;5-8部片中打斗镜头居多,所以我们给划分为动作片;9-12 接吻镜头居多,我们就给分为爱情片。那没第13步呢?我们可以看出,搞笑镜头居多,所以也可以分为喜剧片。

这是我们的一种思维方式的判断,还有另一种方式可以解决我们的问题;

利用欧式距离公式我们来寻找新片所接近的影片类型。

这中间 

这个欧式距离公式可以计算样本数据与所有样本的距离。

例如:x样本就是我们的新片,那么数据就为[23,3,17] 设y为样本中的夜孔雀:[9,39,8,"爱情片"]

则我们计算就是d=(23−9)2+(3−39)2+(17−8)2​    这样我们就能计算出“夜孔雀 ” 和我们所要判断的新片的距离 ,同理将其他数据样本也用公式计算出来,最后 我们分析出距离新片最近的几个影片中,那类的影片概率颇高,我们就能根据这个数据进行判断。  

下面我们来构建代码,理解代码表达我们的算法:

#首先我们需要导入我们需要的库,这里面我们使用numpy库居多。
import numpy as np
#其次,我们需要将我们收集到的数据建立成我们可以使用的数集。
#这里,因为数据量小我们可以手动输入,也可以通过读取数据的函数进行操作。
dian_ying_set = {"宝贝当家": [45, 2, 9, "喜剧片"],  
              "美人鱼": [21, 17, 5, "喜剧片"],  
              "澳门风云3": [54, 9, 11, "喜剧片"],  
              "功夫熊猫3": [39, 0, 31, "喜剧片"],  
              "谍影重重": [5, 2, 57, "动作片"],  
              "叶问3": [3, 2, 65, "动作片"],  
              "伦敦陷落": [2, 3, 55, "动作片"],  
              "我的特工爷爷": [6, 4, 21, "动作片"],  
              "奔爱": [7, 46, 4, "爱情片"],  
              "夜孔雀": [9, 39, 8, "爱情片"],  
              "代理情人": [9, 38, 2, "爱情片"],  

              "新步步惊心": [8, 34, 17, "爱情片"]}      

#由于我们要计算的新片:唐人街探案[23, 3, 17, "?片"]  就可以使用欧式距离公式来计算。欧式距离是一个最简单也是最常用的距离计算公式,
#这其中,我们可以定义三个镜头的数据为参数,求距离新片的距离最近的影片,就可以确定新片的类别了。
x = [23,3,17]
KNN = []
for key, v in dian_ying_set.items():
    d = float(np.sqrt((x[0]- v[0])**2 + (x[1]- v[1])**2 + (x[2]-v[2])**2))
    KNN.append([key,round(d,2)])

print(KNN)

第三步:按照距离大小进行递增排序。

KNN.sort(key=lambda dis:dis[1])

 

第四步:选取距离最小的k个样本。

这里取k=5;

 

KNN = KNN[:5]

 

 

print(KNN)

第五步:确定前k个样本所在类别出现的频率,并输出出现频率最高的类别。

labels = {"喜剧片":0,"动作片":0,"爱情片":0}  
for s in KNN:  
    label = dian_ying_set[s[0]]  
    labels[label[3]] += 1  
labels =sorted(labels.items(),key=lambda l: l[1],reverse=True)  

print(labels,labels[0][0],sep='\n') 

 

 分析KNN的特点:

1.通过上面的例子我们可以发现 KNN 是属于惰性学习的。

这是与急切学习(eager learning)相对应的,因为KNN没有显式的学习过程!也就是说没有训练阶段,从上面的例子就可以看出,数据集事先已有了分类和特征值,待收到新样本后直接进行处理。

2.KNN的计算复杂度较高

我们从上面的例子可以看到,新样本需要与数据集中每个数据进行距离计算,计算复杂度和数据集中的数据数目n成正比,也就是说,KNN的时间复杂度为O(n),因此KNN一般适用于样本数较少的数据集。

3.k取不同值时,分类结果可能会有显著不同。

上例中,如果k取值为k=1,那么分类就是动作片,而不是喜剧片。一般k的取值不超过20,上限是n的开方。

 

 

你可能感兴趣的:(机械学习算法小结1——knn算法 (K-临近算法))