(一)KNN依旧是一种监督学习算法

KNN(K Nearest Neighbors,K近邻 )算法是机器学习全部算法中理论最简单。最好理解的。KNN是一种基于实例的学习,通过计算新数据与训练数据特征值之间的距离,然后选取K(K>=1)个距离近期的邻居进行分类推断(投票法)或者回归。假设K=1。那么新数据被简单分配给其近邻的类。KNN算法算是监督学习还是无监督学习呢?首先来看一下监督学习和无监督学习的定义。对于监督学习。数据都有明白的label(分类针对离散分布,回归针对连续分布),依据机器学习产生的模型能够将新数据分到一个明白的类或得到一个预測值。对于非监督学习,数据没有label。机器学习出的模型是从数据中提取出来的pattern(提取决定性特征或者聚类等)。比如聚类是机器依据学习得到的模型来推断新数据“更像”哪些原数据集合。KNN算法用于分类时,每一个训练数据都有明白的label。也能够明白的推断出新数据的label,KNN用于回归时也会依据邻居的值预測出一个明白的值,因此KNN属于监督学习。

KNN算法的过程为:

  1. 选择一种距离计算方式, 通过数据全部的特征计算新数据与已知类别数据集中的数据点的距离
  1. 依照距离递增次序进行排序。选取与当前距离最小的k个点
  1. 对于离散分类,返回k个点出现频率最多的类别作预測分类;对于回归则返回k个点的加权值作为预測值

(二)KNN算法关键

KNN算法的理论和过程就是那么简单,为了使其获得更好的学习效果,有以下几个须要注意的地方。

1、数据的全部特征都要做可比較的量化。

若是数据特征中存在非数值的类型,必须採取手段将其量化为数值。

举个样例。若样本特征中包括颜色(红黑蓝)一项,颜色之间是没有距离可言的,可通过将颜色转换为灰度值来实现距离计算。

另外,样本有多个參数,每个參数都有自己的定义域和取值范围,他们对distance计算的影响也就不一样。如取值较大的影响力会盖过取值较小的參数。为了公平,样本參数必须做一些scale处理,最简单的方式就是全部特征的数值都採取归一化处置。

2、须要一个distance函数以计算两个样本之间的距离。

距离的定义有非常多。如欧氏距离、余弦距离、汉明距离、曼哈顿距离等等,关于相似性度量的方法可參考‘漫谈:机器学习中距离和相似性度量方法’。普通情况下,选欧氏距离作为距离度量,可是这是仅仅适用于连续变量。

在文本分类这样的非连续变量情况下,汉明距离能够用来作为度量。通常情况下。假设运用一些特殊的算法来计算度量的话,K近邻分类精度可显著提高,如运用大边缘近期邻法或者近邻成分分析法。

3,确定K的值

K是一个自己定义的常数,K的值也直接影响最后的预计,一种选择K值得方法是使用 cross-validate(交叉验证)误差统计选择法交叉验证的概念之前提过,就是数据样本的一部分作为训练样本,一部分作为測试样本。比方选择95%作为训练样本,剩下的用作測试样本。

通过训练数据训练一个机器学习模型,然后利用測试数据測试其误差率。 cross-validate(交叉验证)误差统计选择法就是比較不同K值时的交叉验证平均误差率。选择误差率最小的那个K值。

比如选择K=1,2,3,... ,   对每一个K=i做100次交叉验证。计算出平均误差。然后比較、选出最小的那个

(三)KNN分类

训练样本是多维特征空间向量,当中每一个训练样本带有一个类别标签(喜欢或者不喜欢、保留或者删除)。分类算法常採用“多数表决”决定,即k个邻居中出现次数最多的那个类作为预測类。“多数表决”分类的一个缺点是出现频率较多的样本将会主导測试点的预測结果。那是由于他们比較大可能出如今測试点的K邻域而測试点的属性又是通过K领域内的样本计算出来的。解决这个缺点的方法之中的一个是在进行分类时将K个邻居到測试点的距离考虑进去。比如,若样本到測试点距离为d,则选1/d为该邻居的权重(也就是得到了该邻居所属类的权重),接下来统计统计k个邻居全部类标签的权重和,值最大的那个就是新数据点的预測类标签。

