机器学习算法系列(1):K近邻

一、K近邻算法

K近邻算法简单、直观。首先给出一张图,根据这张图来理解最近邻分类器。

根据上图所示,有两类不同的样本数据,分别用蓝色的小正方形和红色的小三角形表示,而图正中间的那个绿色的圆所标示的数据则是待分类的数据。也就是说,现在,我们不知道中间那个绿色的数据是从属于哪一类(蓝色小正方形或者红色小三角形),下面,我们就要解决这个问题:给这个绿色的圆分类。

我们常说,物以类聚,人以群分,判别一个人是一个什么样的人,常常可以从他身边的朋友入手,所谓观其友,而识其人。我们不是要判别上图中那个绿色的圆是属于那一类数据么,好说,从他的另据下手。但一次性看多少个邻居呢?从上图中,你还可以看到:

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

于此,我们看到,KNN算法为给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例,这K个实例的多数属于某个类,就把该输入实例分为这个类。

K近邻法算法步骤如下:

输入:训练数据集$T={(x_1,y_1),(x_2,y_2),···,(x_N,y_N)}$,其中,$x_i$是实例的特征向量,$y_i$是实例的类别;新实例的特征向量$x$

输出:新实例$x$所属的类别$y$

  • 1)根据给定的距离度量,在训练集$T$中找出与$x$最邻近的$k$个点,涵盖这k个点的$x$领域记作$N_k(x)$;
  • 2)在$N_k(x)$中根据分类决策规则(如多数表决)决定$x$的类别$y$:

其中$I$为指示函数,即当$y_i=c_i$时为1,否则为0.

二、K近邻模型

2.1 模型

k近邻法中,当训练集、距离度量、K值以及分类决策规则确定后,对于任何一个新的输入实例,它所属的类唯一地确定。这相当于根据上述要素将特征空间划分为一些子空间,确定子空间里的每个点所属的类。

2.2 距离度量

特征空间中两个实例点的距离可以反映出两个实力点之间的相似性程度。K近邻模型的特征空间一般是N维实数向量空间,使用的距离可以是欧式距离,也可以是其他距离。

  • 欧氏距离:最常见的两点之间或多点之间的距离表示法,又称之为欧几里得度量,它定义于欧几里得空间中
  • 曼哈顿距离:我们可以定义曼哈顿距离的正式意义为$L1$距离或城市区块距离,也就是在欧几里得空间的固定直角坐标系上两点所形成的线段对轴产生的投射的距离总和。

    通俗来讲,想想你在曼哈顿要从一个十字路口开车到另一个十字路口,驾驶距离是两点间的直线距离吗?显然不是,除非你能穿越大楼。而实际驾驶距离就是这个“曼哈顿距离”,此即曼哈顿距离名称的来源,同时,曼哈顿距离也称为城市街区距离。

  • 切比雪夫距离:
  • 闵可夫斯基距离:它不是一种距离,而是一组距离的定义。

    当p=1时,即曼哈顿距离
    当p=2时,即欧式距离
    当$prightarrow infty$,即切比雪夫距离

  • 标准化欧氏距离:对样本集先进行标准化$
    hat{x}_i=frac{x_i-bar{x}}{s}$经过简单的推导就可以得到来标准化欧氏距离。
  • 夹角余弦:几何中夹角余弦可用来衡量两个向量方向的相似度,机器学习中借用这一概念来衡量向量之间的相似度。

2.3 K值的选择

K值得选择会对K近邻法的结果产生重大影响。

如果选择较小的K值,就相当于用较小的领域中的训练实例进行预测,“学习”近似误差会减小,只有与输入实例较近或相似的训练实例才会对预测结果起作用,与此同时带来的问题是“学习”的估计误差会增大,换句话说,K值得减小就意味着整体模型变得复杂,容易发生过拟合(容易受到训练数据的噪声而产生的过拟合的影响)。

如果选择较大的K值,就相当于用较大领域中的训练实例进行预测,其优点是可以减小学习的估计误差,但缺点是学习的近似误差会增大。这时候,与输入实例较远的训练实例也会对预测器作用,使预测发生错误,且K值得增大就意味着整体的模型变得简单。

