笔者本人是个初入机器学习的小白,主要是想把学习过程中的大概知识和自己的一些经验写下来跟大家分享,也可以加强自己的记忆,有不足的地方还望小伙伴们批评指正,点赞评论走起来~

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. 【机器学习实战学习笔记(1-2)】k-近邻算法应用实例python代码

    文章目录 1.改进约会网站匹配效果 1.1 准备数据:从文本文件中解析数据 1.2 分析数据:使用Matplotlib创建散点图 1.3 准备数据:归一化特征 1.4 测试算法:作为完整程序验证分类器 ...

  2. 机器学习实战 - 读书笔记(07) - 利用AdaBoost元算法提高分类性能

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习笔记,这次是第7章 - 利用AdaBoost元算法提高分类性能. 核心思想 在使用某个特定的算法是, ...

  3. OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波

    http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...

  4. 《机实战》第2章 K近邻算法实战(KNN)

    1.准备:使用Python导入数据 1.创建kNN.py文件,并在其中增加下面的代码: from numpy import * #导入科学计算包 import operator #运算符模块,k近邻算 ...

  5. 【机器学习实战学习笔记(2-2)】决策树python3.6实现及简单应用

    文章目录 1.ID3及C4.5算法基础 1.1 计算香农熵 1.2 按照给定特征划分数据集 1.3 选择最优特征 1.4 多数表决实现 2.基于ID3.C4.5生成算法创建决策树 3.使用决策树进行分 ...

  6. 机器学习学习笔记之一:K最近邻算法(KNN)

    算法 假定数据有M个特征,则这些数据相当于在M维空间内的点 \[X = \begin{pmatrix} x_{11} & x_{12} & ... & x_{1M} \\ x_ ...

  7. 【转载】 机器学习实战 - 读书笔记(07) - 利用AdaBoost元算法提高分类性能

    原文地址: https://www.cnblogs.com/steven-yang/p/5686473.html ------------------------------------------- ...

  8. (数据科学学习手札13)K-medoids聚类算法原理简介&Python与R的实现

    前几篇我们较为详细地介绍了K-means聚类法的实现方法和具体实战,这种方法虽然快速高效,是大规模数据聚类分析中首选的方法,但是它也有一些短板,比如在数据集中有脏数据时,由于其对每一个类的准则函数为平 ...

  9. 02-16 k近邻算法

    目录 k近邻算法 一.k近邻算法学习目标 二.k近邻算法引入 三.k近邻算法详解 3.1 k近邻算法三要素 3.1.1 k值的选择 3.1.2 最近邻算法 3.1.3 距离度量的方式 3.1.4 分类 ...

随机推荐

  1. Java核心API需要掌握的程度

    分类: java技术2009-08-29 01:03 213人阅读 评论(0) 收藏 举报 javaapiswingxmlio Java的核心API是非常庞大的,这给开发者来说带来了很大的方便,经常人 ...

  2. Vue项目中v-for无法渲染数据

    在Vue项目中,我们想要实现下面的布局效果 后端返回的数据格式如下,可以看出产品列表五张图的数据位于同一个数组中 而我的html结构如下: 我希望直接渲染左边一张大图,然后右边的四张小图通过v-for ...

  3. hdu 1874 畅通工程续(SPFA模板)

    畅通工程续 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  4. SpringData JPA使用JPQL的方式查询和使用SQL语句查询

    使用Spring Data JPA提供的查询方法已经可以解决大部分的应用场景,但是对于某些业务来说,我们还需要灵活的构造查询条件, 这时就可以使用@Query注解,结合JPQL的语句方式完成查询 持久 ...

  5. Echarts 折线图y轴标签值过长 显示

    参考: https://blog.csdn.net/dandelion_drq/article/details/79270597 改变Y轴单位:https://www.cnblogs.com/cons ...

  6. SPFA和堆优化的Dijk

    朴素dijkstra时间复杂度$O(n^{2})$,通过使用堆来优化松弛过程可以使时间复杂度降到O((m+n)logn):dijkstra不能用于有负权边的情况,此时应使用SPFA,两者写法相似. 朴 ...

  7. 006、Java中定义中文变量中文标识符

    01.代码如下 package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  8. 虚拟机下安装Maven

    1.首先需要下载maven安装包(我下载的是apache-maven-3.5.3版本) 官网下载:http://maven.apache.org/download.cgi 2.将压缩包放到虚拟机下(我 ...

  9. 留学生Essay写作清晰简洁8大原则

    英语Essay写作中国留学生需要掌握的一个技能,一篇文笔简洁优雅的Essay对于提高分数会有很大帮助.但目前的情况是,很多人并没有受过专门的学术Essay写作训练,在写Essay时经常会出现各种各样的 ...

  10. DevOps - 工程师职责

    章节 DevOps – 为什么 DevOps – 与传统方式区别 DevOps – 优势 DevOps – 不适用 DevOps – 生命周期 DevOps – 与敏捷方法区别 DevOps – 实施 ...