热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

机器学习:kNN算法(也叫k近邻算法)

一、kNN算法基础#kNN:k-NearestNeighboors#多用于解决分类问题1)特点:是机器学习中唯一一个不需要训练过程的算法,可以别认为是没有模型的算法,也可以认为训

一、kNN算法基础

# kNN:k-Nearest Neighboors

# 多用于解决分类问题

 1)特点:

  1. 是机器学习中唯一一个不需要训练过程的算法,可以别认为是没有模型的算法,也可以认为训练数据集就是模型本身;
  2. 思想极度简单;
  3. 应用数学知识少(近乎为零);
  4. 效果少;
  5. 可以解释机械学习算法使用过程中的很多细节问题
  6. 更完整的刻画机械学习应用的流程;

 2)思想:

  • 根本思想:两个样本,如果它们的特征足够相似,它们就有更高的概率属于同一个类别;
  • 问题:根据现有训练数据集,判断新的样本属于哪种类型
  • 方法/思路
  1. 求新样本点在样本空间内与所有训练样本的欧拉距离;
  2. 对欧拉距离排序,找出最近的k个点;
  3. 对k个点分类统计,看哪种类型的点数量最多,此类型即为对新样本的预测类型;

 3)代码实现过程:

  • 示例代码:

    import numpy as np
    import matplotlib.pyplot as plt
    raw_data_x
    = [[3.3935, 2.3312],
    [
    3.1101, 1.7815],
    [
    1.3438, 3.3684],
    [
    3.5823, 4.6792],
    [
    2.2804, 2.8670],
    [
    7.4234, 4.6965],
    [
    5.7451, 3.5340],
    [
    9.1722, 2.5111],
    [
    7.7928, 3.4241],
    [
    7.9398, 0.7916]]
    raw_data_y
    = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
    # 训练集样本的data
    x_train = np.array(raw_data_x)
    # 训练集样本的label
    y_train = np.array(raw_data_y)
    # 1)绘制训练集样本与新样本的散点图
    #
    根据样本类型(0、1两种类型),绘制所有样本的各特征点
    plt.scatter(x_train[y_train == 0, 0], x_train[y_train == 0, 1], color = 'g')
    plt.scatter(x_train[y_train
    == 1, 0], x_train[y_train == 1, 1], color = 'r')
    # 新样本
    x = np.array([8.0936, 3.3657])
    # 将新样本的特征点绘制在训练集的样本空间
    plt.scatter(x[0], x[1], color = 'b')
    plt.show()
    # 2)在特征空间中,计算训练集样本中的所有点与新样本的点的欧拉距离
    from math import sqrt
    # math模块下的sqrt函数:对数值开平方sqrt(number)
    distances = []
    for x_train in x_train:
    d
    = sqrt(np.sum((x - x_train) ** 2))
    distances.append(d)
    # 也可以用list的生成表达式实现:
    #
    distances = [sqrt(np.sum((x - x_train) ** 2)) for x_train in x_train]
    # 3)找出距离新样本最近的k个点,并得到对新样本的预测类型
    nearest = np.argsort(distances)
    k
    = 6
    # 找出距离最近的k个点的类型
    topK_y = [y_train[i] for i in nearest[:k]]
    # 根据类别对k个点的数量进行统计
    from collections import Counter
    votes
    = Counter(topK_y)
    # 获取所需的预测类型:predict_y
    predict_y = votes.most_common(1)[0][0]

 

  • 封装好的Python代码

    import numpy as np
    from math import sqrt
    from collections import Counter
    def kNN_classify(k, X_train, y_train, x):
    assert 1 <= k <= X_train.shape[0],"k must be valid"
    assert X_train.shape[0] == y_train.shape[0], \
    "the size of X_train nust equal to the size of y_train"
    assert X-train.shape[1] == x.shape[0],\
    "the feature number of x must be equal to X_train"
    distances
    = [sprt(np.sum((x_train - x) ** 2)) for x_train in X_train]
    nearest
    = np.argsort(distances)
    topK_y
    = [y_train[i] for i in nearest[:k]]
    vates
    = Counter(topK_y)
    return votes.most_common(1)[0][0]

    # assert:表示声明;此处对4个参数进行限定;

  • 代码中的其它Python知识:
  1. math模块下的sprt()方法:对数开平方;

    from math import sqrt
    print(sprt(9))
    # 3

  2. collections模块下的Counter()方法:对列表中的数据进行分类统计,生产一个Counter对象;

    from collections import Counter
    my_list
    = [0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3]
    print(Counter(my_list))
    # 一个Counter对象:Counter({0: 2, 1: 3, 2: 4, 3: 5})

  3. Counter对象的most_common()方法:Counter.most_common(n),返回Counter对象中数量最多的n种数据,返回一个list,list的每个元素为一个tuple;

    from collections import Counter
    my_list
    = [0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3]
    votes
    = Counter(my_list)
    print(votes.most_common(2))
    # [(3, 5), (2, 4)]

 

