k-近邻算法(改进约会网站的配对效果)

news/2024/5/11 0:51:19/文章来源:https://blog.csdn.net/lcl497049972/article/details/97946280

示例背景:

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

(1)不喜欢的人;

(2)魅力一般的人;

(3)极具魅力的人;

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

 

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

海伦收集约会数据已经有了一段时间,她把这些数据存放在文本文件datingTestSet.txt中,每个样本数据占据一行,总共有1000行。海伦的样本主要包括以下3种特征:

1.每年获得的飞行常客里程数;

2.玩视频游戏所耗时间百分比;

3.每周消费的冰淇淋公升数;

在将上述特征数据输入到分类器之前,必须将待处理数据的格式改变为分类器可以接受的格式。在kNN.py中创建名为file2matrix的函数,以此来处理输入格式问题。该函数的输入为文本文件名字符串,输出为训练样本矩阵和类标签向量。

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

import matplotlib as mpl
import matplotlib.pyplot as plt
import operatordef file2matrix(filename):  #获取数据f = open(filename)arrayOLines = f.readlines()numberOfLines = len(arrayOLines)returnMat = zeros((numberOfLines,3),dtype=float)#zeros(shape, dtype, order),创建一个shape大小的全为0矩阵,dtype是数据类型,默认为float,#order表示在内存中排列的方式(以C语言或Fortran语言方式排列),默认为C语言排列classLabelVector = []rowIndex = 0for line in arrayOLines:line = line.strip()listFormLine = line.split('\t')returnMat[rowIndex,:] = listFormLine[0:3]classLabelVector.append(int(listFormLine[-1]))rowIndex += 1return returnMat, classLabelVectorif __name__ == "__main__":datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')fig = plt.figure()  #图mpl.rcParams['font.sans-serif'] = ['KaiTi']mpl.rcParams['font.serif'] = ['KaiTi']plt.xlabel('玩视频游戏所耗时间百分比')plt.ylabel('每周消费的冰淇淋公升数')'''matplotlib.pyplot.ylabel(s, *args, **kwargs)override = {'fontsize'            : 'small','verticalalignment'   : 'center','horizontalalignment' : 'right','rotation'='vertical' : }'''ax = fig.add_subplot(111) #将图分成1行1列,当前坐标系位于第1块处(这里总共也就1块)ax.scatter(datingDataMat[: ,1], datingDataMat[: ,2],15.0*array(datingLabels), 15.0*array(datingLabels))#scatter是用来画散点图的# scatter(x,y,s=1,c="g",marker="s",linewidths=0)# s:散列点的大小,c:散列点的颜色,marker:形状,linewidths:边框宽度plt.show()

 

这是简单的创建了一下散点图,可以看到上面的图中还缺少了图例,所以下面的代码以另两列数据为例创建了带图例的散点图,代码大致还是一样的:

from numpy import *
import matplotlib as mpl
import matplotlib.pyplot as plt
import operatordef file2matrix(filename):  #获取数据f = open(filename)arrayOLines = f.readlines()numberOfLines = len(arrayOLines)returnMat = zeros((numberOfLines,3),dtype=float)#zeros(shape, dtype, order),创建一个shape大小的全为0矩阵,dtype是数据类型,默认为float,order表示在内存中排列的方式(以C语言或Fortran语言方式排列),默认为C语言排列classLabelVector = []rowIndex = 0for line in arrayOLines:line = line.strip()listFormLine = line.split('\t')returnMat[rowIndex,:] = listFormLine[0:3]classLabelVector.append(int(listFormLine[-1]))rowIndex += 1return returnMat, classLabelVectorif __name__ == "__main__":datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')fig = plt.figure()  #图plt.title('散点分析图')mpl.rcParams['font.sans-serif'] = ['KaiTi']mpl.rcParams['font.serif'] = ['KaiTi']plt.xlabel('每年获取的飞行常客里程数')plt.ylabel('玩视频游戏所耗时间百分比')'''matplotlib.pyplot.ylabel(s, *args, **kwargs)override = {'fontsize'            : 'small','verticalalignment'   : 'center','horizontalalignment' : 'right','rotation'='vertical' : }'''type1_x = []type1_y = []type2_x = []type2_y = []type3_x = []type3_y = []ax = fig.add_subplot(111) #将图分成1行1列,当前坐标系位于第1块处(这里总共也就1块)index = 0for label in datingLabels:if label == 1:type1_x.append(datingDataMat[index][0])type1_y.append(datingDataMat[index][1])elif label == 2:type2_x.append(datingDataMat[index][0])type2_y.append(datingDataMat[index][1])elif label == 3:type3_x.append(datingDataMat[index][0])type3_y.append(datingDataMat[index][1])index += 1type1 = ax.scatter(type1_x, type1_y, s=30, c='b')type2 = ax.scatter(type2_x, type2_y, s=40, c='r')type3 = ax.scatter(type3_x, type3_y, s=50, c='y', marker=(3,1))'''scatter是用来画散点图的matplotlib.pyplot.scatter(x, y, s=20, c='b', marker='o', cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, verts=None, hold=None,**kwargs)其中,xy是点的坐标,s点的大小maker是形状可以maker=(5,1)5表示形状是5边型,1表示是星型(0表示多边形,2放射型,3圆形)alpha表示透明度;facecolor=‘none’表示不填充。'''ax.legend((type1, type2, type3), ('不喜欢', '魅力一般', '极具魅力'), loc=0)'''loc(设置图例显示的位置)'best'         : 0, (only implemented for axes legends)(自适应方式)'upper right'  : 1,'upper left'   : 2,'lower left'   : 3,'lower right'  : 4,'right'        : 5,'center left'  : 6,'center right' : 7,'lower center' : 8,'upper center' : 9,'center'       : 10,'''plt.show()

 

准备数据:归一化数值

当我们计算样本之间的欧几里得距离时,由于有些数值较大,所以它对结果整体的影响也就越大,那么小数据的可能就毫无影响了。在这个例子中飞行常客里程数很大,然而其余两列数据很小。为了解决这个问题,需要把数据相应的进行比例兑换,也就是这里需要做的归一化数值,将所有数值转化为[0,1]之间的值。

公式为:
newValue=(oldValue−min)/(max−min)newValue=(oldValue−min)/(max−min)   (minmin和maxmax分别是数据集中的最小特征值和最大特征值)

def autoNorm(dataSet): #归一化数值minVals = dataSet.min(0)  #0表示每列的最小值,1表示每行的最小值,以一维矩阵形式返回maxVals = dataSet.max(0)ranges = maxVals - minValsnormDataSet = zeros(shape(dataSet))m = dataSet.shape[0]normDataSet = dataSet - tile(minVals, (m,1))normDataSet = normDataSet/tile(ranges, (m,1))return normDataSet, ranges, minVals

测试并构造完整算法

根据这1000个数据,将其中的100个作为测试数据,另900个作为训练集,看着100个数据集的正确率。

最后根据自己输入的测试数据来判断应该出现的结果是什么。

