机器学习实战k-近邻算法(kNN)应用之改进婚恋网站配对效果代码解

news/2024/5/20 10:48:15/文章来源:https://blog.csdn.net/SCUT_Arucee/article/details/50070765

一.背景简要说明

问题背景不再详细赘述了,《机器学习实战》中有详细介绍,利用KNN想做的就是训练出一个分类器,能根据对方的一些特征判断他(她)对你的吸引程度,是不喜欢,还是一般喜欢,还是很喜欢。以此改进约会配对效果。

二.模块代码及注释

from numpy import *
import operator#样本数据集创建函数
def creatDataSet():dataSet = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])labels = ['A','A','B','B']return dataSet,labels#k-NN简单实现函数
def classify0(inX,dataSet,labels,k):#求出样本集的行数,也就是labels标签的数目dataSetSize = dataSet.shape[0]#构造输入值和样本集的差值矩阵diffMat = tile(inX,(dataSetSize,1)) - dataSet#计算欧式距离sqDiffMat = diffMat**2sqDistances = sqDiffMat.sum(axis=1)distances = sqDistances**0.5#求距离从小到大排序的序号sortedDistIndicies = distances.argsort()#对距离最小的k个点统计对应的样本标签classCount = {}for i in range(k):#取第i+1近邻的样本对应的类别标签voteIlabel = labels[sortedDistIndicies[i]]#以标签为key,标签出现的次数为value将统计到的标签及出现次数写进字典classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1#对字典按value从大到小排序sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)#返回排序后字典中最大value对应的keyreturn sortedClassCount[0][0]#从文本文件中解析数据
def file2matrix(filename):fr = open(filename)#按行读取整个文件的内容arrayOfLines = fr.readlines()#求文件行数,即样本总数numberOfLines = len(arrayOfLines)#初始化返回数组及列表returnMat = zeros((numberOfLines,3))classLabelVector = []index = 0for line in arrayOfLines:#截取掉每一行的回车符line = line.strip()#将一行数据根据制表符分割成包含多个元素(特征)的列表listFromLine = line.split('\t')#分割后的特征数据列表存入待返回的numpy数组returnMat[index,:] = listFromLine[0:3]#将文件每一行最后一列的数据存入待返回的分类标签列表classLabelVector.append(int(listFromLine[-1]))#控制待返回的numpy数组进入下一行index+=1return returnMat,classLabelVector#特征变量归一化
def autoNorm(dataSet):#取出每一列的最小值,即每一个特征的最小值minVals = dataSet.min(0)#取出每一列的最大值,即每一个特征的最大值maxVals = dataSet.max(0)#每一个特征变量的变化范围ranges = maxVals - minVals#初始化待返回的归一化特征数据集normDataSet = zeros(shape(dataSet))#特征数据集行数,即样本个数m = dataSet.shape[0]#利用tile()函数构造与原特征数据集同大小的矩阵,并进行归一化计算normDataSet = dataSet - tile(minVals,(m,1))normDataSet = normDataSet/tile(ranges,(m,1))return normDataSet,ranges,minVals#分类器测试
def datingClassTest():#给定用于测试分类器的样本比例hoRatio = 0.10#调用文本数据解析函数datingDataMat,datingLabels = file2matrix('F:/programming tools/datingTestSet2.txt')#调用特征变量归一化函数normMat,ranges,minVals = autoNorm(datingDataMat)#归一化的特征数据集行数,即样本个数m = normMat.shape[0]#用于测试分类器的测试样本个数numTestVecs = int(m*hoRatio)#初始化分类器犯错样本个数errorCount = 0.0for i in range(numTestVecs):#以测试样本作为输入,测试样本之后的样本作为训练样本,对测试样本进行分类classifierResult = classify0(normMat[i,:],normMat[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]):errorCount+=1.0#输出分类器错误率        print("the total error rate is: %f" % (errorCount/float(numTestVecs)))#约会网站对新输入分类
def classifyPerson():#定义一个存储了三个字符串的列表,分别对应不喜欢,一般喜欢,很喜欢resultList = ['not at all','in small dose','in large dose']#用户输入三个特征变量,并将输入的字符串类型转化为浮点型ffMiles = float(input("frequent flier miles earned per year:"))percentats = float(input("percentage of time spent playing video games:"))iceCream = float(input("liters of ice cream consumed per year:"))#调用文本数据解析函数datingDataMat,datingLabels = file2matrix('F:\programming tools\datingTestSet2.txt')#调用特征变量归一化函数normMat,ranges,minVals = autoNorm(datingDataMat)#将输入的特征变量构造成特征数组(矩阵)形式inArr = array([ffMiles,percentats,iceCream])#调用kNN简单实现函数classifierResult = classify0((inArr-minVals)/ranges,normMat,datingLabels,3)#将分类结果由数字转换为字符串print("You will probably like this person",resultList[classifierResult - 1])