二、总结

 1)k近邻算法的作用

  1、解决分类问题,而且天然可以解决多分类问题;

  2、也可以解决回归问题,其中scikit-learn库中封装的KNeighborsRegressor,就是解决回归问题;

 2)缺点

  • 缺点1:效率低下
  1. 原因:如果训练集有m个样本,n个特征,预测每一个新样本,需要计算与m个样本的距离,每计算一个距离,要使用n个时间复杂度,则计算m个样本的距离,使用m * n个时间复杂度;
  2. 算法的时间复杂度:反映了程序执行时间随输入规模增长而增长的量级,在很大程度上能很好反映出算法的优劣与否。
  3. 算法的时间复杂度与空间复杂度,参考:算法的时间复杂度和空间复杂度
  4. 可以通过树结构对k近邻算法优化:KD-Tree、Ball-Tree,但即便进行优化,效率依然不高;

 

  • 缺点2:高度数据相关
  1. 机器学习算法,就是通过喂给数据进行预测,理论上所有机器学习算法都是高度数据相关;
  2. k近邻算法对outlier更加敏感:比如三近邻算法,在特征空间中,如果在需要预测的样本周边,一旦有两个样本出现错误值,就足以使预测结果错误,哪怕在更高的范围里,在特征空间中有大量正确的样本;

 

  • 缺点3:预测的结果不具有可解释性
  1. 按k近邻算法的逻辑:找到和预测样本比较近的样本,就得出预测样本和其最近的这个样本类型相同;
  2. 问题:为什么预测的样本类型就是离它最近的样本的类型?
  3. 很多情况下,只是拿到预测结果是不够的,还需要对此结果有解释性,进而通过解释推广使用,或者制作更多工具,或者以此为基础发现新的理论/规则,来改进生产活动中的其它方面——这些是kNN算法做不到的;

 

  • 缺点4:维数灾难
  1. 维数灾难:随着维度的增加,“看似相近”的两个点之间的距离越来越大;
  2. 例:[0, 0, 0, &#8230;0]和[1, 1, 1,&#8230;1],按欧拉定理计算,元素个数越多,两点距离越大;
  3. 方案:降维(PCA);

 

三、使用机器学习算法的流程

《机器学习:k-NN算法(也叫k近邻算法)》

  • 获取原始数据——数据分割——数据归一化——训练模型——预测
  1. 获取原始数据:一般可从scikit-learn库中调用——# 调用数据集的操作流程  机器学习:scikit-learn中算法的调用、封装并使用自己所写的算法
  2. 数据分割:一般按2 :8进行分割——# 分割数据的代码实现过程、通过scikit-learn库分割数据的操作流程  机器学习:训练数据集、测试数据集
  3. 数据归一化:参见  机器学习:数据归一化(Scaler)
  4. 训练模型、模型预测:  机器学习:scikit-learn中算法的调用、封装并使用自己所写的算法

 


推荐阅读
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 提升Python编程效率的十点建议
    本文介绍了提升Python编程效率的十点建议,包括不使用分号、选择合适的代码编辑器、遵循Python代码规范等。这些建议可以帮助开发者节省时间,提高编程效率。同时,还提供了相关参考链接供读者深入学习。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 2018年人工智能大数据的爆发,学Java还是Python?
    本文介绍了2018年人工智能大数据的爆发以及学习Java和Python的相关知识。在人工智能和大数据时代,Java和Python这两门编程语言都很优秀且火爆。选择学习哪门语言要根据个人兴趣爱好来决定。Python是一门拥有简洁语法的高级编程语言,容易上手。其特色之一是强制使用空白符作为语句缩进,使得新手可以快速上手。目前,Python在人工智能领域有着广泛的应用。如果对Java、Python或大数据感兴趣,欢迎加入qq群458345782。 ... [详细]
  • 学习SLAM的女生,很酷
    本文介绍了学习SLAM的女生的故事,她们选择SLAM作为研究方向,面临各种学习挑战,但坚持不懈,最终获得成功。文章鼓励未来想走科研道路的女生勇敢追求自己的梦想,同时提到了一位正在英国攻读硕士学位的女生与SLAM结缘的经历。 ... [详细]
  • IB 物理真题解析:比潜热、理想气体的应用
    本文是对2017年IB物理试卷paper 2中一道涉及比潜热、理想气体和功率的大题进行解析。题目涉及液氧蒸发成氧气的过程,讲解了液氧和氧气分子的结构以及蒸发后分子之间的作用力变化。同时,文章也给出了解题技巧,建议根据得分点的数量来合理分配答题时间。最后,文章提供了答案解析,标注了每个得分点的位置。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
author-avatar
庄乐星
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有