邻近算法(k-NearestNeighbor) 是机器学习中的一种分类(classification)算法,也是机器学习中最简单的算法之一了。虽然很简单,但在解决特定问题时却能发挥很好的效果。因此,学习kNN算法是机器学习入门的一个很好的途径。

  kNN算法的思想非常的朴素,它选取k个离测试点最近的样本点,输出在这k个样本点中数量最多的标签(label)。我们假设每一个样本有m个特征值(property),则一个样本的可以用一个m维向量表示: X =( x1,x2,... x),  同样地,测试点的特征值也可表示成:Y =( y1,y2,... y)。那我们怎么定义这两者之间的“距离”呢?

  在二维空间中,有:d2 = ( x- y)2 + ( x- y),  在三维空间中,两点的距离被定义为:d2 = ( x- y)2 + ( x- y)2  + ( x3 - y)。我们可以据此推广到m维空间中,定义m维空间的距离:d2 = ( x- y)2 + ( x- y)2  + ...... + ( xm - y)2 。要实现kNN算法,我们只需要计算出每一个样本点与测试点的距离,选取距离最近的k个样本,获取他们的标签(label) ,然后找出k个样本中数量最多的标签,返回该标签。

  在开始实现算法之前,我们要考虑一个问题,不同特征的特征值范围可能有很大的差别,例如,我们要分辨一个人的性别,一个女生的身高是1.70m,体重是60kg,一个男生的身高是1.80m,体重是70kg,而一个未知性别的人的身高是1.81m, 体重是64kg,这个人与女生数据点的“距离”的平方 d2 = ( 1.70 - 1.81 )2 + ( 60 - 64 )= 0.0121 + 16.0 = 16.0121,而与男生数据点的“距离”的平方d2 = ( 1.80 - 1.81 )2 + ( 70 - 64 )= 0.0001 + 36.0 = 36.0001 。可见,在这种情况下,身高差的平方相对于体重差的平方基本可以忽略不计,但是身高对于辨别性别来说是十分重要的。为了解决这个问题,就需要将数据标准化(normalize),把每一个特征值除以该特征的范围,保证标准化后每一个特征值都在0~1之间。我们写一个normData函数来执行标准化数据集的工作:

 def normData(dataSet):
maxVals = dataSet.max(axis=0)
minVals = dataSet.min(axis=0)
ranges = maxVals - minVals
retData = (dataSet - minVals) / ranges
return retData, ranges, minVals

然后开始实现kNN算法:

 def kNN(dataSet, labels, testData, k):
distSquareMat = (dataSet - testData) ** 2 # 计算差值的平方
distSquareSums = distSquareMat.sum(axis=1) # 求每一行的差值平方和
distances = distSquareSums ** 0.5 # 开根号,得出每个样本到测试点的距离
sortedIndices = distances.argsort() # 排序,得到排序后的下标
indices = sortedIndices[:k] # 取最小的k个
labelCount = {} # 存储每个label的出现次数
for i in indices:
label = labels[i]
labelCount[label] = labelCount.get(label, 0) + 1 # 次数加一
sortedCount = sorted(labelCount.items(), key=opt.itemgetter(1), reverse=True)
# 对label出现的次数从大到小进行排序
return sortedCount[0][0] # 返回出现次数最大的label

  注意,在testData作为参数传入kNN函数之前,需要经过标准化。

  我们用几个小数据验证一下kNN函数是否能正常工作:

 if __name__ == "__main__":
dataSet = np.array([[2, 3], [6, 8]])
normDataSet, ranges, minVals = normData(dataSet)
labels = ['a', 'b']
testData = np.array([3.9, 5.5])
normTestData = (testData - minVals) / ranges
result = kNN(normDataSet, labels, normTestData, 1)
print(result)

  结果输出 a ,与预期结果一致。

完整代码:

 import numpy as np
from math import sqrt
import operator as opt def normData(dataSet):
maxVals = dataSet.max(axis=0)
minVals = dataSet.min(axis=0)
ranges = maxVals - minVals
retData = (dataSet - minVals) / ranges
return retData, ranges, minVals def kNN(dataSet, labels, testData, k):
distSquareMat = (dataSet - testData) ** 2 # 计算差值的平方
distSquareSums = distSquareMat.sum(axis=1) # 求每一行的差值平方和
distances = distSquareSums ** 0.5 # 开根号,得出每个样本到测试点的距离
sortedIndices = distances.argsort() # 排序,得到排序后的下标
indices = sortedIndices[:k] # 取最小的k个
labelCount = {} # 存储每个label的出现次数
for i in indices:
label = labels[i]
labelCount[label] = labelCount.get(label, 0) + 1 # 次数加一
sortedCount = sorted(labelCount.items(), key=opt.itemgetter(1), reverse=True) # 对label出现的次数从大到小进行排序
return sortedCount[0][0] # 返回出现次数最大的label if __name__ == "__main__":
dataSet = np.array([[2, 3], [6, 8]])
normDataSet, ranges, minVals = normData(dataSet)
labels = ['a', 'b']
testData = np.array([3.9, 5.5])
normTestData = (testData - minVals) / ranges
result = kNN(normDataSet, labels, normTestData, 1)
print(result)

