机器学习 Python实践-K近邻算法
机器学习K近邻算法的实现主要是参考《机器学习实战》这本书。
一、K近邻(KNN)算法
K最近邻(k-Nearest Neighbour,KNN)分类算法,理解的思路是:如果一个样本在特征空间中的K个最相似(即特征空间最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
我们采用一个图来进行说明(如下):
图中的蓝色小正方形和红色的小正方形属于两类不同的样本数据,图正中间的绿色的圆代表的是待分类的数据。现在我们可以根据K最近邻算法来判断绿色的圆属于哪一类数据?
- 如果K=3,绿色圆点的最近的3个邻居是2个红色小三角形和1个蓝色小正方形,由于红色三角形所占比例为2/3,选择概率大的一类,我们可以认为绿色的这个待分类点属于红色的三角形一类。
- 如果K=5,绿色圆点的最近的5个邻居是2个红色三角形和3个蓝色的正方形,由于蓝牙正方形所占比例为3/5,选择概率大的一类,我们可以认为绿色的这个待分类点属于蓝色的正方形一类。
以上就是对K最近邻算法的理解。
K-近邻算法的特点是:
优点:精度高、对异常值不敏感、无数据输入假定。
缺点:计算复杂度高、空间复杂度高。
适用数据范围:数值型和标称型。
二、算法实践
现在我们对《机器学习实战》中K最近邻的代码进行实现
首先要导入样本数据,我们建立KNN.py的模块,用来生成数据库,代码如下:
from numpy import *
import operator def createDataSet():
group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
labels = ['A','A','B','B']
return group, labels
在代码中,我们导入了Python的两个模块:科学计算包Numpy和运算符模块。Python中导入Nump模块可以参考之前的Python安装reque模块文章。
然后实现K-近邻算法,
K-近邻算法的具体思想如下:
(1)计算已知类别数据集中的点与当前点之间的距离
(2)按照距离递增次序排序
(3)选取与当前点距离最小的k个点
(4)确定前k个点所在类别的出现频率
(5)返回前k个点中出现频率最高的类别作为当前点的预测分类
Python代码如下:
# coding : utf-8 from numpy import *
import operator
import kNN group, labels = kNN.createDataSet() def classify(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 #开方,得到距离
sortedDistances = distances.argsort() #按照distances中元素进行升序排列后得到相应下表的列表
classCount = {} #选择距离最小的k个点
for i in range(k):
numOflabel = labels[sortedDistances[i]]
classCount[numOflabel] = classCount.get(numOflabel,0) + 1
sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1),reverse=True) #按classCount字典的value(类别出现次数)降序排列
return sortedClassCount[0][0] test = classify([0,0], group, labels, 3)
print test
运算结果为:
B
输出结果是B:说明我们新的数据([0,0])是属于B类。
代码解析:
classify函数的参数为:
- inX:用于分类的输入向量
- dataSet:训练样本集合
- labels:标签向量
- k:K-近邻算法中的k
shape函数:是numpy.core.fromnumeric中的函数,它的功能是读取矩阵的长度,比如shape[0]就是读取矩阵第一维度的长度。它的输入参数可以是一个整数表示维 度,也可以是一个矩阵。如下所示:
>>> from numpy import *
>>> shape([1])
(1L,)
>>> shape([[1],[2]])
(2L, 1L)
>>> shape(3)
()
>>>
>>> e=eye(3)
>>> e
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
>>> e.shape
(3L, 3L)
>>> e.shape[0]
3L
>>>
一维矩阵,shape([1]),结果为(1L,);
二维矩阵,shape([1],[2]), 结果为(2L,1L);
单独的数字,返回值为空;
创建一个单位矩阵e,可以判断e的形状,e.shape的结果为(3L,3L); 我们只取第一维度长度(即行数)e.shape[0]的值为3L。
tile函数:tile函数是模板numpy.lib.shape_base中的函数。函数的形式是tile(A,reps)。
A的类型众多,几乎所有类型都可以:array, list, tuple, dict, matrix以及基本数据类型int, string, float以及bool类型。
reps的类型也很多,可以是tuple,list, dict, array, int,bool.但不可以是float, string, matrix类型。
tile函数是为了扩充数组元素,看一下举例:
>>> from numpy import *
>>> a=array([1,2])
>>> tile(a,(3,2)) #构造3X2个copy
array([[1, 2, 1, 2],
[1, 2, 1, 2],
[1, 2, 1, 2]])
>>> tile(7,(3,2))
array([[7, 7],
[7, 7],
[7, 7]])
>>>
简单理解tile(a,(3,2))就是对a进行3X2的复制。具体的理解可以参考这篇文章:http://blog.sina.com.cn/s/blog_6bd0612b0101cr3u.html。
在算法程序中tile(inX, (dataSetSize,1))就是对inX进行了复制了dataSetSize行,1表示列的倍数。
diffMat = tile(inX, (dataSetSize,1)) - dataSet 这一行代码表示前一个二维数组矩阵的每一个元素减去后一个数组对应的元素值,实现了矩阵之间的减法。
sqDistances = sqDiffMat.sum(axis=1)这一行代码中,axis=1:参数等于1的时候,表示矩阵中行之间的数的求和,等于0的时候表示列之间数的求和。
classCount.get(numOflabel,0) + 1:这一行代码中使用了字典的get方法,在这里需要理解,get方法可以访问字典中键对应的值。key存在则返回对应value,键不存在返回None,也可以设定自己的返回参数,设置的方法是:变量名.get(键名,参数)。在这里我们设置的参数为0,说明在访问不到键对应值时,返回的参数为0,然后对其加1,如此循环,便可以得到key出现的频率。
sorted函数:
为Python内置的排序函数,可以对list或者iterator进行排序,官网文档见:http://docs.python.org/2/library/functions.html?highlight=sorted#sorted,该函数原型为:
sorted(iterable[, cmp[, key[, reverse]]])
参数解释:
(1)iterable指定要排序的list或者iterable;
(2)cmp为函数,指定排序时进行比较的函数,可以指定一个函数或者lambda函数,如:
students为类对象的list,每个成员有三个域,用sorted进行比较时可以自己定cmp函数,例如这里要通过比较第三个数据成员来排序,代码可以这样写:
students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
sorted(students, key=lambda student : student[2])
(3)key为函数,指定取待排序元素的哪一项进行排序,函数用上面的例子来说明,代码如下:
sorted(students, key=lambda student : student[2])
key指定的lambda函数功能是去元素student的第三个域(即:student[2]),因此sorted排序时,会以students所有元素的第三个域来进行排序。
也可以用operator.itemgetter函数来实现,例如要通过student的第三个域排序,可以这么写:
sorted(students, key=operator.itemgetter(2))
sorted函数也可以进行多级排序,例如要根据第二个域和第三个域进行排序,可以这么写:
sorted(students, key=operator.itemgetter(1,2)) 即先跟句第二个域排序,再根据第三个域排序。
(4)reverse参数就不用多说了,是一个bool变量,表示升序还是降序排列,默认为false(升序排列),定义为True时将按降序排列。
在算法程序中,我们也可以用另一种方法来获得最大概率的分类,代码修改如下:
classCount = {}
for i in range(k):
numOflabel = labels[sortedDistances[i]]
classCount[numOflabel] = classCount.get(numOflabel,0) + 1 maxCount = 0
for key, value in classCount.items():
if value > maxCount:
maxCount = value
maxIndex = key
return maxIndex
同样可以实现。
机器学习 Python实践-K近邻算法的更多相关文章
- 机器学习03:K近邻算法
本文来自同步博客. P.S. 不知道怎么显示数学公式以及排版文章.所以如果觉得文章下面格式乱的话请自行跳转到上述链接.后续我将不再对数学公式进行截图,毕竟行内公式截图的话排版会很乱.看原博客地址会有更 ...
- 02机器学习实战之K近邻算法
第2章 k-近邻算法 KNN 概述 k-近邻(kNN, k-NearestNeighbor)算法是一种基本分类与回归方法,我们这里只讨论分类问题中的 k-近邻算法. 一句话总结:近朱者赤近墨者黑! k ...
- 机器学习实战笔记--k近邻算法
#encoding:utf-8 from numpy import * import operator import matplotlib import matplotlib.pyplot as pl ...
- 机器学习随笔01 - k近邻算法
算法名称: k近邻算法 (kNN: k-Nearest Neighbor) 问题提出: 根据已有对象的归类数据,给新对象(事物)归类. 核心思想: 将对象分解为特征,因为对象的特征决定了事对象的分类. ...
- 《机器学习实战》-k近邻算法
目录 K-近邻算法 k-近邻算法概述 解析和导入数据 使用 Python 导入数据 实施 kNN 分类算法 测试分类器 使用 k-近邻算法改进约会网站的配对效果 收集数据 准备数据:使用 Python ...
- 用python实现k近邻算法
用python写程序真的好舒服. code: import numpy as np def read_data(filename): '''读取文本数据,格式:特征1 特征2 -- 类别''' f=o ...
- 机器学习:1.K近邻算法
1.简单案例:预测男女,根据身高,体重,鞋码 import numpy as np import matplotlib import sklearn from skleran.neighbors im ...
- 《机器学习实战》——K近邻算法
三要素:距离度量.k值选择.分类决策 原理: (1) 输入点A,输入已知分类的数据集data (2) 求A与数据集中每个点的距离,归一化,并排序,选择距离最近的前K个点 (3) K个点进行投票,票数最 ...
- GridSearchCV网格搜索得到最佳超参数, 在K近邻算法中的应用
最近在学习机器学习中的K近邻算法, KNeighborsClassifier 看似简单实则里面有很多的参数配置, 这些参数直接影响到预测的准确率. 很自然的问题就是如何找到最优参数配置? 这就需要用到 ...
随机推荐
- 前端学习 -- Xhtml语法规范
Xhtml语法规范 HTML中不区分大小写,但是尽量使用小写: HTML的注释不能嵌套: 标签必须结构完整{要么成对出现,要么自结束标签,虽然浏览器会帮我们修正一些不符合规范的内容} 标签可以嵌套但是 ...
- 【cdq分治】【P4390】[BOI2007]Mokia 摩基亚
Description 给你一个 \(W~\times~W\) 的矩阵,每个点有权值,每次进行单点修改或者求某子矩阵内权值和,允许离线 Input 第一行是两个数字 \(0\) 和矩阵大小 \(W\) ...
- composer install 出现的问题
今天克隆代码之后,在composer install 的时候出现了一些问题,在此记录一下. 错误代码如下: [root@localhost MarketingCenter]# composer ins ...
- Service Fabric —— Stateful Service 概念
作者:潘罡 (Van Pan) @ Microsoft 上节中我们谈到了Service Fabric最底层的两个概念,一个是针对硬件层面而言的Node Type和Node.另一个是Applicatio ...
- [Linux]-Linux常用命令之文件解压
不压缩方式压缩的文件需要不同的命令来解压缩,下面是Linux的各种文件解压命令. 对于.tar结尾的文件: tar -xf 对于.gz结尾的文件 : gzip -d all.gz gunzip all ...
- java基础-System类常用方法介绍
java基础-System类常用方法介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.System类概念 在API中system类介绍的比较简单,我们给出定义,system中 ...
- JS中浮点数精度误差解决
问题出现 0.1 + 0.2 = 0.30000000000000004 问题分析 对于浮点数的四则运算,几乎所有的编程语言都会有类似精度误差的问题,只不过在 C++/C#/Java 这些语言中已经封 ...
- ShareRepository
文件共享下载链接: 1:关于模拟器的配置附件http://pan.baidu.com/s/1jGFqfh8 原文地址:http://www.cnblogs.com/killerlegend/p/382 ...
- vuejs2.0 vue实例的生命周期
每个 Vue 实例在被创建之前都要经过一系列的初始化过程.例如,实例需要配置数据观测(data observer).编译模版.挂载实例到 DOM ,然后在数据变化时更新 DOM .下图展示的就是一个v ...
- 2016/2/13 《计算机系统要素》(The Elements of Computing Systems)读书笔记(1)
过年期间一直在啃一本书,学习计算机组成原理. 这是一本很棒的书,是一个基于项目的学习过程.可以让人理解的很深刻. coursera上有这本书前半部分的教程,是由书的作者团队们开的课,个人认为很棒,可惜 ...