三.详细解读

我们在前面kNN的简单实施代码模块的基础上继续添加需要的函数和方法。

kNN的核心实现代码前面已给出:机器学习实战k-邻近算法(kNN)简单实施代码解读

新增了4个函数或方法,分别是文本文件解析函数file2matrix,特征变量归一化函数autoNorm,分类器测试方法datingClassTest以及分类器最终对新输入进行分类的方法classifyPerson。

1.文本文件解析函数file2matrix

接受一个参数,即待解析的文件名,注意传入的时候要带上后缀名,如:xxx.txt,否则会说该目录下没有指定文件。

★arrayOfLines = fr.readlines()
按行读取整个文件的内容,返回一个列表,文件的每一行数据以字符串的形式作为列表的一个元素,故numberOfLines = len(arrayOfLines)求出列表元素的数目,也就是文本一共有多少行数据。

python中需要注意.read(),.readline()和.readlines()的区别,以如下test.txt为例



①.read()是一次读取整个文件的内容,并把 文件内容放到一个字符串变量中 。如下:



.readline()每次读取文件的一行,将读取到的一行内容放到一个字符串变量中,再次调用时会继续读下一行。如下:



.readlines()每次按行读取整个文件内容,将读取到的内容放到一个列表中,文件每一行内容以字符串的形式作为列表的一个元素。如下:



注意:hello world下方有三行空行的原因是文件每行结尾都有一个换行符(除了最后一行),再加上print()本身输出一个元素后会自动换行。

line = line.strip()
按行读取文本内容时,截取掉每一行的回车符。如下:



listFromLine = line.split('\t')
将一行数据根据制表符分割成包含一个或多个元素(特征)的列表,例如如下的test文件中第三行python与3.4之间存在制表符,则这一行返回的列表包含两个元素,每个元素都是一个字符串,其几行因为没有制表符,故返回的是只含有一个元素的列表。对列表直接print的结果和对列表按元素print的结果也是不同的。应用这条语句的目的是把文件中每行以制表符分隔开的多个特征数据分别作为一个元素提取到列表中。



returnMat[index,:] = listFromLine[0:3]
将分割后的特征数据列表存入待返回的numpy数组。这里只存前3列的数据,因为前3列代表特征变量,最后一列是分类标签。

classLabelVector.append(int(listFromLine[-1]))
将文件每一行最后一列的数据存入待返回的分类标签列表,我们提取到的是字符串形式的标签,要转换为整型后再存入代表分类标签的列表。

2.特征变量归一化函数autoNorm

使用特征变量归一化的目的是在计算欧式距离时防止那些数字差值很大的特征变量对计算结果的影响太大,尽量维持特征的等权重,不让某一个特征对分类结果的影响明显大于其他特征。利用下面的公式将任意取值范围的特征值转换为0到1区间内的值:
newValue = (oldValue-min) / (max-min)                      (☆)

minVals = dataSet.min(0)
取出每一列的最小值,即每一个特征的最小值。

maxVals = dataSet.max(0)
取出每一列的最大值,即每一个特征的最大值。.min(0)和.max(0)里的0代表按列取最小值和最大值,若要取出每一行的最小或最大值则要使用.min(1)或.max(1)。

normDataSet = zeros(shape(dataSet))
初始化待返回的归一化特征数据集,shape以一个元组的形式返回dataSet的行数m和列数3。zero((m,3))将其初始化为一个m行3列的全0矩阵。

normDataSet = dataSet - tile(minVals,(m,1))
normDataSet = normDataSet/tile(ranges,(m,1))
利用tile()函数构造与原特征数据集同大小的矩阵,并利用(☆)式进行归一化计算。
关于tile()的用法,前面已经提到,这里再给出链接,numpy库tile用法。

3.分类器测试函数datingClassTest