利用Python实现kNN算法的更多相关文章

  1. Python实现KNN算法及手写程序识别

    1.Python实现KNN算法 输入:inX:与现有数据集(1xN)进行比较的向量   dataSet:已知向量的大小m数据集(NxM)   个标签:数据集标签(1xM矢量)   k:用于比较的邻居数 ...

  2. Python实现KNN算法

    Python实现Knn算法 关键词:KNN.K-近邻(KNN)算法.欧氏距离.曼哈顿距离  KNN是通过测量不同特征值之间的距离进行分类.它的的思路是:如果一个样本在特征空间中的k个最相似(即特征空间 ...

  3. [Python] 应用kNN算法预测豆瓣电影用户的性别

    应用kNN算法预测豆瓣电影用户的性别 摘要 本文认为不同性别的人偏好的电影类型会有所不同,因此进行了此实验.利用较为活跃的274位豆瓣用户最近观看的100部电影,对其类型进行统计,以得到的37种电影类 ...

  4. ML一:python的KNN算法

    (1):list的排序算法: 参考链接:http://blog.csdn.net/horin153/article/details/7076321 示例: DisListSorted = sorted ...

  5. 利用python深度学习算法来绘图

    可以画画啊!可以画画啊!可以画画啊! 对,有趣的事情需要讲三遍. 事情是这样的,通过python的深度学习算法包去训练计算机模仿世界名画的风格,然后应用到另一幅画中,不多说直接上图! 这个是世界名画& ...

  6. 基于python 实现KNN 算法

    #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/11/7 14:50 # @Author : gylhaut # @Site ...

  7. 吴裕雄 python 机器学习-KNN算法(1)

    import numpy as np import operator as op from os import listdir def classify0(inX, dataSet, labels, ...

  8. knn算法详解

    邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一.所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代 ...

  9. 机器学习回顾篇(6):KNN算法

    1 引言 本文将从算法原理出发,展开介绍KNN算法,并结合机器学习中常用的Iris数据集通过代码实例演示KNN算法用法和实现. 2 算法原理 KNN(kNN,k-NearestNeighbor)算法, ...

随机推荐

  1. P2286 [HNOI2004]宠物收养场

    题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ...

  2. web.xml is missing and <failOnMissingWebXml> is se

    摘要 maven模块化 在学习maven模块化构建项目的时候遇到了如下报错信息: web.xml is missing and <failOnMissingWebXml> is set t ...

  3. Maven入门1-在Eclipse中新建Maven Web项目

    在eclipse中新建Maven Web项目 很多时候开发效率低下,大部分原因是IDE环境不熟悉.配置不会配置:因此在学习一项技能之前,有必要对基本的环境配置有所了解,正所谓磨刀不误砍柴工.这篇文章主 ...

  4. POJ 3984 路径输出

    迷宫问题 Description 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, ...

  5. docker搭建zabbix

    本次使用docker搭建zabbix的组合是mysql+docker+zabix-server 1 先安装数据库mysql docker run --name zabbix-mysql-server ...

  6. MySQL oracle 分页

    (1)MySql的Limit m,n语句 Limit后的两个参数中,参数m是起始下标,它从0开始:参数n是返回的记录数.我们需要分页的话指定这两个值即可. 比如:查询10行记录,起始行从3开始 SEL ...

  7. C++学习(五)入门篇——基本类型

    面向对象编程的本质是设计并扩展自己的数据类型,让类型和数据匹配. 内置C++分成两种类型:基本类型和复合类型 1.简单变量 程序需要存储信息时,必须记录三个基本属性 (1)信息将存储在哪 (2)要存储 ...

  8. 2、微信小程序之弹幕的实现(无后台)

    对弹幕功能主要利用环信来实现的,读者也许对环信这个东西很陌生,请先自行了解这环信再来看这文章. 环信开发文档:http://docs.easemob.com/im/400webimintegratio ...

  9. (转)eclipse安装jetty

    背景:在项目开发的过程中,一个老的项目使用的是jetty启动,在用tomcat启动的过程中出现了启动不了的异常,浪费了好多时间.因为项目一直是用jetty启动的,为了不浪费时间,也只好改变思路选择je ...

  10. opencv+python3.4的人脸识别----2017-7-19

    opencv3.1  +  python3.4 第一回合(抄代码,可实现):人脸识别涉及一个级联表,目前能力还无法理解. 流程:1.读取图像---2.转换为灰度图---3.创建级联表---4.对灰度图 ...