举例,K=5,计算出新数据点到近期的五个邻居的举例是(1,3,3,4,5),五个邻居的类标签是(yes,no,no。yes,no)

若是依照多数表决法,则新数据点类别为no(3个no,2个yes);若考虑距离权重类别则为yes(no:2/3+1/5,yes:1+1/4)。

以下的Python程序是採用KNN算法的实例(计算欧氏距离。多数表决法决断):一个是採用KNN算法改进约会站点配对效果。还有一个是採用KNN算法进行手写识别。

约会站点配对效果改进的样例是依据男子的每年的飞行里程、视频游戏时间比和每周冰激凌耗量三个特征来推断其是否是海伦姑娘喜欢的类型(类别为非常喜欢、一般和讨厌),决策採用多数表决法。

因为三个特征的取值范围不同,这里採用的scale策略为归一化。

使用KNN分类器的手写识别系统 仅仅能识别数字0到9。

须要识别的数字使用图形处理软件,处理成具有同样的色 彩和大小 :宽髙是32像素X32像素的黑白图像。虽然採用文本格式存储图像不能有效地利用内存空间,为了方便理解,这里已经将将图像转换为文本格式。训练数据中每一个数字大概有200个样本。程序中将图像样本格式化处理为向量,即一个把一个32x32的二进制图像矩阵转换为一个1x1024的向量。

