【机器学习实战学习笔记(1-1)】k-近邻算法原理及python实现
笔者本人是个初入机器学习的小白,主要是想把学习过程中的大概知识和自己的一些经验写下来跟大家分享,也可以加强自己的记忆,有不足的地方还望小伙伴们批评指正,点赞评论走起来~
文章目录
1.k-近邻算法概述
k-近邻(k-nearest neighbor, k-NN)算法是一种基本分类与回归方法,这里只讨论分类问题中的k-NN。
k-NN算法:假设给定一个训练数据集,其中的实例类别已定(即有标签的训练数据集,属于有监督学习问题),分类时,对新的输入实例,在训练数据集中找到与该实例距离最近的k个实例,这k个实例的多数属于某个类,就把该输入实例分为这个类。
因此,k-NN不具有显式的学习过程。该算法实际上是利用训练数据集对特征向量空间进行划分,并作为其分类的“模型”。
k-NN的特点:
- 优点:精度高、对异常值不敏感、无数据输入假定;(优点的第三点不是特别理解,欢迎知道的小伙伴留言指教~)
- 缺点:计算复杂度高、空间复杂度高;
- 适用数据范围:数值型、标称型
k-NN使用的模型实际上对应于特征空间的划分。模型由距离度量、k值、分类决策规则这三个基本要素决定,下面对k-NN模型这三个基本要素进行简单介绍。
1.1 距离度量
特征空间中两个实例点的距离是两个实例点相似程度的反映。k-NN使用的距离是欧氏距离,也可以是其他距离,如更一般的LpL_pLp距离或Minkowski距离。
设特征空间χ\chiχ是n维实数向量空间RnR^nRn,xi,xj∈χx_i,x_j\in\chixi,xj∈χ,xi=(xi(1),xi(2),...,xi(n))Tx_i = (x_{i}^{(1)},x_{i}^{(2)},...,x_{i}^{(n)})^Txi=(xi(1),xi(2),...,xi(n))T,xj=(xj(1),xj(2),...,xj(n))Tx_j= (x_{j}^{(1)},x_{j}^{(2)},...,x_{j}^{(n)})^Txj=(xj(1),xj(2),...,xj(n))T,xi,xjx_i,x_jxi,xj的LpL_pLp距离定义为:
Lp(xi,xj)=(∑l=1n∣xi(l)−xj(l)∣p)1p(p≥1)L_p(x_i,x_j)=(\sum_{l=1}^{n}|x_{i}^{(l)}-x_{j}^{(l)}|^p)^{\frac{1}{p}}(p\ge1)Lp(xi,xj)=(l=1∑n∣xi(l)−xj(l)∣p)p1(p≥1)
- 当p=2时,为欧氏距离(Euclidean distance),即L2(xi,xj)=(∑l=1n∣xi(l)−xj(l)∣2)12L_2(x_i,x_j)=(\sum_{l=1}^{n}|x_{i}^{(l)}-x_{j}^{(l)}|^2)^{\frac{1}{2}}L2(xi,xj)=(∑l=1n∣xi(l)−xj(l)∣2)21,或者我们更为熟悉的形式:L2(xi,xj)=∑l=1n(xi(l)−xj(l))2L_2(x_i,x_j)=\sqrt{\sum_{l=1}^{n}(x_{i}^{(l)}-x_{j}^{(l)})^2}L2(xi,xj)=l=1∑n(xi(l)−xj(l))2
- 当p=1时,称为曼哈顿距离(Manhattan distance),即L1(xi,xj)=∑l=1n∣xi(l)−xj(l)∣L_1(x_i,x_j)=\sum_{l=1}^{n}|x_{i}^{(l)}-x_{j}^{(l)}|L1(xi,xj)=l=1∑n∣xi(l)−xj(l)∣
- 当p=∞\infty∞时,它是各个坐标距离的最大值,即L∞(xi,xj)=maxl∣xi(l)−xj(l)∣L_\infty(x_i,x_j)=max_{l}|x_{i}^{(l)}-x_{j}^{(l)}|L∞(xi,xj)=maxl∣xi(l)−xj(l)∣
1.2 k值的选择
k值的选择会对k-NN法的结果产生重大影响。
若选择较小的k值,就相当于用较小的领域中的训练实例进行预测。
- 优点:学习的近似误差(approximation error)会减小,只有与输入实例距离较近(相似)的训练实例才会对预测结果有影响;
- 缺点:学习的估计误差(estimation error)会增大,预测结果会对近邻的实例点非常敏感。这时如果邻近的实例点恰巧是噪声,预测就会出错。
k值的减小意味着整体模型变得复杂,容易发生过拟合。
若选择较大的k值,就相当于用较大邻域中的训练实例进行预测。
- 优点:学习的估计误差会减小
- 缺点:学习的近似误差会增大。这时与输入实例距离较远(不相似)的训练实例也会对预测结果有影响,使预测发生错误。
k值的增大意味着整体模型变得简单,容易欠拟合。
在实际应用中,k值一般取一个比较小的数值。通常采用交叉验证法来选取最优的k值。
1.3 分类决策规则
k-NN中的分类决策规则通常是多数表决,即由与输入实例距离最近的k个训练实例中的多数类决定输入实例的类。
2.k-近邻算法实现
2.1 实现方法
实现k-近邻法时,主要考虑的问题是如何对训练数据进行快速k近邻搜索。这点在特征空间的维数较大及训练数据容量较大时尤其重要。
下面主要介绍k-近邻法的两种实现方法:
线性搜索(linear scan)法:
- 优点:这是k近邻法最简单的实现方法
- 缺点:要计算输入实例与每一个训练实例的距离。当训练集很大时,计算非常耗时,这种方法不太可行。
kd树(也称k决策树):
为了提高k近邻搜索的效率,可以考虑使用特殊的结构存储训练数据,以减少计算距离的次数。具体方法有很多,其中方法之一就是kd树方法。可以节省大量的计算开销。
2.2 k-近邻法python3.6实现
本节主要介绍基于欧式距离、多数表决规则,实现方法采用线性搜索法,实现k-近邻法。开发环境为python3.6。
对于kd树的实现,现在暂时没有了解代码实现,后期再补上。
2.2.1 k-近邻法实现程序
from numpy import *
import operator
## 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
# 选择距离最小的k个点
sortedDistIndicies = distances.argsort()
classCount = {}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
# 对字典排序
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
# Python3中不再支持iteritems(),将iteritems()改成items()
return sortedClassCount[0][0]
2.2.2 classify0(inX, dataSet, labels, k)中部分方法注释
classify0函数中参数说明
inX:测试实例,n维行向量(n为实例的特征数)
dataSet:训练实例数据集,m*n的NumPy矩阵(m为训练实例数,n为实例的特征数)
labels:m维行向量(m为训练实例总个数)
数组的维度
例子:x = array([[[1,2,3],[4,5,6]],[[7,8,9],[0,1,2]],[[3,4,5],[6,7,8]]])
print(x.shape) #(3,2,3)
可以看到x是一个包含了3个两行三列的二维数组的三维数组:
x.shape[0]代表包含二维数组的个数,x.shape[1]表示二维数组的行数,x.shape[2]表示二维数组的列数。
tile(A, res)
功能:重复A的各个维度
参数类型:
A: Array类的都可以
rep:A沿着各个维度重复的次数
例子:
print(tile([1,2],(2,2,3)))
重复顺序为: [1,2] => [[1,2] , [1,2]] => [[[1,2],[1,2]] , [[1,2],[1,2]]] => [[[1,2,1,2,1,2],[1,2,1,2,1,2]] , [[1,2,1,2,1,2],[1,2,1,2,1,2]]]
sum()
在numpy中数组都有着[]标记,则axis=0对应着最外层的[],axis=1对应第二外层的[],以此类推。
例子:
a= array([[1,2],[3,4]])
a.sum(axis = 0)
a有两层[],最外层[]里的最大单位块分别为[1,2],[3,4],对这两个单位块做块与块之间的运算,[1,2]+[3,4] = [4, 6];
做完加法后本应是[[4, 6]],但是移除最外层[]后,原来的两层[]变成一层[],所以返回结果为 [4, 6]。
argsort()函数
x.argsort():将x中的元素从小到大排列,提取其对应的index(索引)
dict.items()
作用:可以将字典中的所有项,以列表方式返回。因为字典是无序的,所以用items方法返回字典的所有项,也是没有顺序的。
operator.itemgetter()
operator模块提供的itemgetter函数用于获取对象的哪些维的数据,参数为一些序号。
2.2.3 如何测试分类器
这里用错误率来评估分类器在某个数据集上的执行效果:
错误率=分类器给出错误结果的次数测试执行的总数错误率=\frac{分类器给出错误结果的次数}{测试执行的总数}错误率=测试执行的总数分类器给出错误结果的次数
参考资料:
- 《机器学习实战》第二章
- 《统计学习方法》第三章
【机器学习实战学习笔记(1-1)】k-近邻算法原理及python实现的更多相关文章
- 【机器学习实战学习笔记(1-2)】k-近邻算法应用实例python代码
文章目录 1.改进约会网站匹配效果 1.1 准备数据:从文本文件中解析数据 1.2 分析数据:使用Matplotlib创建散点图 1.3 准备数据:归一化特征 1.4 测试算法:作为完整程序验证分类器 ...
- 机器学习实战 - 读书笔记(07) - 利用AdaBoost元算法提高分类性能
前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习笔记,这次是第7章 - 利用AdaBoost元算法提高分类性能. 核心思想 在使用某个特定的算法是, ...
- OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波
http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...
- 《机实战》第2章 K近邻算法实战(KNN)
1.准备:使用Python导入数据 1.创建kNN.py文件,并在其中增加下面的代码: from numpy import * #导入科学计算包 import operator #运算符模块,k近邻算 ...
- 【机器学习实战学习笔记(2-2)】决策树python3.6实现及简单应用
文章目录 1.ID3及C4.5算法基础 1.1 计算香农熵 1.2 按照给定特征划分数据集 1.3 选择最优特征 1.4 多数表决实现 2.基于ID3.C4.5生成算法创建决策树 3.使用决策树进行分 ...
- 机器学习学习笔记之一:K最近邻算法(KNN)
算法 假定数据有M个特征,则这些数据相当于在M维空间内的点 \[X = \begin{pmatrix} x_{11} & x_{12} & ... & x_{1M} \\ x_ ...
- 【转载】 机器学习实战 - 读书笔记(07) - 利用AdaBoost元算法提高分类性能
原文地址: https://www.cnblogs.com/steven-yang/p/5686473.html ------------------------------------------- ...
- (数据科学学习手札13)K-medoids聚类算法原理简介&Python与R的实现
前几篇我们较为详细地介绍了K-means聚类法的实现方法和具体实战,这种方法虽然快速高效,是大规模数据聚类分析中首选的方法,但是它也有一些短板,比如在数据集中有脏数据时,由于其对每一个类的准则函数为平 ...
- 02-16 k近邻算法
目录 k近邻算法 一.k近邻算法学习目标 二.k近邻算法引入 三.k近邻算法详解 3.1 k近邻算法三要素 3.1.1 k值的选择 3.1.2 最近邻算法 3.1.3 距离度量的方式 3.1.4 分类 ...
随机推荐
- html css3
一.引入样式 1.行内样式表 <h1 style="color: red;font-size: 18px;">10-30</h1> 2.内部样式表(在hea ...
- Java的SpringMVC执行流程
SpringMVC找Controller流程 1.扫描整个项目(Spring已经做了)定义一个Map集合. 2.拿到所有加了@Controller注解的类. 3.遍历类里面的所有方法对象. 4.判断方 ...
- linux(centos6.9)下使用yum安装mysql,及启动MySQL等
查看系统自带的mysql版本:rpm -qa | grep mysql 卸载mysql:rpm -e mysql-libs-5.1.73-8.el6_8.x86_64 --nodeps 1. 安装my ...
- WARN No appenders could be found for logger 。。。。
对于类似与标题的警告信息,一般来说是环境在没有加载log4j的配置文件之前就读取了log4j的包. 解决方法就是先加载log4j的配置文件,然后再加载log4j的包. 另一个解决方案就是移除log4j ...
- Python入门必学知识,30万年薪Python工程师带你学
Python是一种计算机编程语言.计算机编程语言和我们日常使用的自然语言有所不同,最大的区别就是,自然语言在不同的语境下有不同的理解,而计算机要根据编程语言执行任务,就必须保证编程语言写出的程序决不能 ...
- JS: 子项可以来回交换的两个下拉列表
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> ...
- jQuery事件 - toggle() 方法
1.切换元素的显示与隐藏状态 实例 切换 <p> 元素的显示与隐藏状态: $(".btn1").click(function(){ $("p").h ...
- JavaScript的调用
1 方法调用模式 var myObject = { value : 0, increment : function(inc) { alert('hi'); } }; myObject.incremen ...
- Angular2的双向数据绑定
什么是双向绑定 如图: 双向绑定.jpg 双向绑定机制维护了页面(View)与数据(Data)的一致性.如今,MVVM已经是前段流行框架必不可少的一部分. Angular2中的双向绑定 双向绑定, ...
- Spring boot application.properties和 application.yml 初学者的学习
来自于java尚硅谷教程 简单的说这两个配置文件更改配置都可以更改默认设置的值比如服务器端口号之类的,只需再文件中设置即可, properties可能是出现的比较早了,如果你不调你的默认编码,中文可能 ...