用python实现K-近邻算法改进约会网站的配对效果

摘自:《机器学习实战》,用python编写的(需要matplotlib和numpy库)

  海伦一直使用在线约会网站寻找合适自己的约会对象。尽管约会网站会推荐不同的人选,但她没有从中找到喜欢的人。经过一番总结,她发现曾交往过三种类型的人:

  1.不喜欢的人( 以下简称1 );

  2.魅力一般的人( 以下简称2 );

  3.极具魅力的人(以下简称3 )

  尽管发现了上述规律,但海伦依然无法将约会网站推荐的匹配对象归入恰当的分类。她觉得可以在周一到周五约会哪些魅力一般的人,而周末则更喜欢与那些极具魅力的人为伴。海伦希望我们的分类软件可以更好的帮助她将匹配对象划分到确切的分类中。此外海伦还收集了一些约会网站未曾记录的数据信息,她认为这些数据更有助于匹配对象的归类。

我们先提取一下这个案例的目标:根据一些数据信息,对指定人选进行分类(1或2或3)。为了使用kNN算法达到这个目标,我们需要哪些信息?前面提到过,就是需要样本数据,仔细阅读我们发现,这些样本数据就是“ 海伦还收集了一些约会网站未曾记录的数据信息 ”。好的,下面我们就开始吧!

----1.收集数据

  海伦收集的数据是记录一个人的三个特征:每年获得的飞行常客里程数;玩视频游戏所消耗的时间百分比;每周消费的冰淇淋公升数。数据是txt格式文件,如下图,前三列依次是三个特征,第四列是分类(1:不喜欢的人,2:魅力一般的人,3:极具魅力的人),每一行代表一个人。

---- 2.准备数据:从文本文件中解析数据

  何为准备数据?之前收集到了数据,放到了txt格式的文档中了,看起来也比较规整,但是计算机并不认识啊。计算机需要从txt文档中读取数据,并把数据进行格式化,也就是说存到矩阵中,用矩阵来承装这些数据,这样才能使用计算机处理。

  需要两个矩阵:一个承装三个特征数据,一个承装对应的分类。于是,我们定义一个函数,函数的输入时数据文档(txt格式),输出为两个矩阵。

代码如下:

简要解读代码:首先打开文件,读取文件的行数,然后初始化之后要返回的两个矩阵(returnMat、classLabelsVector),然后进入循环,将每行的数据各就各位分配给returnMat和classLabelsVector。

  在python命令提示符下面输入以下命令:

----3.分析数据:使用Matplotlib创建散点图

  Matplotlib库提供的scatter函数支持个性化标记散点图上的点。散点图使用了datingDataMat矩阵的第二、三列数据,分别表示特征值“玩视频游戏所耗时间百分比”和“每周所消耗的冰淇淋公升数”。

----4.设计算法:用kNN算法

  k-近邻算法的目的就是找到新数据的前k个邻居,然后根据邻居的分类来确定该数据的分类。

  首先要解决的问题,就是什么是邻居?当然就是“距离”近的了,不同人的距离怎么确定?这个有点抽象,不过我们有每个人的3个特征数据。每个人可以使用这三个特征数据来代替这个人——三维点。比如样本的第一个人就可以用(40920, 8.326976, 0.953952)来代替,并且他的分类是3。那么此时的距离就是点的距离:

  A点(x1, x2, x3),B点(y1, y2, y3),这两个点的距离就是:(x1-y1)^2+(x2-y2)^2+(x3-y3)^2的平方根。求出新数据与样本中每个点的距离,然后进行从小到大排序,前k位的就是k-近邻,然后看看这k位近邻中占得最多的分类是什么,也就获得了最终的答案。

  这个处理过程也是放到一个函数里的,代码如下:

简要解读代码:该函数的4个参数分别为新数据的三个特征inX、样本数据特征集(上一个函数的返回值)、样本数据分类(上一个函数的返回值)、k,函数返回位新数据的分类。第二行dataSetSize获取特征集矩阵的行数,第三行为新数据与样本各个数据的差值,第四行取差值去平方,之后就是再取和,然后平方根。代码中使用的排序函数都是python自带的。

好了,现在我们可以分析数据了,不过,有一点不知道大家有没有注意,我们回到那个数据集,第一列代表的特征数值远远大于其他两项特征,这样在求距离的公式中就会占很大的比重,致使两点的距离很大程度上取决于这个特征,这当然是不公平的,我们需要的三个特征都均平地决定距离,所以我们要对数据进行处理, 希望处理之后既不影响相对大小又可以不失公平 :

