目录

K-近邻算法实战(二):约会网站配对效果判断

实战

1.背景介绍

2.准备数据:数据分类

3.分析数据:数据可视化

4.准备数据:数据归一化

5.测试算法:验证分类器

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


K-近邻算法实战(二):约会网站配对效果判断

一般的K-近邻算法流程:

1.收集数据:方法有爬虫进行数据收集或是使用第三方提供的数据

2.准备数据:用Python解析、预处理数据

3.分析数据:对数据进行分析,例如使用Matplotlib将数据可视化

4.测试算法:计算算法的错误率

5.使用算法:在错误率可接受的范围内,运用k-近邻算法进行分类

实战

1.背景介绍

线上网站寻找适合自己的约会对象,海伦女士对自己的喜好进行一番总结,她发现可以将交往过的人进行如下分类:

1.不喜欢的人

2.魅力一般的人

3.极具魅力的人

海伦收集交往过的人的数据主要包含3个特征:

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

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

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

采用的数据集包含三个特征和一个喜欢的类型,放在文本文件datingTesingSet.txt中,数据下载:Machine-Learning/datingTestSet.txt at master · Jack-Cherish/Machine-Learning (github.com)

文件中的数据格式如下:

2.准备数据:数据分类

在机器学习:K-近邻算法(一)_晶哥哥&的博客-CSDN博客中,学习了K-近邻算法的代码实现,就是写成了分类器,那么要使用分类器就要将待处理的数据格式改变为分类器能接受的格式,即特征矩阵和分类标签向量。

(1)编写代码如下:

'''
函数说明:对数据进行分类:1代表不喜欢,2代表魅力一般,3代表极具魅力
输入:文件名(filename)
输出:特征矩阵(returnMat)、分类标签(classLabelVector)
'''def file2matrix(filename):#打开文件file=open(filename)#得到文件的所有内容arrayofLines=file.readlines()#得到文件的行数numberofLines=len(arrayofLines)#初始化返回的特征矩阵,注意这里函数里边的矩阵类型必须加括号returnMat=np.zeros((numberofLines,3))#初始化分类标签向量calssLabelVector=[]#行的索引值index=0for line in arrayofLines:#删除每一行的首尾空白符line=line.strip()#将每一行的内容按照分隔符切片listFormLine=line.split('\t')#将切片后的列表中前三行内容存放到特征矩阵中returnMat[index,:]=listFormLine[0:3]#将文本中的喜欢程度进行分类if listFormLine[-1]=='didntLine':classLabelVector.append(1)elif listFormLine[-1]=='smallDoses':classLabelVector.append(2)elif listFormLine[-1]=='largeDoses':listLabelVector.append(3)index+=1return returnMat,classLabelVector

(2)不会的知识点:

A.文件的readlines()

返回一个列表,将文件中的每一行作为一个列表项

例如:x.txt文件的内容为:

B.字符串的strip()方法

用于删除字符串首尾指定的字符(参数为空时,默认删除空白符,包括:‘\t’,‘\n’,‘\r’,‘ ’)或序列

C.字符串的split()方法

通过指定分隔符来对字符串进行切片

split(str='',num=string.count(str))

str----分隔符,默认为所有空白符,包括:空格、换行、制表符等

num--分割次数,默认为-1,即分割所有

返回值:返回切片后的字符串的列表

(3)测试效果如下:

3.分析数据:数据可视化

将数据进行可视化的方式展示,方便进行观察

(1)编写的代码如下:

