热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

机器学习&python使用k-近邻算法改进约会网站的配对效果

参考自:《MachineLearningInAction》第二章#################################################################

参考自:《Machine Learning In Action》第二章


######################################################################


程序流程:

1.收集数据:提供文本文件

2.准备数据:使用Python解析文本文件

3.分析数据:使用Matplotlib画二维扩散图

4.测试算法:使用提供的部分数据作为测试样本。

测试样本和非测试样本的区别在于:测试样本是已经完成分类的数据,如果预测分类与实际类别不同,则标记为一个错误

5.使用算法:产生简单的命令行程序,然后可以输入一些特征数据以判断结果


###########################################################


本样本共有三种特征:

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

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

每周消费的冰淇淋公升数


数据存放在文本文件datingTestSet2.txt文件中,每个样本数据占据一行,总共有1000行

#!/usr/local/env python
#-*- coding: utf-8 -*-

from numpy import * #导入科学计算包numpy模块
import operator #导入运算符模块

#k-近邻分类算法
def classify0(inX, dataSet, labels, k): #4个输入参数分别为:用于分类的输入向量inX,输入的训练样本集dataSet,标签向量labels,选择最近邻居的数目k
#计算距离
dataSetSize=dataSet.shape[0] #获取数据集的宽
diffMat=tile(inX, (dataSetSize, 1))-dataSet #使用欧式距离度量,故将输入向量和数据集中各向量相减
sqDiffMat=diffMat**2 #平方
sqDistances=sqDiffMat.sum(axis=1) #计算输入向量和数据集中各向量之间的差的平方和
distances=sqDistances**0.5 #计算欧式距离
#选择距离最小的k个点 计算所属类别的出现频率
sortedDistIndicies=distances.argsort() #取得输入向量和数据集中各向量欧式距离的从小到大排序的下标值
classCount={} #定义一个空字典
for i in range(k): #取计算欧氏距离排序后最小的前k个值
voteIlabel=labels[sortedDistIndicies[i]]
classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
#排序 选择前k个点中出现最多的那一个类
sortedClassCount=sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]

#将文本记录转换为Numpy的array
def file2matrix(filename): #输入为文件名字符串
fr=open(filename) #打开文件
arrayOLines=fr.readlines() #取得该文件的每行数据的列表
numberOfLines=len(arrayOLines) #计算该文件共有多少行(即共有多少个样本)
returnMat=zeros((numberOfLines, 3)) #创建返回的Numpy矩阵
classLabelVector=[]
index=0
for line in arrayOLines: #解析文件数据到列表
line=line.strip() #去掉首尾空白符
listFromLine=line.split('\t') #利用空格符分离字符串
returnMat[index, :]=listFromLine[0:3] #将每行样本数据的前3个数据输入返回样本矩阵中
classLabelVector.append(int(listFromLine[-1])) #将每行样本数据的最后一个数据加入类标签向量中
index+=1
return returnMat, classLabelVector #返回训练样本矩阵和类标签向量

#归一化特征值
def autoNorm(dataSet): #输入为数据集数据
minVals=dataSet.min(0) #获得数据集中每列的最小值
maxVals=dataSet.max(0) #获得数据集中每列的最大值
ranges=maxVals-minVals #获取取值范围
normDataSet=zeros(shape(dataSet)) #初始化归一化数据集
m=dataSet.shape[0] #行
normDataSet=dataSet-tile(minVals, (m, 1))
normDataSet=normDataSet/tile(ranges, (m, 1)) #特征值相除
return normDataSet, ranges, minVals #返回归一化矩阵,取值范围以及最小值

#测试程序
def datingClassTest():
hoRatio=0.10 #取测试样本占数据集样本的10%
datingDataMat,datingLabels=file2matrix('datingTestSet2.txt') #得到样本集,样本标签
normMat,ranges,minVals=autoNorm(datingDataMat) #得到归一化样本集,取值范围以及最小值
m=normMat.shape[0] #样本集行数
numTestVecs=int(m*hoRatio) #测试样本集数量
errorCount=0.0 #初始化错误率
for i in range(numTestVecs): #循环,计算测试样本集错误数量
classifierResult=classify0(normMat[i,:], normMat[numTestVecs:m,:], datingLabels[numTestVecs:m], 3) #k-近邻算法
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 doses', 'in large doses']
percentTats=float(raw_input("percentage of time spent playing video games?"))
ffMiles=float(raw_input("frequent filer miles earned per year?"))
iceCream=float(raw_input("liters of icecream consumed per year?"))
datingDataMat,datingLabels=file2matrix('datingTestSet2.txt')
normMat,ranges,minVals=autoNorm(datingDataMat)
inArr=array([ffMiles, percentTats, iceCream])
classifierResult=classify0((inArr-minVals)/ranges,normMat,datingLabels,3)
print "You will probably like this person: ",resultList[classifierResult-1]


########################################################3
代码解析


在将上述特征数据输入到分类器之前,必须将待处理数据的格式改变为分类器可以接受的格式。