from numpy import *
import matplotlib as mpl
import matplotlib.pyplot as plt
import operatordef classify0(inX, dataSet, labels, k):dataSetSize = dataSet.shape[0]diffMat = tile(inX, (dataSetSize,1)) - dataSet  #统一矩阵,实现加减sqDiffMat = diffMat**2sqDistances = sqDiffMat.sum(axis=1)  #进行累加,axis=0是按列,axis=1是按行distances = sqDistances**0.5  #开根号sortedDistIndicies = distances.argsort()  #按升序进行排序,返回原下标classCount = {}for i in range(k):voteIlabel = labels[sortedDistIndicies[i]]classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1  #get是字典中的方法,前面是要获得的值,后面是若该值不存在时的默认值sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)return sortedClassCount[0][0]def file2matrix(filename):  #获取数据f = open(filename)arrayOLines = f.readlines()numberOfLines = len(arrayOLines)returnMat = zeros((numberOfLines,3),dtype=float)#zeros(shape, dtype, order),创建一个shape大小的全为0矩阵,dtype是数据类型,默认为float,order表示在内存中排列的方式(以C语言或Fortran语言方式排列),默认为C语言排列classLabelVector = []rowIndex = 0for line in arrayOLines:line = line.strip()listFormLine = line.split('\t')returnMat[rowIndex,:] = listFormLine[0:3]classLabelVector.append(int(listFormLine[-1]))rowIndex += 1return returnMat, classLabelVectordef autoNorm(dataSet): #归一化数值minVals = dataSet.min(0)  #0表示每列的最小值,1表示每行的最小值,以一维矩阵形式返回maxVals = dataSet.max(0)ranges = maxVals - minValsnormDataSet = zeros(shape(dataSet))m = dataSet.shape[0]normDataSet = dataSet - tile(minVals, (m,1))normDataSet = normDataSet/tile(ranges, (m,1))return normDataSet, ranges, minValsdef datingClassTest(datingDataMat, datingLabels):  #测试正确率hoRatio = 0.1m = datingDataMat.shape[0]numTestVecs = int(hoRatio*m)numError = 0.0for i in range(numTestVecs):classifierResult = classify0(datingDataMat[i,:], datingDataMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3)print('The classifier came back with: %d, the real answer is: %d.' %(classifierResult, datingLabels[i]))if (classifierResult != datingLabels[i]):numError += 1print('错误率为 %f' %(numError/float(numTestVecs)))def classifyPerson(datingDataMat, datingLabels, ranges, minVals):result = ['not at all', 'in small doses', 'in large doses']print('请输入相应信息:')percentTats = float(input('percentage of time spent playing video games?'))ffMiles = float(input('frequent flier miles earned per year?'))iceCream = float(input('liters of ice cream consumed per year?'))inArr = array([ffMiles, percentTats, iceCream])classifyResult = classify0((inArr-minVals)/ranges, datingDataMat, datingLabels, 3)print('You will probably like this person: ', result[classifyResult-1])if __name__ == "__main__":datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')datingDataMat, ranges, minVals = autoNorm(datingDataMat) #归一化数值datingClassTest(datingDataMat, datingLabels)classifyPerson(datingDataMat, datingLabels, ranges, minVals)fig = plt.figure()  #图plt.title('散点分析图')mpl.rcParams['font.sans-serif'] = ['KaiTi']mpl.rcParams['font.serif'] = ['KaiTi']plt.xlabel('每年获取的飞行常客里程数')plt.ylabel('玩视频游戏所耗时间百分比')'''matplotlib.pyplot.ylabel(s, *args, **kwargs)override = {'fontsize'            : 'small','verticalalignment'   : 'center','horizontalalignment' : 'right','rotation'='vertical' : }'''type1_x = []type1_y = []type2_x = []type2_y = []type3_x = []type3_y = []ax = fig.add_subplot(111) #将图分成1行1列,当前坐标系位于第1块处(这里总共也就1块)index = 0for label in datingLabels:if label == 1:type1_x.append(datingDataMat[index][0])type1_y.append(datingDataMat[index][1])elif label == 2:type2_x.append(datingDataMat[index][0])type2_y.append(datingDataMat[index][1])elif label == 3:type3_x.append(datingDataMat[index][0])type3_y.append(datingDataMat[index][1])index += 1type1 = ax.scatter(type1_x, type1_y, s=30, c='b')type2 = ax.scatter(type2_x, type2_y, s=40, c='r')type3 = ax.scatter(type3_x, type3_y, s=50, c='y', marker=(3,1))'''scatter是用来画散点图的matplotlib.pyplot.scatter(x, y, s=20, c='b', marker='o', cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, verts=None, hold=None,**kwargs)其中,xy是点的坐标,s点的大小maker是形状可以maker=(5,1)5表示形状是5边型,1表示是星型(0表示多边形,2放射型,3圆形)alpha表示透明度;facecolor=‘none’表示不填充。'''ax.legend((type1, type2, type3), ('不喜欢', '魅力一般', '极具魅力'), loc=0)'''loc(设置图例显示的位置)'best'         : 0, (only implemented for axes legends)(自适应方式)'upper right'  : 1,'upper left'   : 2,'lower left'   : 3,'lower right'  : 4,'right'        : 5,'center left'  : 6,'center right' : 7,'lower center' : 8,'upper center' : 9,'center'       : 10,'''plt.show()