如果K=N。那么无论输入实例是什么,都将简单地预测它属于在训练实例中最多的类。这时,模型过于简单,完全忽略训练实例中的大量有用信息,是不可取的(最近邻列表中可能包含远离其近邻的数据点),如下图所示。

在实际应用中,K值一般取一个比较小的数值。通常采用交叉验证法来选取最优的K值(经验规则:K一般低于训练样本数的平方根)。

2.4 分类决策规则

K近邻法中的分类决策规则往往是多数表决,即由输入实例的K个邻近的训练实例中的多数类决定输入实例的类。

三、K近邻的优缺点

3.1 优点

  • 简单、易于理解、易于实现、无需估计参数、无需训练。
  • 适合对稀有事件进行分类(如大概流式率很低时,比如0.5%,构造流失预测模型);
  • 特别适合多酚类问题,如根据基因特征来判断其功能分类,KNN比SVM的表现要好。

3.2 缺点

  • 懒惰算法,对测试样本分类时的计算量大,内存开销大,评分慢。
  • 可解释性较差,无法给出决策树那样的规则。
  • 当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。
  • KNN是一种懒惰算法,平时不好好学习,考试(对测试样本分类)时才临阵磨枪(临时去找K个近邻),懒惰的后果,构造模型很简单,但在测试样本分类地系统开销大,因为要扫描全部训练样本并计算距离。已经有一些方法提高计算的效率,例如压缩训练样本量。
  • 决策树和基于规则的分类器都是积极学习eager learner的例子,因为一旦训练数据可用,它们就开始学习从输入属性到类标号的映射模型。一个相反的策略是推迟对训练数据的建模,直到需要分类测试样例时再进行。采用这种策略的技术被称为消极学习法lazy learner。最近邻分类器就是这样的一种方法。

四、python代码实现

4.1 K-近邻算法简单示例

KNN算法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

# coding=utf-8

"""

Created on Feb 22  2017

KNN

@author: plushunter

"""

# coding=utf-8

from numpy import *

import operator

class ():

def __init__(self,k=3):

self._k=k

def _calDistance(self,inputX,trainX):

dataSetSize=trainX.shape[0]

# tile for array and repeat for matrix in Python

diffMat=tile(inputX,(dataSetSize,1))-trainX

大专栏  机器学习算法系列(1):K近邻lass="line">        sqDiffMat=diffMat**2

# take the sum of difference from all dimensions,axis=0是按列求和,axis=1 是按行求和

sqDistances=sqDiffMat.sum(axis=1)

distances=sqDistances**0.5

# argsort returns the indices that would sort an array.argsort函数返回的是数组值从小到大的索引值

# http://www.cnblogs.com/100thMountain/p/4719503.html

# find the k nearest neighbours

sortedDistIndicies = distances.argsort()

return sortedDistIndicies

def _classify(self,sample,trainX,trainY):

if isinstance(sample,ndarray) and isinstance(trainX,ndarray) and isinstance(trainY,ndarray):

pass

else:

try:

sample=array(sample)

trainX=array(trainX)

trainY=array(trainY)

except:

raise TypeError("numpy.ndarray required for trainX and ..")

sortedDistIndicies=self._calDistance(sample,trainX)

classCount={}#create the dictionary

for i in range(self._k):

label=trainY[sortedDistIndicies[i]]

classCount[label]=classCount.get(label,0)+1

#get(label,0) : if dictionary 'classCount' exist key 'label', return classCount[label]; else return 0

sorteditem=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)

#operator.itemgetter(1) can be substituted by 'key = lambda x: x[1]'

return sorteditem[0][0]

def classify(self,inputX,trainX,trainY):

if isinstance(inputX,ndarray) and isinstance(trainX,ndarray) 

and isinstance(trainY,ndarray):

pass

else:

try:

inputX = array(inputX)

trainX = array(trainX)

trainY = array(trainY)

except:

raise TypeError("numpy.ndarray required for trainX and ..")