将一些分类标签已知的测试样本输入分类器,比较分类器的输出结果和样本的实际分类标签,以测试分类器的错误率。错误率=对测试样本分类出错的个数/测试样本总数。

hoRatio = 0.10
给定用于测试分类器的样本比例为0.1,另外90%的样本作为训练样本。

datingDataMat,datingLabels = file2matrix('F:/programming tools/datingTestSet2.txt')
调用文本数据解析函数,得到特征变量和分类标签。

normMat,ranges,minVals = autoNorm(datingDataMat)
调用特征变量归一化函数,得到归一化的特征变量,每一个特征的范围,每一个特征的最小值。

numTestVecs = int(m*hoRatio)
求出用于测试分类器的测试样本个数,因为样本个数必须为整数,故使用int取整。

classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)
以测试样本作为输入,测试样本之后的样本作为训练样本,对测试样本进行分类。这里调用了kNN简单实现函数classify0。
normMat[i,:]为当前的测试样本归一化的输入特征,normMat[numTestVecs:m,:]为训练样本归一化的特征矩阵,datingLabels[numTestVecs:m]为与之对应的训练样本的分类标签向量,3代表k的取值,实际操作时可以自行更改。


4.约会网站预测函数classifyPerson

resultList = ['not at all','in small dose','in large dose']
定义一个存储了三个字符串的列表,分别对应不喜欢,一般喜欢,很喜欢

ffMiles = float(input("frequent flier miles earned per year:"))
   percentats = float(input("percentage of time spent playing video games:"))
   iceCream = float(input("liters of ice cream consumed per year:"))
注意这里用户输入的东西会被当成是字符串,所以一定要转换为我们需要的类型。

inArr = array([ffMiles,percentats,iceCream])
将输入的特征变量构造成特征数组(矩阵)形式。

classifierResult = classify0((inArr-minVals)/ranges,normMat,datingLabels,3)
调用kNN简单实现函数对新的输入进行分类,注意要将输入特征归一化。

print("You will probably like this person",resultList[classifierResult - 1])
将分类结果由数字转换为字符串。

四.运行结果


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

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

相关文章

我在B站学通过HUGO搭建网站

我在下载主题的时候遇到了GIT的问题, 错误是 git不是本地或内部指令 1、新建一个目录,存放下载下来的项目,我在D盘新建了一个“gitspace”文件夹,用来存放下载下来的项目 2、进入刚刚新建的文件夹,即进入“gitspace”…

基于vue框架Vant UI组件库移动端电商网站webapp项目总结

项目总结 一、项目名称 电商网站webapp开发二、技术栈 框架:vue框架 UI组件:Vant移动端Vue组件库安装:npm install vant -S项目中引用的部分组件:1、Tabbar标签栏:封装成底部标签栏,引入到其他组件中&am…

合作网站

我有兴趣并且现在也学习的不错了,html ,asp还自我感觉可以,做了一两个网站都是一两个页面,现在是在想真正做一个好的,但是一个人是很难做出来的。 没有时间,每天还得搞定那几门功课,所以想和志同…

nginx启用gzip(提升网站性能)

nginx服务器启用gzip可以对客户端请求的资源进行压缩,从而减少带宽和文件下载时间,提升网站加载速度。nginx关于gzip的配置内容如下: # 开启gzipgzip on;# 允许压缩文件的最小字节数,大于该阈值即可被压缩gzip_min_length 1024;# …

基于element的网站自适应方案(移动端适配)

一般而言,管理系统类的网站我们往往会按照PC的标准来设计,不会去考虑小屏幕的适配,甚至是移动端的适配,因为这种系统网站往往涉及到大量的列表查询页(表格列往往很多,列内容长短不一)&#xff0…

ASP.net 网站开发知识点总结

一、常用技术概括及介绍 1. SQL server:处理数据库的设计 2. asp.net 3. html :前端网页 4. css     :网页的布局设计 5. JavaScript :能够更好的操作页面 6. jQuery : 7. ajax    :处理局…

SEO大事件:百度站长平台推出新站加速收录计划!

近日,在百度推出飓风算法,蝶变行动后,百度站长平台又悄然推出了一个小工具,对于中小站长可谓是大大的福音,很多刚刚从事SEO行业的小伙伴,经常发现向百度提交一个全新的网站,站点链接收录特别缓慢…

SEO价值匹配策略