'''
函数说明:可视化数据
输入:特征矩阵(datingDataMat)、分类标签向量(datingLables)
'''
def showdatas(datingDataMat,datingLabels):#设置汉字格式font=FontProperties(fname=r'c:\windows\fonts\simsun.ttc',size=14)#创建画布,将fig画布分割成1行1列,不共享x轴y周,fig画布的到校为(13,8)#nrow=2,ncols=2,代表将fig画布分为四个区域,axs[0][0]表示第一行第一个区域fig,axs=plt.subplots(nrows=2,ncols=2,sharex=False,sharey=False,figsize=(13,8))numberofLabels=len(datingDataMat)LabelsColors=[]#设置标签颜色for i in datingLabels:if i==1:LabelsColors.append('black')if i==2:LabelsColors.append('orange')if i==3:LabelsColors.append('red')#画出散点图1,以特征矩阵的第一列和第二列数据画散点,散点大小为15axs[0][0].scatter(x=datingDataMat[:,0],y=datingDataMat[:,1],color=LabelsColors,s=15,alpha=0.5)#设置标题,x轴label,y轴labelaxs0_title_text=axs[0][0].set_title(u'每年获得的飞行常客里程数与玩视频游戏所消耗时间占比',FontProperties=font)axs0_xlabel_text=axs[0][0].set_xlabel(u'每年获得的飞行常客里程数',FontProperties=font)axs0_ylabel_text=axs[0][0].set_ylabel(u'玩视频游戏所消耗时间占比',FontProperties=font)#设置对象属性plt.setp(axs0_title_text,size=9,weight='blod',color='red')plt.setp(axs0_xlabel_text,size=9,weight='blod',color='black')plt.setp(axs0_ylabel_text,size=9,weight='blod',color='black')#画出散点图2,以特征矩阵的第一列和第三列数据画散点,散点大小为15axs[0][1],scatter(x=datingDataMat[:,0],y=datingDataMat[:,2],s=15,alpha=0.5)#设置标题,x轴label,y轴labelaxs1_title_text=axs[0][1].set_title(u'每年获得的飞行常客里程数与每周消耗的冰淇淋公升数',FontProperties=font)axs1_xlabel_text=axs[0][1].set_xlabel(u'每年获得的飞行常客里程数',FontPreperties=font)axs1_ylabel_text=axs[0][1].set_ylabel(u'每周消耗的冰淇淋公升数',FontProperties=font)#设置对象属性plt.setp(axs1_title_text,size=9,weight='blod',color='red')plt.setp(axs1_xlabel_text,size=9,weight='blod',color='black')plt.setp(axs1_ylabel_text,size=9,weight='blod',color='black')#画出散点图3,以特征矩阵的第二列和第三列数据画散点,散点大小为15axs[1][0].scatter(x=datingDataMat[:,1],y=datingDataMat[:,2],s=15,alpha=0.5)#设置标题,x轴label,y轴labelaxs2_title_text=axs[1][0].set_title(u'玩视频游戏所消耗时间占比与每周消耗的冰淇淋公升数',FontProperties=font)axs2_xlabel_text=axs[1][0].set_xlabel(u'玩视频游戏所消耗时间占比',FontProperteis=font)axs2_ylabel_text=axs[1][0],set_ylabel(u'每周消耗的冰淇淋公升数',FontProperties=font)#设置对象属性plt.setp(set_title_text,size=9,weight='blod',color='red')plt.setp(set_xlabel_text,size=9,weight='blod',color='black')plt.setp(set_ylavel_text,size=9,weight='blod',color='black')#设置图例didntLike=mlines.Line2D([],[],color='black',marker='.',markersize=6,label='didntLike')smallDoses=mlines.Line2D([],[],color='orange',marker='.',markersize=6,label='smallDoses')largeDoses=mlines.Line2D([],[],color='red',marker='.',markersize=6,label='largeDoses')#添加图例axs[0][0].legend(handles=[didntLike,smallDoses,largeDoses])axs[0][1].legend(handles=[didntLike,smallDoses,largeDoses])axs[1][0].legend(handles=[didntLike,smallDoses,largeDoses])#显示图片plt.show()

(2)不会的知识点

A.字符串前缀符r和u

在字符串前加r,表明这些字符是原生字符

对于原生字符的理解跟转义字符有关:

在字符串前加u,python2中用在字符串前,放置中文乱码,python3中所有的字符串默认都是unicode字符串

B.画散点图,使用创建子图的scattor()时,设置散点大小的关键字是s,不是size

C.plt.setp()用于设置对象属性

(3)代码实现结果如下:

4.准备数据:数据归一化

为什么要进行数据归一化?计算下面样本1和样本2之间的距离,使用欧式距离公式。