可以看到错误率为5%:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_805878.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何从优酷、土豆、56.com/等网站下视频

写这篇博客的原因本人比较喜欢在网上看一些小视频,搞笑视频、微电影什么的,比如像人人的分享视频、优酷的TED视频和最近出的的原创经典神马的,当你看到一个比较好的视频的时候,自然是想把他下下来收藏喽,下面是我收集的…

【大型网站技术实践】初级篇:搭建MySQL主从复制经典架构

随笔- 80 文章- 1 评论- 531 【大型网站技术实践】初级篇:搭建MySQL主从复制经典架构 一、业务发展驱动数据发展 随着网站业务的不断发展,用户量的不断增加,数据量成倍地增长,数据库的访问量也呈线性地增长。特别是在用户访问高…

ASP.NET网站实现中英文转换(本地化资源)

主要内容: 1. 简单例子 2. 进一步认识Localization 3. 语言转换 4. 解决方案 一. 简单例子 下面通过一个简单的例子来说明利用Localization来实现本地化是那么的简单,首先我们打开Visual Studio 2005,新建一个名叫Localization的工程&#xf…

大型网站框架的演变

大型网站框架的演变 之前也有一些介绍大型网站架构演变的文章,例如LiveJournal的、ebay的,都是非常值得参考的,不过感觉他们讲的更多的是每次演变的结果,而没有很详细的讲为什么需要做这样的演变,再加上近来感觉有不少…

10个提供免费PHP脚本下载的网站

1.PHP Junkyard 这里提供免费的PHP脚本下载。包括PHP资源,教程,文章等等。 2.Free-Php.net Free-Php.net 为你提供分类列表,包括免费的PHP脚本,商业PHP脚本,PHP资源,PHP教程,网页资源&#xff0…

Https网站搭建——通过https://localhost:8443访问tomcat首页

图片大致介绍了Https浏览器与服务器握手的过程,涉及到的名词:证书、Hash算法、随机数密码、公钥加密、私钥解密、握手消息、hash验证、摘要 tomcat服务器配置可以实现https双向认证,简单起见,我们只实现单向认证,过程&…

网站流量分析及网络营销方法-小经验