d = len(shape(inputX))

results=[]

if d == 1:

result = self._classify(inputX,trainX,trainY)

results.append(result)

else:

for i in range(len(inputX)):

result = self._classify(inputX[i],trainX,trainY)

results.append(result)

return results

if __name__=="__main__":

trainX = [[1,1.1],

[1,1],

[0,0],

[0,0.1]]

trainY = ['A','A','B','B']

clf=KNNClassifier(k=3)

inputX = [[0,0.1],[0,0]]

result = clf.classify(inputX,trainX,trainY)

print result

#output which type these belongs to

/Users/HuaZhang/anaconda2/bin/python /Users/HuaZhang/Desktop/GitHub/machine-lerning/KNN/KNN.py

['B', 'B']

Process finished with exit code 0

4.2 KNN实现手写识别系统

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

# coding=utf-8

"""

Created on Mar 22  2017

KNN: Hand Writing

@author: plushunter

"""

from numpy import *

import operator

from os import listdir

import KNN

def img2vector(filename):

returnVect = zeros((1, 1024))

fr = open(filename)

for i in range(32):

lineStr = fr.readline()

# n = len(lineStr)

# if not n:

#     continue

for j in range(32):

returnVect[0, 32 * i + j] = int(lineStr[j])

return returnVect

def loadDataSet(filedir):

FileList = listdir(filedir)

m = len(FileList)

X = zeros((m,1024))

Y = []

for i in range(m):

fileNameStr = FileList[i]

classNumStr = int(fileNameStr.split('_')[0])

Y.append(classNumStr)

X[i, :] = img2vector(filedir + "/" + fileNameStr)

return X,Y

def handWritingClassTest(inputX,inputY,trainX,trainY):

cls=KNN.KNNClassifier(k=3)

error=0.0

result = cls.classify(inputX,trainX,trainY)

for i in range(len(result)):

if result[i] != inputY[i]:

error+=1

precision_rate =1- error /len(inputY)

print precision_rate

# return errorRate

def main():

trainDir = "digits/trainingDigits"

testDir = "digits/testDigits"

trainX,trainY = loadDataSet(trainDir)

inputX,inputY = loadDataSet(testDir)

handWritingClassTest(inputX,inputY,trainX,trainY)

if __name__=="__main__":

main()

#output precision_rate

/Users/HuaZhang/anaconda2/bin/python /Users/HuaZhang/Desktop/GitHub/machine-lerning/KNN/HandWriting.py

0.988372093023

Process finished with exit code 0

原文地址:https://www.cnblogs.com/liuzhongrong/p/12262837.html

时间: 2024-11-07 23:13:48

机器学习算法系列(1):K近邻的相关文章

机器学习算法( 二、K - 近邻算法)

一.概述 k-近邻算法采用测量不同特征值之间的距离方法进行分类. 工作原理:首先有一个样本数据集合(训练样本集),并且样本数据集合中每条数据都存在标签(分类),即我们知道样本数据中每一条数据与所属分类的对应关系,输入没有标签的数据之后,将新数据的每个特征与样本集的数据对应的特征进行比较(欧式距离运算),然后算出新数据与样本集中特征最相似(最近邻)的数据的分类标签,一般我们选择样本数据集中前k个最相似的数据,然后再从k个数据集中选出出现分类最多的分类作为新数据的分类. 二.优缺点 优点:精度高.对

机器学习之KNN(k近邻)算法

1.算法介绍k近邻算法是学习机器学习的入门算法,可实现分类与回归,属于监督学习的一种.算法的工作原理是:输入一个训练数据集,训练数据集包括特征空间的点和点的类别,可以是二分类或是多分类.预测时,输入没有类别的点,找到k个与该点距离最接近的点,使用多数表决的方法,得出最后的预测分类. 2.算法优缺点优点:没有高深的数学思想,容易理解,精度高,对异常值不敏感,无数据输入假定:缺点:计算复杂度高,空间复杂度高:理解:因为knn算法是寻找与目标点接近的点,在计算时,异常值与目标点的"距离"会较