from numpy import *
import operator
from os import listdir
import matplotlib
import matplotlib.pyplot as plt
import pdb def classify0(inX, dataSet, labels, k=3):
#pdb.set_trace()
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() #ascend sorted,
#return the index of unsorted, that is to choose the least 3 item
classCount={}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1# a dict with label as key and occurrence number as value
sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
'''descend sorted according to value, '''
return sortedClassCount[0][0] def file2matrix(filename):
fr = open(filename)
#pdb.set_trace()
L = fr.readlines()
numberOfLines = len(L) #get the number of lines in the file
returnMat = zeros((numberOfLines,3)) #prepare matrix to return
classLabelVector = [] #prepare labels return
index = 0
for line in L:
line = line.strip()
listFromLine = line.split('\t')
returnMat[index,:] = listFromLine[0:3]
classLabelVector.append(int(listFromLine[-1]))
#classLabelVector.append((listFromLine[-1]))
index += 1
fr.close()
return returnMat,classLabelVector def plotscattter():
datingDataMat,datingLabels = file2matrix('datingTestSet2.txt') #load data setfrom file
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = fig.add_subplot(111)
ax3 = fig.add_subplot(111)
ax1.scatter(datingDataMat[:,0],datingDataMat[:,1],15.0*array(datingLabels),15.0*array(datingLabels))
#ax2.scatter(datingDataMat[:,0],datingDataMat[:,2],15.0*array(datingLabels),15.0*array(datingLabels))
#ax2.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*array(datingLabels),15.0*array(datingLabels))
plt.show() def autoNorm(dataSet):
minVals = dataSet.min(0)
maxVals = dataSet.max(0)
ranges = maxVals - minVals
normDataSet = zeros(shape(dataSet))
m = dataSet.shape[0]
normDataSet = dataSet - tile(minVals, (m,1))
normDataSet = normDataSet/tile(ranges, (m,1)) #element wise divide
return normDataSet, ranges, minVals def datingClassTest(hoRatio = 0.20):
#hold out 10%
datingDataMat,datingLabels = file2matrix('datingTestSet2.txt') #load data setfrom file
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 real answer is: %d" % (classifierResult, datingLabels[i])
if (classifierResult != datingLabels[i]): errorCount += 1.0
print "the total error rate is: %.2f%%" % (100*errorCount/float(numTestVecs))
print 'testcount is %s, errorCount is %s' %(numTestVecs,errorCount) def classifyPerson():
'''
input a person , decide like or not, then update the DB
'''
resultlist = ['not at all','little doses','large doses']
percentTats = float(raw_input('input the person\' percentage of time playing video games:'))
ffMiles = float(raw_input('flier miles in a year:'))
iceCream = float(raw_input('amount of iceCream consumed per year:'))
datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')
normMat, ranges, minVals = autoNorm(datingDataMat)
normPerson = (array([ffMiles,percentTats,iceCream])-minVals)/ranges
result = classify0(normPerson, normMat, datingLabels, 3)
print 'you will probably like this guy in:', resultlist[result -1] #update the datingTestSet
print 'update dating DB'
tmp = '\t'.join([repr(ffMiles),repr(percentTats),repr(iceCream),repr(result)])+'\n' with open('datingTestSet2.txt','a') as fr:
fr.write(tmp) def img2file(filename):
#vector = zeros(1,1024)
with open(filename) as fr:
L=fr.readlines()
vector =[int(L[i][j]) for i in range(32) for j in range(32)]
return array(vector,dtype = float) def handwritingClassTest():
hwLabels = []
trainingFileList = listdir('trainingDigits') #load the training set
m = len(trainingFileList)
trainingMat = zeros((m,1024))
for i in range(m):
fileNameStr = trainingFileList[i]
fileStr = fileNameStr.split('.')[0] #take off .txt
classNumStr = int(fileStr.split('_')[0])
hwLabels.append(classNumStr)
trainingMat[i,:] = img2vector('trainingDigits/%s' % fileNameStr)
testFileList = listdir('testDigits') #iterate through the test set
errorCount = 0.0
mTest = len(testFileList)
for i in range(mTest):
fileNameStr = testFileList[i]
fileStr = fileNameStr.split('.')[0] #take off .txt
classNumStr = int(fileStr.split('_')[0])
vectorUnderTest = img2vector('testDigits/%s' % 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.0
print "\nthe total number of errors is: %d" % errorCount
print "\nthe total error rate is: %f" % (errorCount/float(mTest)) if __name__ == '__main__':
datingClassTest()
#handwritingClassTest()

KNN算法学习包下载地址为:

Machine Learning K近邻算法

(四)KNN回归

数据点的类别标签是连续值时应用KNN算法就是回归。与KNN分类算法过程同样。差别在于对K个邻居的处理上。KNN回归是取K个邻居类标签值得加权作为新数据点的预測值。加权方法有:K个近邻的属性值的平均值(最差)、1/d为权重(有效的衡量邻居的权重。使较近邻居的权重比較远邻居的权重大)、高斯函数(或者其它适当的减函数)计算权重= gaussian(distance) (距离越远得到的值就越小,加权得到更为准确的预计。

(五)总结

K-近邻算法是分类数据最简单最有效的算法,其学习基于实例,使用算法时我们必须有接近实际数据的训练样本数据。K-近邻算法必须保存所有数据集,假设训练数据集的非常大,必须使用大量的存储空间。此外,因为必须对数据集中的每一个数据计算距离值,实际使用时可能非常耗时。

k-近邻算法的还有一个缺陷是它无法给出不论什么数据的基础结构信息,因此我们也无法知晓平均实例样本和典型实例样本具有什么特征。

本文作者Adan,来源于:机器学习经典算法具体解释及Python实现--K近邻(KNN)算法。转载请注明出处。

机器学习经典算法具体解释及Python实现--K近邻(KNN)算法的更多相关文章

  1. 机器学习-K近邻(KNN)算法详解

    一.KNN算法描述   KNN(K Near Neighbor):找到k个最近的邻居,即每个样本都可以用它最接近的这k个邻居中所占数量最多的类别来代表.KNN算法属于有监督学习方式的分类算法,所谓K近 ...

  2. 机器学习经典算法具体解释及Python实现--线性回归(Linear Regression)算法

    (一)认识回归 回归是统计学中最有力的工具之中的一个. 机器学习监督学习算法分为分类算法和回归算法两种,事实上就是依据类别标签分布类型为离散型.连续性而定义的. 顾名思义.分类算法用于离散型分布预測, ...

  3. 机器学习 Python实践-K近邻算法

    机器学习K近邻算法的实现主要是参考<机器学习实战>这本书. 一.K近邻(KNN)算法 K最近邻(k-Nearest Neighbour,KNN)分类算法,理解的思路是:如果一个样本在特征空 ...

  4. [Python]基于K-Nearest Neighbors[K-NN]算法的鸢尾花分类问题解决方案

    看了原理,总觉得需要用具体问题实现一下机器学习算法的模型,才算学习深刻.而写此博文的目的是,网上关于K-NN解决此问题的博文很多,但大都是调用Python高级库实现,尤其不利于初级学习者本人对模型的理 ...

  5. Python机器学习基础教程-第2章-监督学习之K近邻

    前言 本系列教程基本就是摘抄<Python机器学习基础教程>中的例子内容. 为了便于跟踪和学习,本系列教程在Github上提供了jupyter notebook 版本: Github仓库: ...

  6. K近邻分类算法实现 in Python

    K近邻(KNN):分类算法 * KNN是non-parametric分类器(不做分布形式的假设,直接从数据估计概率密度),是memory-based learning. * KNN不适用于高维数据(c ...

  7. 机器学习实战 - python3 学习笔记(一) - k近邻算法

    一. 使用k近邻算法改进约会网站的配对效果 k-近邻算法的一般流程: 收集数据:可以使用爬虫进行数据的收集,也可以使用第三方提供的免费或收费的数据.一般来讲,数据放在txt文本文件中,按照一定的格式进 ...

  8. TensorFlow实现knn(k近邻)算法

    首先先介绍一下knn的基本原理: KNN是通过计算不同特征值之间的距离进行分类. 整体的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于 ...

  9. 查看neighbors大小对K近邻分类算法预测准确度和泛化能力的影响

    代码: # -*- coding: utf-8 -*- """ Created on Thu Jul 12 09:36:49 2018 @author: zhen &qu ...

随机推荐

  1. 九度oj 题目1022:游船出租

    题目描述:     现有公园游船租赁处请你编写一个租船管理系统.当游客租船时,管理员输入船号并按下S键,系统开始计时:当游客还船时,管理员输入船号并按下E键,系统结束计时.船号为不超过100的正整数. ...

  2. Opencv学习笔记——视频进度条的随动

    1. CvCapture结构体: CvCapture是一个结构体,用来保存图像捕获的信息,就像一种数据类型(如int,char等)只是存放的内容不一样,在OpenCv中,它最大的作用就是处理视频时(程 ...

  3. BZOJ2245 [SDOI2011]工作安排 【费用流】

    题目 你的公司接到了一批订单.订单要求你的公司提供n类产品,产品被编号为1~n,其中第i类产品共需要Ci件.公司共有m名员工,员工被编号为1~m员工能够制造的产品种类有所区别.一件产品必须完整地由一名 ...

  4. 如何解决maven archetype加载太慢的方法

    有时候在构建maven项目时,archetype加载不出来,一直在Retrieving archetype...,现象如下: 有两种解决方法: ①点击链接下载:http://files.cnblogs ...

  5. 【bzoj4320】【ShangHai2006 Homework】【并查集+离线处理】

    ShangHai2006 Homework Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 918  Solved: 460[Submit][Statu ...

  6. (48)C#网络4 web

    WebClient 类 提供用于将数据发送到和接收来自通过 URI 确认的资源数据的常用方法 private delegate string delegatehWeb(); private void ...

  7. stm32的IIc总线--超声波测距

  8. SpringCloud-Eureka注册中心

    什么是微服务,分布式? 分布式:不同的模块部署在不同的服务器上,可以更好的解决网站高并发. 微服务:架构设计概念,各服务间隔离(分布式也是隔离),自治(分布式依赖整体组合)其它特性(单一职责,边界,异 ...

  9. Chrome常用URL命令(伪URL)

    在Chrome地址栏输入chrome://chrome-urls/可以看到所有的Chrome支持的伪RUL 1.chrome://accessibility/ 可达性分析,默认是关闭的,点击acces ...

  10. Windows下部署多个Tomcat

    编辑bin/startup.bat SET JAVA_HOME=...(JDK所在路径) SET CATALINA_HOME=...(Tomcat解压的路径) 编辑server.xml文件 <! ...