在解释这个策略之前,我们首先要了解,什么是有价值的东西。100元对你也许很有价值,但是对于百万富翁来说,也许根本不值得一提;小米手机对你来说很有价值,但是对于苹果手机爱好者来说,小米要差很多…

SEO营销思维:名利借力策略

大部分人在生活中追求的无非就是名和利,我们在做网站SEO的时候,可以利用这点把自己的网站做得更好。很多人有这样的苦恼: 1、自己有产品,但是产品没有名气,不懂如何在互联网推广。 2、自己有名气,但是没有自…

从零开始学SEO的基础概念

SEO的意思是搜索引擎优化,它一般由两部分组成:站内优化和站外优化。站内优化主要是指通过网站技术、网站内容结构、域名、服务器和代码等操作,促使用户的网站能够在百度搜索引擎当中获得更好的排名;而站外优化可以理解为&#xff…

一个金融行业站SEO优化方案分析

前面写了两篇文章被大家评定为内容过于基础,建议添加一些实战案例。今天深圳seo就把自己的一个金融站的实战案例分享给大家。 网站目的:1、外币兑换业务  2、网站要有一定的流量 3、提升权重以便以后开展其它业务 策略:因为外币兑换与汇率…

抖音seo源码搭建 抖音矩阵系统具体功能展示?

抖音seo源码搭建,抖音矩阵系统: 抖音SEO和百度SEO、360SEO、搜狗SEO 其实就是换汤不换药,很多时候去了解这个SEO的时候,也不要去局限于它只是做抖音还是做小红书或知乎等。 我们不仅仅是去了解这个平台,同时更要去了解…

短视频seo源码账号矩阵程序开发搭建?短视频seo矩阵搜索技术

短视频seo源码账号矩阵程序开发搭建?短视频seo矩阵搜索技术 短视频seo源码账号矩阵程序开发搭建?短视频seo矩阵搜索技术如何部署? 首先什么是短视频搜索短视频SEO? 用户通过短视频平台在搜索框去做搜索的时候输入关键词&#xff…

抖音seo源码二次开发,短视频seo源码二次开发

抖音seo源码二次开发,短视频seo源码二次开发 抖音seo这套系统除了前端搭建,以及视频制作板块(视频制作包括智能云剪辑、智能渲染去重,云端数字人),其他的功能板块视频定时发布,视频分发&#x…

抖音seo矩阵系统,抖音矩阵系统源码怎么搭建?

抖音seo矩阵系统,抖音矩阵系统源码怎么搭建? 抖音seo矩阵系统,抖音矩阵系统源码怎么搭建?抖音矩阵系统即是在抖音平台的基础上进行多账号的布局,形成客户不论搜索账号,视频以及关键词视频时,平…

介绍一下关于goodnotes,notability的手帐笔记素材的网站,含有A4大量的打印纸,电子手帐,贴图,便签,字体

官网:http://www.bishua666.com/a4做了ipad等等移动端的适配 1.提供各种A4打印纸模板,可以导出图片,pdf到打印机方便打印,打印纸类型有日程计划,练字书法,清单,财务,音乐,艾宾浩斯,康内尔 2.提供数百款GoodNotes和Notability等笔记类的应用类别手帐笔记模板pdf,pdf模板可以转图…

javascript跨域_您网站的Javascript跨域API

javascript跨域 Javascript cross-domain api for your website Welcome our readers. Today I would like to give a small but very important lesson where we will create our own cross-domain javascript api. I think that many of you have already tried to implement…

如何使用Akismet保护任何网站免受垃圾邮件的侵害

Akismet – spam protection. Today we will continue PHP lessons. And today we will talk about spam protection. I think every one have own website, and every one faced with appearing of unwanted content on the site (spam). What is spam? – this is (usually)…

通过phpstudy搭建简单的网站

1.简单一键构建:下载phpstudy,开启Apache2.4.39和MySQL5.7.26 选择软件管理--网站程序,选择自己想搭建的网站类型,点击一键部署,设置账户密码,搭建成功 2.如果中途报错,或者端口组冲突&#x…

linux宝塔新建站点

网上查了各种资料,绕了一大圈。有的说域名解析有问题,有的说端口问题,说的都是什么鬼东西啊。我特此在此记录下我自己找到的方法(做个笔记)。 首先新建立站点如图: 准备步骤:不管有没有域名你都…