机器学习小记——KNN(K近邻) ^_^ (一)

为了让绝大多数人都可以看懂,所以我就用简单的话语来讲解机器学习每一个算法 第一次写ML的博文,所以可能会有些地方出错,欢迎各位大佬提出意见或错误 祝大家开心进步每一天- 博文代码全部为python 简单的说一下什么是机器学习,机器学习英文名称是Machine Learning, ML 机器学习(Machine Learning, ML)是一门多领域交叉学科,涉及概率论.统计学.逼近论.凸分析.算法复杂度理论等多门学科.专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有

机器学习之路: python k近邻分类器 鸢尾花分类预测

使用python语言 学习k近邻分类器的api 欢迎来到我的git查看源代码: https://github.com/linyi0604/kaggle 1 from sklearn.datasets import load_iris 2 from sklearn.cross_validation import train_test_split 3 from sklearn.preprocessing import StandardScaler 4 from sklearn.neighbors i

K近邻算法小结

什么是K近邻? K近邻一种非参数学习的算法,可以用在分类问题上,也可以用在回归问题上. 什么是非参数学习? 一般而言,机器学习算法都有相应的参数要学习,比如线性回归模型中的权重参数和偏置参数,SVM的C和gamma参数,而这些参数的学习又依赖一定的学习策略.相比较而言,k近邻算法可以说是最简单,也是最容易理解的一种机器学习算法了. K近邻算法思想? 具体而言,在一个待测试样本周围找K个最近的点,然后根据这k个点进行决策,如果是分类问题,决策结果就是K个点中出现最多的类别:如果是回归问题,结果值为

02-16 k近邻算法

[TOC] 更新.更全的<机器学习>的更新网站,更有python.go.数据结构与算法.爬虫.人工智能教学等着你:https://www.cnblogs.com/nickchen121/ k近邻算法 k近邻算法(k-nearest neighbors,KNN)是一种基本的分类和回归方法,本文只探讨分类问题中的k近邻算法,回归问题通常是得出最近的$k$个实例的标记值,然后取这$k$实例标记值的平均数或中位数. k近邻算法经常被人们应用于生活当中,比如傅玄曾说过"近朱者赤近墨者黑&quo

更快找到正确的机器学习算法

(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:机器学习无疑是现在一个高大上的热点,而且微软在Azure提供了机器学习的服务.那么如何更快找到正确的机器学习算法呢?微软也给大家提供了建议. 随着大数据的深入应用,机器学习也从学术界逐步走入到工业界,现在电子商务.社交.广告.智能硬件都有机器学习的身影.微软作为一家有着深厚科研实力的公司,不仅在Azure中提供了机器学习的服务供大家选用,还提供了一个名为Azure Machine Learni

机器学习---算法---K-近邻算法

转自:https://www.cnblogs.com/Rosanna/p/3615507.html K-近邻和最近邻(K=1)是模式识别中常用的分类方法,K-近邻算法思想是找到与当前样本相邻的K个有标签样本,然后通过投票决定此样本的类别.例如下图中如何分类未知的绿色圆圈呢? 例如我们可以取K=3个临近的样本时,通过投票(红色两个大于蓝色一个),从而将绿色圆圈归于红色三角一类. 一.基于实例的学习 K-近邻和局部加权回归就是基于实例的学习.基于实例的学习过程只是简单的存储已知的训练数据,当遇到新的

机器学习经典算法详解及Python实现--K近邻(KNN)算法

(一)KNN依然是一种监督学习算法 KNN(K Nearest Neighbors,K近邻 )算法是机器学习所有算法中理论最简单,最好理解的.KNN是一种基于实例的学习,通过计算新数据与训练数据特征值之间的距离,然后选取K(K>=1)个距离最近的邻居进行分类判断(投票法)或者回归.如果K=1,那么新数据被简单分配给其近邻的类.KNN算法算是监督学习还是无监督学习呢?首先来看一下监督学习和无监督学习的定义.对于监督学习,数据都有明确的label(分类针对离散分布,回归针对连续分布),根据机器学习产