使用file2matrix函数,输入为文件名字符串,输出为训练样本矩阵和类标签向量



在处理不同取值范围的特征值时,通常将其数值归一化,如将取值范围处理为0到1或者-1到1之间。

下面的公式可以将任意取值范围的特征值转化为0到1区间内的值:

newValues=(oldValues-min)/(max-min)

其中min和max分别是数据集中的最小特征值和最大特征值

使用函数autoNorm(),讲数字特征值转化为0到1区间



推荐阅读
  • Ihavetwomethodsofgeneratingmdistinctrandomnumbersintherange[0..n-1]我有两种方法在范围[0.n-1]中生 ... [详细]
  • javascript分页类支持页码格式
    前端时间因为项目需要,要对一个产品下所有的附属图片进行分页显示,没考虑ajax一张张请求,所以干脆一次性全部把图片out,然 ... [详细]
  • 字节流(InputStream和OutputStream),字节流读写文件,字节流的缓冲区,字节缓冲流
    字节流抽象类InputStream和OutputStream是字节流的顶级父类所有的字节输入流都继承自InputStream,所有的输出流都继承子OutputStreamInput ... [详细]
  • php更新数据库字段的函数是,php更新数据库字段的函数是 ... [详细]
  • 在2019中国国际智能产业博览会上,百度董事长兼CEO李彦宏强调,人工智能应务实推进其在各行业的应用。随后,在“ABC SUMMIT 2019百度云智峰会”上,百度展示了通过“云+AI”推动AI工业化和产业智能化的最新成果。 ... [详细]
  • 本文详细介绍了MySQL数据库的基础语法与核心操作,涵盖从基础概念到具体应用的多个方面。首先,文章从基础知识入手,逐步深入到创建和修改数据表的操作。接着,详细讲解了如何进行数据的插入、更新与删除。在查询部分,不仅介绍了DISTINCT和LIMIT的使用方法,还探讨了排序、过滤和通配符的应用。此外,文章还涵盖了计算字段以及多种函数的使用,包括文本处理、日期和时间处理及数值处理等。通过这些内容,读者可以全面掌握MySQL数据库的核心操作技巧。 ... [详细]
  • PyTorch实用技巧汇总(持续更新中)
    空洞卷积(Dilated Convolutions)在卷积操作中通过在卷积核元素之间插入空格来扩大感受野,这一过程由超参数 dilation rate 控制。这种技术在保持参数数量不变的情况下,能够有效地捕捉更大范围的上下文信息,适用于多种视觉任务,如图像分割和目标检测。本文将详细介绍空洞卷积的计算原理及其应用场景。 ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
  • 当使用 `new` 表达式(即通过 `new` 动态创建对象)时,会发生两件事:首先,内存被分配用于存储新对象;其次,该对象的构造函数被调用以初始化对象。为了确保资源管理的一致性和避免内存泄漏,建议在使用 `new` 和 `delete` 时保持形式一致。例如,如果使用 `new[]` 分配数组,则应使用 `delete[]` 来释放内存;同样,如果使用 `new` 分配单个对象,则应使用 `delete` 来释放内存。这种一致性有助于防止常见的编程错误,提高代码的健壮性和可维护性。 ... [详细]
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • 在Android应用开发中,实现与MySQL数据库的连接是一项重要的技术任务。本文详细介绍了Android连接MySQL数据库的操作流程和技术要点。首先,Android平台提供了SQLiteOpenHelper类作为数据库辅助工具,用于创建或打开数据库。开发者可以通过继承并扩展该类,实现对数据库的初始化和版本管理。此外,文章还探讨了使用第三方库如Retrofit或Volley进行网络请求,以及如何通过JSON格式交换数据,确保与MySQL服务器的高效通信。 ... [详细]
  • 本指南从零开始介绍Scala编程语言的基础知识,重点讲解了Scala解释器REPL(读取-求值-打印-循环)的使用方法。REPL是Scala开发中的重要工具,能够帮助初学者快速理解和实践Scala的基本语法和特性。通过详细的示例和练习,读者将能够熟练掌握Scala的基础概念和编程技巧。 ... [详细]
  • 技术日志:使用 Ruby 爬虫抓取拉勾网职位数据并生成词云分析报告
    技术日志:使用 Ruby 爬虫抓取拉勾网职位数据并生成词云分析报告 ... [详细]
  • 本文探讨了利用JavaScript实现集合的对称差集算法的方法。该算法旨在处理多个数组作为输入参数,同时保留每个数组中元素的原始顺序。算法不会移除单个数组内的重复元素,但会删除在不同数组之间出现的重复项。通过这种方式,能够有效地计算出多个数组的对称差集。 ... [详细]
  • 本文介绍了一种算法,用于计算当前日期在本年度的具体周数。该方法由作者王峰提出,通过私有函数 `weekOfYear` 实现,能够准确地确定当前日期在一年中的周位置。此算法在日历计算和时间管理中具有广泛应用,适用于各种编程语言和应用场景。 ... [详细]
author-avatar
蓝星星空
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有