这种方法叫做,归一化数值,通过这种方法可以把每一列的取值范围划到0~1或-1~1:,处理的公式为:

  newValue = (oldValue - min)/(max - min)

  归一化数值的函数代码为:

在python命令提示符下,重新加载kNN.py模块,执行autoNorm函数,检测函数的执行结果:

---5.测试算法:作为完整程序验证分类器

  经过了格式化数据、归一化数值,同时我们也已经完成kNN核心算法的函数,现在可以测试了,测试代码为:

通过测试代码我们可以在回忆一下这个例子的整体过程:

  • 读取txt文件,提取里面的数据到datingDataMat、datingLabels;
  • 归一化数据,得到归一化的数据矩阵;
  • 测试数据不止一个,这里需要一个循环,依次对每个测试数据进行分类。

  代码中大家可能不太明白hoRatio是什么。注意,这里的测试数据并不是另外一批数据而是之前的数据集里的一部分,这样我们可以把算法得到的结果和原本的分类进行对比,查看算法的准确度。在这里,海伦提供的数据集又1000行,我们把前100行作为测试数据,后900行作为样本数据集,现在大家应该可以明白hoRatio是什么了吧。

  在python命令提示符下重新加载kNN.py模块,并输入kNN.datingClassTest(),执行分类器测试程序,我们将得到下面的输出结果:

---6.使用算法:构建完整可用系统

  上面我们已经在数据上对分类器进行了测试,现在终于可以使用这个分类器为海伦来对人们分类。我们会给海伦一小段程序,通过改程序海伦会在约会网站上找到某个人并输入他的信息。程序会给出她对对方喜欢程度的预测值。

  将下列代码加入到kNN.py并重新加载kNN.

为了解程序的十几运行效果,输入如下命令:

最后的错误率为0.05。

原文发布于微信公众号 - 大数据挖掘DT数据分析(datadw)

原文发表时间:2016-09-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏机器学习算法全栈工程师

《机器学习》笔记-规则学习(15)

如今机器学习和深度学习如此火热,相信很多像我一样的普通程序猿或者还在大学校园中的同学,一定也想参与其中。不管是出于好奇,还是自身充电,跟上潮流,我觉得都值得试一...

805
来自专栏崔庆才的专栏

浅谈强化学习的方法及学习路线

1717
来自专栏大数据挖掘DT机器学习

极简增强学习新手教程 返回专栏查看评论

“如何学习新技能?”这是一个全球科学家都在研究的基础问题。为什么会想要知道这个问题的答案呐,答对了好处都有啥呢? 因为一旦我们能够理解这一点,就可以实现一些前...

2775
来自专栏智能算法

蚁群算法(独辟蹊径的进化算法)

1. 算法背景——蚁群的自组织行为特征 高度结构化的组织——虽然蚂蚁的个体行为极其简单,但由个体组成的蚁群却构成高度结构化的社会组织,蚂蚁社会的成员有分...

2999
来自专栏小樱的经验随笔

浅谈强化学习的方法及学习路线

介绍 目前,对于全球科学家而言,“如何去学习一种新技能”成为了一个最基本的研究问题。为什么要解决这个问题的初衷是显而易见的,如果我们理解了这个问题,那么我们可以...

3599
来自专栏机器学习算法与Python学习

干货|浅谈强化学习的方法及学习路线

一、介绍 目前,对于全球科学家而言,“如何去学习一种新技能”成为了一个最基本的研究问题。为什么要解决这个问题的初衷是显而易见的,如果我们理解了这个问题,那么我们...

40012
来自专栏大数据文摘

​入门指南 | 人工智能的新希望-强化学习全解

1637
来自专栏AI科技大本营的专栏

技术 | 强化学习入门以及代码实现

介绍 目前,对于全球的科学家而言,“如何去学习一种新技能”已经成为最基本的研究课题之一。解决这个问题的意愿显而易见——如果能够解决这个问题,那么人类就有望做到某...

2977
来自专栏漫漫深度学习路

Probabilistic decoder, Bayesian neural network, Probabilistic encoder

Probabilistic decoder, Bayesian neural network, Probabilistic encoder 最近在看概率模型,看...

17210
来自专栏机器学习和数学

[机器学习] 用KNN识别MNIST手写字符实战

Hi, 好久不见,粉丝涨了不少,我要再不更新,估计要掉粉了,今天有时间把最近做的一些工作做个总结,我用KNN来识别MNIST手写字符,主要是代码部分,全部纯手写...

1183

扫描关注云+社区