KNN(K近邻)算法的简单入门
2017-04-18 23:05
447 查看
机器学习实战(第二章:k-近邻算法)
今天学习了第二章,在此就我理解做一下简单的总结,算是加深我的理解和用我自己的语言描述出这个算法吧。距离计算
基于向量空间的欧几里得距离的计算。(L2距离)特别情况下可采用Lp距离(明氏距离) L1距离。
简单点来说就是 在一个具有大量样本集中,每一个实例都具有3个或以上的特征属性,其中有一个属性必然是分类属性,其余属性为数值型属性(即使是标称型属性,也可以通过 某些方法转变过来),每一个实例都是由属性特征值组成的一个向量,一个样本集就是多个向量组成。
例如下面这个例子
身高 | 体重 | 年龄 | 性别 |
170 | 140 | 22 | 男 |
160 | 100 | 21 | 女 |
一、算法步骤:
1、计算已知类别数据集中的点与当前点之间的距离;
2、按照距离递增次序排序;
3、选取与当前点距离最小的k个点;
4、确定k个点所在类别的出现频率;
(K用于选择最近邻的数目,K的选择非常敏感。K值越小意味着模型复杂度越高,从而容易产生过拟合;K值越大则 意味着整体的模型变得简单,学习的近似误差会增大,在实际的应用中,一般采用一个比较小的K值,用交叉验证的 方法,选取一个最优的K值。)
5、返回前k个点出现频率最高的类别作为当前点的预测分类
二、例子说明(python)
首先按照算法编写一个knn算法类'''
inX:用于分类的输入向量
dataSet:训练样本集
labels:标签向量
k:用于选择最近邻的数目
'''
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()
#按从小到大的排序后的索引值
#选择距离最小的k个点
classCount = {}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0)+1
#排序
sortedClassCount = sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
return sortedClassCount[0][0]
举一个实例说明(手写识别数据)数据说明:
我们需要把每一个样本数据转变成向量的格式,由于图片是32X32的txt文本格式存在,我们转变成1X1024的向量,并把所有的训练样本保存为一个矩阵,对应的每一行就是每一个实例。
#把一个32X32的变成1X1024的向量 def img2vector(filename): returnVec = zeros((1,1024)) fr = open(filename) for i in range(32): lineStr = fr.readline() for j in range(32): returnVec[0,32*i+j] = int(lineStr[j]) return returnVec
运用我们事先写好的knn算法类,按照格式代进去训练并且计算错误率。
def handwritingClassTest(): hwLabels = [] #获取训练集 trainingFileList = os.listdir('digits//trainingDigits') #获取该目录下所有文件名 类型:list m = len(trainingFileList) trainingMat = zeros((m,1024)) for i in range(m): fileNameStr = trainingFileList[i] #7_173.txt fileStr = fileNameStr.split('.')[0] #'7_173' 'txt' classNumStr = int(fileStr.split('_')[0]) #7 173 hwLabels.append(classNumStr) trainingMat[i,:] = img2vector("digits//trainingDigits//"+fileNameStr) #获取测试集 testFileList = os.listdir("digits//testDigits") errorCount = 0 mTest = len(testFileList) for i in range(mTest): fileNameStr = testFileList[i] fileStr = fileNameStr.split('.')[0] # '7_173' 'txt' classNumStr = int(fileStr.split('_')[0]) # 7 173 vectorUnderTest = img2vector("digits//testDigits//"+fileNameStr) classifierResult = classify0(vectorUnderTest,trainingMat,hwLabels,3) print("the classifier came back with: %d,the real answer is: %d"%(classifierResult,classNumStr)) if classifierResult != classNumStr: errorCount += 1 print "the total number of errors is:%d" %errorCount print "the total error rate is:%f" %(errorCount/float(mTest))
总结:
优点1.精度高
2.对异常值不敏感
3.没有对数据的分布假设
缺点
1、knn算法不像其他算法有一个训练的过程
2、knn算法针对那些分类不均匀的分类训练样本可能误差较大
3、计算量太大,每一个待测测试样本都要遍历一遍训练样本来计算距离
4、我们无法知晓实例样本和典型实例样本具有什么特征,无法给出任何数据的基础结构信息
相关文章推荐
- 《机器学习实战》第二章:k-近邻算法(1)简单KNN
- python机器学习——KNN算法简单入门(真的很简单!)
- k-近邻算法(KNN)--1简单原理介绍与实践---by香蕉麦乐迪
- 【KNN近邻算法】实现识别简单数字验证码(算法原理+代码笔记)
- 《机器学习实战》学习笔记——K-近邻算法(KNN)(一)分类器的简单实现
- 机器学习实战--最简单算法--KNN算法(k-近邻算法)
- 机器学习--k-近邻(kNN)算法
- KNN(K近邻)算法
- 简单易学的机器学习算法——k-近邻算法
- (留存记录)近邻分类算法KNN
- 一、K -近邻算法(KNN:k-Nearest Neighbors)
- kNN算法python实现和简单数字识别的方法
- CV最简单的分类算法——knn(k nearest neighbors)
- 《机器学习实战》k-近邻算法概述-程序清单详解kNN.py(未完待续)
- 监督学习_最近邻算法(KNN, k-近邻算法)
- 菜鸟学算法--简单的交换和最大公约数算法入门篇
- 机器学习经典算法详解及Python实现--K近邻(KNN)算法
- 【模式识别】K-近邻分类算法KNN
- k近邻分类算法(kNN)
- K近邻(KNN):分类算法