《机器学习实战》笔记——第二章:k-近邻算法(kNN)实战_knn构建邻接矩阵-程序员宅基地

技术标签: 机器学习  手写识别系统  人工智能  约会网站配对算法  kNN  

1 说明

该书主要以原理简介+项目实战为主,本人学习的主要目的是为了结合李航老师的《统计学习方法》以及周志华老师的西瓜书的理论进行学习,从而走上机器学习的“不归路”。因此,该笔记主要详细进行代码解析,从而透析在进行一项机器学习任务时候的思路,同时也积累自己的coding能力。
正文由如下几部分组成:
1、实例代码(详细注释)
2、知识要点(函数说明)
3、调试及结果展示

2 正文

(1)准备:使用python导入数据

1、将如下内容写入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

知识要点:
①operator模块:该模块是python中内置的操作符函数接口,它定义了一些算术和比较内置操作的函数。接下的代码会用到该模块中的一个非常重要的方法:itemgetter

2、打开python交互式开发环境,执行以下命令并得到结果:

******
PyDev console: starting.
Python 3.6.7 |Anaconda, Inc.| (default, Oct 28 2018, 19:44:12) [MSC v.1915 64 bit (AMD64)] on win32
>>>import kNN
>>>group, labels = kNN.createDataSet()
>>>group
array([[1. , 1.1],
       [1. , 1. ],
       [0. , 0. ],
       [0. , 0.1]])
>>>labels
['A', 'A', 'B', 'B']

(2)实施kNN分类算法

1、在kNN.py文件中添加如下代码,该函数用于k-近邻算法的实现,其中4个输入分别是:输入向量inX(欲进行分类的数据),输入的训练样本集dataSet,标签向量labels以及所选k值。具体实现如下代码所示:

def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0]#获取训练样本集的行数,即样本个数
    diffMat = tile(inX, (dataSetSize,1)) - dataSet#利用tile函数将inX向量构造成一个和dataset有相同行数列数的矩阵,并与之相减
    sqDiffMat = diffMat**2#各个元素分别平方
    sqDistances = sqDiffMat.sum(axis=1)#按列求和,即得到了每一个距离的平方
    distances = sqDistances**0.5#各个元素开平方即得到了距离矩阵
    sortedDistIndicies = distances.argsort()#把向量中每个元素进行排序,而它的结果是元素的索引形成的向量
    classCount={
   
    }
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]#把按值大小顺序排列的欧氏距离索引list前k个对应的labels遍历出来
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1#统计labels中各类出现的频次,以字典的形式输出
    #分解为元组列表,operator.itemgetter(1)按照第二个元素的次序对元组进行排序,reverse=True是逆序,即按照从大到小的顺序排列
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

知识要点:
①tile():tile函数位于python模块 numpy中,其功能是重复某个数组,从而形成新的数组。
②argsort():tile函数位于python模块 numpy中,其功能是将目标数组中的元素从小到大排列,提取其对应的index(索引),然后输出。
③sorted():sorted函数是python的内置函数,用来做排序任务,该函数可以对list按一定的规则进行排序。
④items():Python 字典(Dictionary) items() 函数以列表返回可遍历的(键, 值) 元组数组。返回值类型为dict_items。
⑤itemgetter():operator模块提供的itemgetter函数用于获取对象的哪些维的数据,参数为一些序号(即需要获取的数据在对象中的序号),其定义的是一个函数,通过该函数作用到对象上才能获取值。

2、我们假设现在有个待测试数据(0,0),k值选择3,下面就来预测一下该数据所在分类是什么,还是接着之前的python交互式开发环境,所得结果是B分类:

******
>>>kNN.classify0([0,0], group, labels, 3)
'B'

(3)案例1-使用k-近邻算法改进约会网站的配对效果

1、书中案例给定了3个维度的特征,共计1000组,存放在工程根目录下的datingTestSet2.txt文本文件下。在将特征数据输入到分类器之前,需要将待处理数据的格式改变为分类器可以接受的格式。案例中定义了file2matrix函数,该函数的输入为文本文件名字符串,输出为训练样本矩阵和类标签向量。具体实现代码如下:

def file2matrix(filename):
    fr = open(filename)
    numberOfLines = len(fr.readlines())#获取文件的行数
    returnMat = zeros((numberOfLines,3))#构造返回的矩阵
    classLabelVector = []#构造返回的labels列表
    fr = open(filename)#此处为何还要开一次呢?
    index = 0
    for line in fr.readlines():
        line = line.strip()#按行去除头尾字符、空白符(包括\n、\r、\t、' ',即:换行、回车、制表符、空格)
        listFromLine = line.split('\t')#拆分字符串,通过指定分隔符对字符串进行切片,并返回分割后的字符串列表(list)
        returnMat[index,:] = listFromLine[0:3]#通过切片操作抽取特征向量
        classLabelVector.append(int(listFromLine[-1]))#获取labels
        index += 1
    return returnMat,classLabelVector