样本 每年获得的飞行常客里程数 玩视频游戏消耗时间占比 每周消费的冰淇淋公升数 样本分类
1 134000 12 0.9 3
2 32000 67 0.1 2

计算公式为:

从公式上可以看出,数字差值越大对计算结果影响越大,那么对于本项目来说,顾客飞行里程数这一特征比其他两个特征对结果的影响大且远远大,出现这样情况的原因是由于,飞行里程数的数量级远远大于另外两个特征,对于海伦来说三个特征同等重要。

处理这种不同取值范围的特征时,通常采用将数据归一化,将任意取值范围的特征值转化为0到1之间或-1到1之间,本次采用0到1之间。

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

注:改变数值的取值范围会增加分类器的复杂度,但为了得到准确结果,必须这样做。

(1)编写代码如下:

'''
函数说明:将训练集的数据进行归一化
输入:特征矩阵(dataSet)
输出:归一化后的特征矩阵(normDataSet)数据范围(ranges)数据最小值(minVals)
'''def autoNorm(dataSet):#获取数据的最大值和最小值minVals=dataSet.min(0)maxVals=dataSet.max(0)#获取最大值和最小值的范围ranges=maxVals-minVals#初始化归一化后的特征矩阵normDataSet=np.zeros(np.shape(dataSet))#获取dataSet的行数m=dataSet.shape[0]#原数据减去最小值normDataSet=dataSet-np.tile(minVals,(m,1))#再除以最大值与最小值的差normDataSet=normDataSet/np.tile(ranges,(m,1))#返回归一化后的特征值,数据范围,最小值return normDataSet,ranges,minVals

(2)不会的知识点:

A.列表的内置函数min()和max()

对于列表---->max(list)得到列表中最大的值,min()也是

对于二维矩阵--->假如x是一个4行3列的二维矩阵

x.mix(0)返回的列表是由每一列中的最小元素组成的,列表中元素个数为3

x.min(1)返回的列表是由每一行中的最小元素组成的,列表中元素个数为4

B.numpy的shape()

np.shape(x)返回x矩阵的行数和列数

x.shape[0]返回x矩阵的行数

x.shape[1]返回x矩阵的列数

(3)测试效果如下:

5.测试算法:验证分类器

机器学习算法对于评估算法正确率的缓解是必不可少的,通常我们会将训练样本的90%的数据来训练分类器,其余10%用来测试分类器,注意10%的测试数据应该是随机选择的。

(1)编写代码如下:

'''
函数说明:测试算法的正确率
输入:无
输出:打印出正确率
注:这里调用前面写好的代码块
分类特征矩阵和标签向量的函数---file2matrix(filename)
将数据归一化的函数---autoNorm(datingSet)
分类器函数(在前一篇文章KNN(一)中)----classify0(inX,dataSet,labels,k)
'''def datingClassTest():filename='datingTestSet.txt'#获取特征矩阵和分类标签向量datingDataMat,datingLabels=file2matrix(filename)#设置测试数据百分比hoRatio=0.10#将数据归一化,返回归一化后的矩阵,数据范围,数据最小值normMat,ranges,minVals=autoNorm(datingDataMat)#获取数据的行数m=datingDataMat.shape[0]#得到测试数据的个数numTestVecs=int(m*hoRatio)#初始化错误分类计数errorCount=0.0for i in range(numTestVecs):#前numTestVecs个数据作为测试集,后面的数据做训练集classifierResult=classify0(normMat[i,:],normMat[numTestVecs:,:],datingLabels[numTestVecs:],4)print('分类结果:%d\t真是类别:%d'%(classifierResult,datingLabels[i]))if classifierResult!=datingLabels[i]:erroeCount+=1.0#%%是指字符'%'print('错误率:%f%%'%(errorCount/float(numTestVecs)*100))

(2)测试结果:

通过修改k值和训练集与测试集所占比例会改变错误率。

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

        将前面写的代码段进行整合,写成一个小程序,海伦在网站上将某人的三个特征信息输入,程序就会给出喜欢程度的预测值。

(1)编写的代码如下:

'''
函数说明:KNN算法,分类器
'''
import numpy as npdef classify0(inX,dataSet,labels,k):#获取dataSet的行数dataSize=dataSet.shape[0]diffMat=np.tile(inX,(dataSize,1))-dataSetsqDiffMat=diffMat**2sqDistances=sqDiffMat.sum(axis=1)distances=sqDistances**0.5#将计算出的距离元素进行排序,获得排序后的索引值sortedDistIndices=distances.argsort()#记录类别次数classCount={}for i range(k):#取出前K个元素的类别voteIlabel=labels[sortedDistIndices[i]]#计算类别次数classCount[voteIlabel]=classCount.get(voteIlabel,0)+1sortedClassCount=sorted(classCount,items(),key=operator.itemgetter(1),reverse=True)return sortedClassCount[0][0]'''
函数说明:将数据进行分类,1代表不喜欢,2代表魅力一般,3代表极具魅力
分类为:特征矩阵和分类标签向量'''
def file2matrix(filename):#打开文件file=open(filename)#将数据存放在数组中arrayoLines=file.readlines()#获取数据的行数numberofLines=len(arrayoLines)#初始化特征矩阵returnMat=np.zeros((numberofLines,3))#初始化分类标签向量classLabelVector=[]#行的索引值index=0for line in arrayoLines:#清除首尾空白符line=line.strip()#将数据切片listFormLine=line.split('/t')#将前三列数据存放到特征矩阵中returnMat[index,:3]=listFormLine[:3]#将标签分类if listFormLine[-1]=='didntLike':classLabelVector.append(1)elif listFormLine[-1]=='smallDoses':classLabelVector.append(2)elif listFormLine[-1]=='largeDoses':classLabelVector.append(3)index+=1return returnMat,classLabelVector'''
函数说明:将数据归一化'''def autoNorm(dataSet):#获取最大值和最小值minVals=dataSet.min(0)maxVals=dataSet.max(0)#得到数据范围ranges=maxVals-minVals#初始化归一化后的特征矩阵normDataSet=np.zeros(np.shape(dataset))#获取数据的行数m=dataSet.shape[0]normDataSet=dataSet-np.tile(minVals,(m,1))normDataSet=normDataSet/np.tile(ranges,(m,1))#返回归一化后的矩阵,数据范围,最小值return normDataSet,ranges,minVals'''
函数说明:使用算法测试
'''def classifyPerson():#输出结果列表result=['讨厌','有些喜欢','非常喜欢']#输入三个特征的数据ffMiles=float(input('每年获得的飞行常客里程数:'))precentTats=float(input('玩视频游戏所消耗时间占比:'))iceCream=float(imput('每周消耗的冰淇淋公升数:'))#文件名filename='datingTestSet.txt'#分类数据datingDataMat,datingLabels=file2matrix(filename)#将数据归一化normMat,ranges,minVals=autoNorm(datingDataMat)#生成测试集数组inArr=np.array([ffMiles,precentTats,iceCream])#将测试集数据归一化norminArr=(inArr-minVals)/ranges#调用分类器classifierResult=classify0(norminArr,normMat,datingLabels,3)#打印结果print('你可能%s这个人'%(result[classifierResult-1]))if __name__=='__main__':classifyPerson()

(2)测试结果如下:

批注:我学习的博主Jack Cui,网址:Jack Cui | 关注人工智能及互联网的个人网站 (cuijiahua.com)

我就是看他的学习记录学习的,详细学习内容可进入他的网站学习。我写文章主要目的是为了再次熟悉代码和记录不会的知识点。

机器学习:K-近邻算法(二)约会网站配对效果相关推荐

  1. 【机器学习】机器学习从零到掌握之三 -- 教你使用K近邻算法改进约会网站

    本文是<机器学习从零到掌握>系列之第3篇 机器学习从零到掌握之一 -- 教你理解K近邻算法 机器学习从零到掌握之二 -- 教你实现K近邻算法 本篇使用的数据存放在文本文件datingTes ...

  2. 模式识别和机器学习实战-K近邻算法(KNN)- Python实现 - 约会网站配对效果判断和手写数字识别

    文章目录 前言 一. k-近邻算法(KNN) 1.算法介绍 2.举个例子--电影分类 3.步骤描述 4.来了--代码实现 二.实战之约会网站配对效果判断 1.导入数据 2.分析数据 3.数据归一化 4 ...

  3. 2 机器学习 K近邻算法(KNN) 学习曲线 交叉验证 手写数字识别

    机器学习 1 K-近邻算法介绍 1.1 分类问题 分类问题:根据已知样本的某些特征,判断一个未知样本属于哪种样本类别. 与回归问题相比,分类问题的输出结果是离散值,用于指定输入的样本数据属于哪个类别. ...

  4. 机器学习——K近邻算法(KNN)(K Nearest Neighbor)

    参考视频与文献: python与人工智能-KNN算法实现_哔哩哔哩_bilibili 机器学习--K近邻算法(KNN)及其python实现_清泉_流响的博客-CSDN博客_python实现knn 机器 ...

  5. KNN实战 —— 约会网站配对效果判定

    (公众号:落叶归根的猪.获取更多资源干货,交个朋友也可) 二.k-近邻算法实战之约会网站配对效果判定 上一小结学习了简单的k-近邻算法的实现方法,但是这并不是完整的k-近邻算法流程,k-近邻算法的一般 ...

  6. [机器学习]K近邻算法及其应用--WEKA工具

    K近邻算法理论基础 k近邻模型 距离度量 k值的选择 分类决策规则 WEKA实战 问题背景 数据预处理 得到分类器 对未知的数据进行分类预测 K近邻算法理论基础 (本节内容参考了:李航<统计学习 ...

  7. python机器学习 | K近邻算法学习(1)

    K近邻算法学习 1 K近邻算法介绍 1.1算法定义 1.2算法原理 1.3算法讨论 1.3.1 K值选择 1.3.2距离计算 1.3.3 KD树 2 K近邻算法实现 2.1scikit-learn工具 ...

  8. 机器学习[k近邻算法]

    k近邻算法简称kNN算法,由Thomas等人在1967年提出[1].它基于以下思想:要确定一个样本的类别,可以计算它与所有训练样本的距离,然后找出和该样本最接近的k个样本,统计这些样本的类别进行投票, ...

  9. KNN算法改进约会网站匹配效果

    文章目录 实验 一.示例:KNN改进约会网站配对 二.实验过程 1.准备数据:从文本文件中解析数据 2.分析数据:使用Matplotlib创建散点图 3.准备数据:归一化数值 4.测试算法:作为完整程 ...

最新文章

  1. 373. Find K Pairs with Smallest Sums (java,优先队列)
  2. 安卓中如何判断一个字符串是否为空
  3. andpods授权码订单号分享_不要再让你的接口裸奔了,Boot快速尝试OAuth2密码和授权码模式...
  4. Nodejs进阶:express+session实现简易身份认证
  5. OCR-PIL.Image与Base64 String的互相转换
  6. 掘金-Markdown 编辑器使用手册
  7. 这四种攻击单片机的主要技术你了解多少?
  8. python反射详解
  9. 前端技术学习之选择器(十三)
  10. 常用技术指标与四大交易理论
  11. Android04-UI01常用控件
  12. 毕业设计 STM32单片机的GPS定位系统 - 物联网
  13. 形式语言与自动机理论期末复习
  14. 【干货】从QQ群起家的情趣商城站长之路
  15. 小米应用闪退解决方法
  16. 麓言科技CAD制图技巧
  17. Matlab解方程, 等到数字解和解析式解
  18. VScode受难记 - 0
  19. Processing 安装外部库 Box2d
  20. javaSE-常用API(全)

热门文章

  1. ArrayList源码解析之subList
  2. C#图像处理-OpenCVSharp教程(十二) OpenCVSharp图像几何变换:平移、旋转、缩放、转置和镜像等
  3. 笔记本电脑睡眠耗电及唤醒设置
  4. python 获取word文档页数
  5. findIndex的使用
  6. vue 免费的每天不限次数的调用天气接口
  7. Linux 零拷贝技术
  8. 十分钟解决爬虫问题!超轻量级反爬虫方案
  9. 2021中山濠头中学高考成绩查询,2021年中山高中录取分数线是多少及高中排名榜...
  10. iptables A主机 ping B 主机