做了一段网站,经常上站长网。也学习到了不少东西,但是本人还是和大家一样始终是一个技术出身的programmer. 所以有小经验的话,还是应该写在博客园,给自家人看。管理大师德鲁克教导我们:没有测量就没有管理(…

Linux下Web服务器应用之网站安全-https

Linux下Web服务器应用之网站安全(https)解决方案 HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础…

网站访问统计系统 piwik

piwik官网地址:http://piwik.org/ Piwik是一套基于PhpMySQL技术构建的开源网站访问统计系统,前身是phpMyVisites。Piwik可以给你详细的统计信息,比如网页 浏览人数, 访问最多的页面, 搜索引擎关键词等等,并且采用了大量的AJAX/Flash技术&…

网站前端性能优化总结【转】

一、服务器侧优化 1. 添加 Expires 或 Cache-Control 信息头 某些经常使用到、并且不会经常做改动的图片(banner、logo等等)、静态文件(登录首页、说明文档等)可以设置较长的有效期(expiration date)&…

网站性能工具Yslow的使用方法

Yslow是雅虎开发的基于网页性能分析浏览器插件,从年初我使用了YSlow后,改变了博客模板大量冗余代码,不仅提升了网页的打开速度,这款插件还帮助我分析了不少其他网站的代码,之前我还特意写了提高网站速度的秘籍&#xf…

10款方便的在线文件格式转换工具网站。

1.online-convert online-convert是一个十分优秀的在线格式转换应用,支持格式覆盖文档、图片、音频、视频、电子书、Flash以及一些 不常见的格式。使用非常简单,你只需根据在你想转换成的格式的分类(如文档的在document converter&#xff09…

获得alexa网站下面美国排名前二十的网址

为什么80%的码农都做不了架构师&#xff1f;>>> #!/usr/bin/python #encoding:utf8 #author:cosmeimport re import urllibdef getTop25ReginalSties():GETTOP25 re.compile(r^\<a\shref\\"/siteinfo/(?P<gettop>\S)\"\>\S\</a\>.*)…

最新70佳单页网站设计案例欣赏(中篇)

单页网站是指只有一个页面的网站&#xff0c;这种形式的网站曾经非常流行&#xff0c;现在依然有很多人喜欢。不过&#xff0c;并不是每个网站都适合做成单页&#xff0c;一般都是内容比较少而且将来内容也不怎么增加的情况才适合这样做。如果你打算做一个这样的网站&#xff0…

(转载)让网站变灰的CSS代码(支持IE、FIREFOX和CHROME)

2019独角兽企业重金招聘Python工程师标准>>> <p style"margin: 20px 0px; font-size: 1.2em; line-height: 1.8; font-family: Tahoma, Verdana, 宋体; color: #525252;">原文&#xff1a;<a href"http://www.uisdc.com/gray-css-code"…

从两个服务器访问相同网站

目标: 从两台服务器访问同一个网站. 模型: 服务器A , 服务器B 上运行apache 安装php 服务器C 上保存网页文件, 及运行Mysql数据库 大致流程: 服务器C 建立网页存放目录和Mysql数据目录 启用 nfs 服务 并共享网页存放…

从杨致远辞去雅虎说起,那些衰落的网站巨头给我们的启示

盘点一下近些年衰落的互联网巨头 雅虎---无可置疑排名第一位&#xff0c;昔日的互联网霸主99年市值超过1200亿美金&#xff0c;记得小时候看过一个动画片&#xff0c;里面经常有个大猩猩叫“yahoo”哈哈&#xff0c;从哪个时候雅虎成为我第一知道的互联网品牌&#xff0c;但是今…

我的.Net电子商务网站第一步 - UI

决定要做一个电子商务网站&#xff0c;一直以来都觉得自己美工很烂&#xff0c;那先从美工入手吧&#xff01; 折腾了2天之后&#xff0c;有了最初的效果&#xff0c;在线demo请点击&#xff1a;http://byyee.com/software/shoppingmall/ 网站用的是国外空间&#xff0c;如果访…

自主服务器详细发布网站教程,能上网即可以做网站服务

很多人只知道固定公网IP发布网站&#xff0c;动态IP时甚至无公网IP时&#xff0c;如何发布网站呢&#xff1f;根据不同的网络环境分析不同的发布网站方式。一&#xff0c;固定公网IP时。通过dnspod或nat123域名解析&#xff0c;将域名解析到网站主机IP即可。二&#xff0c;动态…

IIS发布asp.net网站出现的错误

1、 【转】配置错误 不能在此路径中使用此配置节 配置错误 不能在此路径中使用此配置节(转)2011年12月29日 11:22 配 置错误 不能在此路径中使用此配置节。如果在父级别上锁定了该节&#xff0c;便会出现这种情况。锁定是默认设置的 (overrideModeDefault"Deny")&…