知识要点:
①open():open() 函数是python内置的file对象中的一个方法,用于打开一个文件,创建一个 file 对象,相关的方法才可以调用它进行读写。
②readlines():用于读取所有行(直到结束符 EOF)并返回列表,该列表可以由 Python 的 for… in … 结构进行处理。如果碰到结束符 EOF 则返回空字符串。
③strip():用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。
④split():str.split(str="", num=string.count(str))。通过指定分隔符对字符串进行切片,如果参数 num 有指定值,则分隔 num+1 个子字符串。

2、在python交互开发环境中执行的命令和结果如下:

******
PyDev console: starting.
Python 3.6.7 |Anaconda, Inc.| (default, Oct 28 2018, 19:44:12) [MSC v.1915 64 bit (AMD64)] on win32
>>>from kNN import *
>>>datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')
>>>datingDataMat
>>>array([[4.0920000e+04, 8.3269760e+00, 9.5395200e-01],
          [1.4488000e+04, 7.1534690e+00, 1.6739040e+00],
          [2.6052000e+04, 1.4418710e+00, 8.0512400e-01],
          ...,
          [2.6575000e+04, 1.0650102e+01, 8.6662700e-01],
          [4.8111000e+04, 9.1345280e+00, 7.2804500e-01],
          [4.3757000e+04, 7.8826010e+00, 1.3324460e+00]])
>>>datingLabels[0:20]
[3, 2, 1, 1, 1, 1, 3, 3, 1, 3, 1, 1, 2, 1, 1, 1, 1, 1, 2, 3]

此处我是重新打开了交互环境,如果你是按着书上的步骤一步一步做下来的,需要reload我们创建的kNN模块。而书中例程用的是python2,reload还是属于python内置的。如果我们用的是python3,那么就要通过下面的方式进行重载:

******
PyDev console: starting.
Python 3.6.7 |Anaconda
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_39178948/article/details/88737373

智能推荐

k8s问题排错思路(问题:6443 was refused)-程序员宅基地

文章浏览阅读2.3w次,点赞5次,收藏9次。今天启动虚拟机的时候,在master敲入指令,提示错误,如下所示:kubectl get po The connection to the server apiserver.demo:6443 was refused - did you specify the right host or port?按照字面理解是,连接server apiserver.demo:6443被拒绝于是我..._6443 was refused

字符串基础知识总结_什么是字符串-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏13次。字符串什么是字符串字符串是由数字、字⺟、下划线组成的⼀串字符注意:单引号和双引号不能混合使⽤Python中⽤⼀对双引号或者⼀对单引号包裹的内容就是字符串转义字符转义字符是⼀种特殊的字符常量。转义字符以反斜线""开头,后跟⼀个或⼏个字符。转义字符具有特定的含义,不同于字符原有的意义,故称“转义”字符\t 表示制表符\n 表示换⾏符\ 表示反斜杠’ 表示 ’⻓字符串⻓字符串 ⼜叫做⽂档字符串 我们使⽤三重引号来表示⼀个⻓字符串’’’ ‘’’三重引号可以换⾏,并且会保留字符串中的格_什么是字符串

typeScript整理笔记_name: string; //这里会报错,因为不满足索引类型指定的返回值类型-程序员宅基地

文章浏览阅读226次,点赞2次,收藏2次。typeScriptTypeScript 并不是一个完全新的语言, 它是 JavaScript 的超集,为 JavaScript 的生态增加了类型机制,并最终将代码编译为纯粹的 JavaScript 代码。TypeScript 简介TypeScript 由 Microsoft(算上 Angular 2 的话加上 Google)开发和维护的一种开源编程语言。 它支持 JavaScript 的所有语法和语义,同时通过作为 ECMAScript 的超集来提供一些额外的功能,如类型检测和更丰富的语法。_name: string; //这里会报错,因为不满足索引类型指定的返回值类型

无法加载SQLite.Interop.dll:找不到指定模块-程序员宅基地

文章浏览阅读6.6k次。最近在使用SQLite数据库时,使用的是linq2db.SQLite框架,正常编译状态下未报任何错误,只是在项目打包的时候出现了错误,提示无法加载:“SQLite.Interop.dll”,找不到指定模块的问题,我们找到安装后的项目路径下缺失这个文件,解决方法倒是不难,吧对应版本的拷贝进去进行了。猜想可能是在安装linq2db.SQLite的时候没有将SQLite.Interop.dll生成到Debug目录下,尝试更新了linq2db.SQLite升级到4.0.0,但是也没有自动生成,并且安装时依然提示_sqlite.interop.dll

基于距离公式的三角模糊数TOPSIS多属性决策方法及matlab应用_三角模糊书topsis-程序员宅基地

文章浏览阅读2.7k次,点赞4次,收藏16次。上一篇使用三角模糊数去模糊的方法构建了TOPSIS多属性决策方法,这篇使用三角模糊数的距离公式构建TOPSIS多属性决策方法。1.模糊理想解与距离公式我们选择以下4种距离公式,度量各个方案与模糊理想解之问的分离程度,包括Euclidean距离、L2-metric距离、Dp,q距离、Hausdorff距离等。2.排序步骤与matlab程序基于TOPSIS法的三角模糊数型多属性决策问题的..._三角模糊书topsis

js严格模式_js export which has only a getter-程序员宅基地

文章浏览阅读392次。为什么使用严格模式?消除js语法的一些不合理、不严谨之处,减少一些怪异行为;1).消除代码运行的一下不安全之处,保证代码运行的安全;2).提高编译器效率,增加运行速度;3)为未来新版本的js做好铺垫。“严格模式”提现了js更合理、更安全、更严谨的发展方向,包括IE10在内的主流浏览器,都已经支持它,许多大项目已经开始全面拥抱它。另一方面,同样的代码,在“严禁模式”中,可能会..._js export which has only a getter

随便推点

解决IEEE的Latex模板不能显示中文的问题_ieeelatx模板不能用中文-程序员宅基地

文章浏览阅读445次。只需两步就能解决这个问题:1.添加包:\usepackage[UTF8]{ctex}2.编译器选择XeLatex完成!!_ieeelatx模板不能用中文

lua socket_luasocket-2.0.2-程序员宅基地

文章浏览阅读2.2k次。LuaSocket 是 Lua 的网络模块库,它可以很方便地提供TCP、UDP、DNS、FTP、HTTP、SMTP、MIME 等多种网络协议的访问操作。它由两部分组成:一部分是用 C 写的核心,提供对 TCP 和 UDP 传输层的访问支持。另外一部分是用 Lua 写的,负责应用功能的网络接口处理。安装 LuaSocket如果你安装有 Lua 模块的安装和部署工具 -- Lu_luasocket-2.0.2

html type file 响应,把input type=file 上传文件的onchange调用方法参数用\"括起来后赋给div变乱而无响应...-程序员宅基地

文章浏览阅读1.1k次。用 input type=file 来上传文件需要借住 javascript 来完成,客户端的执行过程大概是这样:用户单击“浏览”选择待上传的文件后触发 input 的onchange事件,在onchange事件中调用一个方法,该方法负责把文件提交到服务器,由服务器来完成文件的上传。这种方法上传文件每上传一次后需要重写 input type=file,这就涉及到把 input type=file ..._input type file onchange

ModuleNotFoundError: No module named ‘win32con‘_modulenotfounderror: no module named 'win32com-程序员宅基地

文章浏览阅读3.5k次。Python在windows系统运行时,提示ModuleNotFoundError: No module named ‘win32con’。但是去很多地方都找不到这个包解决方案是:conda install scripyscipy 包中包含了win32con这个包,nice._modulenotfounderror: no module named 'win32com

python for下面的else执行流程是在上面的for执行完成后顺序执行的,除非上面的for循环中有break会导致跳过的情况,否则是执行了上面的for,再执行else_for ~ else语句的执行过程-程序员宅基地

文章浏览阅读349次。#resultt_class.type= <class 'torch.Tensor'>t_class= tensor([[ 3], [ 6], [ 9], [ 5], [ 5], [ 1], [ 2], [ 2], [ 0], [ 7], [ 1], [ 3], [ 3], [ .._for ~ else语句的执行过程

Apache Kafka-Spring Kafka生产消费@KafkaListener源码解析_spring kafka生产者源码-程序员宅基地

文章浏览阅读1.1w次,点赞4次,收藏15次。文章目录概述概述#kafkaspring.kafka.bootstrap-servers=10.11.114.247:9092spring.kafka.producer.acks=1spring.kafka.producer.retries=3spring.kafka.producer.batch-size=16384spring.kafka.producer.buffer-memory=33554432spring.kafka.producer.key-serializer=org.a_spring kafka生产者源码

推荐文章

热门文章

相关标签