机器学习-k-近邻算法

k-近邻算法

  • 一、k-近邻算法概述
    • 1.1 使用python导入数据
    • 1.2 从文本文件中解析数据
  • 二、使用k-近邻算法改进约会网站的配对效果
    • 2.1 准备数据
    • 2.2 数据预处理
    • 2.3 分析数据
    • 2.4 测试算法
    • 2.5使用算法
  • 三、手写体识别系统

一、k-近邻算法概述

k-近邻算法是一种常用的监督学习算法,用于分类和回归任务。其思想为:如果一个样本在特征空间中的k个最近邻居中的大多数属于某个类别,那么该样本也属于这个类别(对于分类任务)或者可以通过这些最近邻居的标签来估计其目标值(对于回归任务)。

1.1 使用python导入数据

def createDataSet():'''构造数据Parameters:NoneReturns:group - 数据labels - 标签'''group = array([[100,98],[100,100],[0,0],[0,10]])    #[测试1的得分,测试2的得分]labels = ['A','A','B','B']    #整体评级情况return group, labels

1.2 从文本文件中解析数据

通过计算两点之间的距离来进一步选择相近的k个点:
d = ( x A 0 − x B 0 ) 2 − ( x A 1 − x B 1 ) 2 d=\sqrt{(x_{A_0}-x_{B_0})^2-(x_{A_1}-x_{B_1})^2} d=(xA0xB0)2(xA1xB1)2

def classify_KNN(inX, dataSet, labels, k):'''使用kNN算法进行分类Parameters:inX - 用于分类的数据(测试集)dataSet - 用于训练的数据(训练集)labels - 训练集标签k - kNN算法参数,选择距离最小的k个点Returns:sortedClassCount - 分类结果'''dataSetSize = dataSet.shape[0]    #dataSet的行数diffMat = inX - dataSet    #计算差值矩阵-广播sqDiffMat = diffMat**2    #差值矩阵平方sqDistances = sqDiffMat.sum(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    #类别数量+1sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)return sortedClassCount[0][0]

至此,就可以通过给定数据进行分类预测,分类预测的效果与数据集的标准

二、使用k-近邻算法改进约会网站的配对效果

2.1 准备数据

海伦将自己交往过的人可以进行如下分类:不喜欢的人、魅力一般的人、极具魅力的人。
海伦收集约会数据已经有了一段时间,她把这些数据存放在文本文件datingTestSet.txt中,每个样本数据占据一行,总共有1000行。海伦收集的样本数据主要包含以下3种特征:每年获得的飞行常客里程数、玩视频游戏所消耗时间百分比、每周消费的冰淇淋公升数。

def file2matrix(filename):'''读取数据,并将其转化为矩阵Parameters:filename - 文件路径Returns:returnMat - 数据矩阵classLabelVector - 数据标签'''with open(filename, "r") as file:lines = file.readlines()    #读取文本信息numberOfLines = len(lines)    #计算行数returnMat = zeros((numberOfLines,3))    #初始化矩阵classLabelVector = []    #创建分类标签向量index = 0for line in lines:line = line.strip()listFromLine = line.split('\t')returnMat[index,:] = listFromLine[0:3]#根据文本中标记的喜欢的程度进行分类,1代表不喜欢,2代表魅力一般,3代表极具魅力if listFromLine[-1] == 'didntLike':classLabelVector.append(1)elif listFromLine[-1] == 'smallDoses':classLabelVector.append(2)elif listFromLine[-1] == 'largeDoses':classLabelVector.append(3)index += 1return returnMat, classLabelVector   #(1000, 3),(1000,)

2.2 数据预处理

对于不同的类别的数据分布差异可能比较大,例如游戏时长百分比的差异在0-1之间,而飞行里程往往差异成败上千不等,差异大的属性值会严重影响欧式距离。因此需要对数据进行标准化,计算公式如下:
d a t a n o r m = d a t a − d a t a m i n d a t a m a x − d a t a m i n data_{norm} = \frac{data-data_{min}}{data_{max}-data_{min}} datanorm=datamaxdatamindatadatamin

def autoNorm(dataSet):'''归一化dataset中的值,函数返回归一化后的数据Parameters:dataSet - 原始数据Returns:normDataSet - 归一化后的数据ranges - 最大最小值的差值minVals - 数据中的最小值'''minVals = dataSet.min(0)    #获得数据的最小值maxVals = dataSet.max(0)    #获得数据的最大值ranges = maxVals - minVals#最大值和最小值的范围normDataSet = zeros(shape(dataSet))    #初始化归一矩阵m = dataSet.shape[0]    #dataSet的行数normDataSet = dataSet - tile(minVals, (m, 1))    #原始值减去最小值,tile是扩充函数normDataSet = normDataSet / tile(ranges, (m, 1))    #除以最大和最小值的差,得到归一化数据return normDataSet, ranges, minVals

2.3 分析数据

def showdatas(datingDataMat, datingLabels):'''将数据以散点图形式展示出来。Parameters:datingDataMat - 数据矩阵datingLabels - 数据标签Returns:None'''color_map = {1: 'r', 2: 'g', 3: 'b'}    # 创建颜色映射,将每个标签映射到不同的颜色label_name = ['didntLike','smallDoses','largeDoses']# 根据标签分组数据点grouped_data = {}for label in np.unique(datingLabels):grouped_data[label] = datingDataMat[datingLabels == label]plt.figure(figsize=(18, 6))plt.subplot(131)    # 创建X-Y平面上的散点图for label, color in color_map.items():points = grouped_data[label]plt.scatter(points[:, 0], points[:, 1], c=color, label=f'{label_name[label-1]}')plt.xlabel('每年获得的飞行常客里程数',fontproperties=font)plt.ylabel('玩视频游戏所消耗时间占',fontproperties=font)plt.legend()# 创建X-Z平面上的散点图plt.subplot(132)for label, color in color_map.items():points = grouped_data[label]plt.scatter(points[:, 0], points[:, 2], c=color, label=f'{label_name[label-1]}')plt.xlabel('每年获得的飞行常客里程数',fontproperties=font)plt.ylabel('每周消费的冰激淋公升数',fontproperties=font)plt.legend()# 创建Y-Z平面上的散点图plt.subplot(133)for label, color in color_map.items():points = grouped_data[label]plt.scatter(points[:, 1], points[:, 2], c=color, label=f'{label_name[label-1]}')plt.xlabel('玩视频游戏所消耗时间占',fontproperties=font)plt.ylabel('每周消费的冰激淋公升数',fontproperties=font)plt.legend()# 显示图形plt.tight_layout()plt.show()

在这里插入图片描述

2.4 测试算法

将数据按照指定比例划分训练集与测试集,训练集用于构建模型,测试集用于评估算法与数据的可靠性。

def datingClassTest():""" 测试算法的准确度,打印出算法的错误率Parameters:NoneReturns:None"""filename = r"./datingTestSet.txt"    #文件路径datingDataMat, datingLabels = file2matrix(filename)hoRatio = 0.10   #测试集比例normMat, ranges, minVals = autoNorm(datingDataMat)    #数据归一化m = normMat.shape[0]    #数据量numTestVecs = int(m * hoRatio)    #测试集个数errorCount = 0.0    #分类错误量for i in range(numTestVecs):    #遍历测试集,评估正确率classifierResult = classify_KNN(normMat[i,:], normMat[numTestVecs:m,:],datingLabels[numTestVecs:m], 4)#输出错误的情况if classifierResult != datingLabels[i]:errorCount += 1.0print("分类结果:%d\t真实类别:%d" % (classifierResult, datingLabels[i]))print("错误率:%f%%" %(errorCount/float(numTestVecs)*100))

2.5使用算法

调用模型就可以进行数据的预估,不同的k值也可能会有不同的结果。需要根据实际应用场景决定

def classifyPerson():""" 根据输入内容进行判断Parameters:NoneReturns:None"""resultList = ['讨厌','有些喜欢','非常喜欢']    #输出结果precentTats = float(input("玩视频游戏所耗时间百分比:"))ffMiles = float(input("每年获得的飞行常客里程数:"))iceCream = float(input("每周消费的冰激淋公升数:"))filename = "./datingTestSet.txt"datingDataMat, datingLabels = file2matrix(filename)normMat, ranges, minVals = autoNorm(datingDataMat)inArr = array([precentTats, ffMiles, iceCream])norminArr = (inArr - minVals) / ranges#返回分类结果classifierResult = classify_KNN(norminArr, normMat, datingLabels, 3)#打印结果print("你可能%s这个人" % (resultList[classifierResult-1]))

在这里插入图片描述

三、手写体识别系统

对于手写识别系统而言整体流程是一致的,主要差距在于数据的输入以及预处理上。

def img2vector(file_path):"""将32x32的二进制图像转换为1x1024向量。Parameters:file_path - 文件名Returns:returnVect - 返回的二进制图像的1x1024向量"""returnVect = np.zeros((1, 1024))    #初始化with open(file_path, 'r') as file:for i in range(32):lineStr = file.readline()for j in range(32):returnVect[0, 32*i+j] = int(lineStr[j])return returnVect

在这里插入图片描述

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

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

相关文章

Ruff南潮物联邀请您参观中国工博会,快来扫码领取免费门票!

由于受疫情影响的延期,第23届中国国际工业博览会(简称"中国工博会")终于将要在2023年9月19日-23日国家会展中心(上海虹桥)举行。 中国工博会是由工业和信息化部、国家发展和改革委员会、科学技术部、商务部、…

境外微信小程序商超建设流程

注册,境外小程序主要是提交企业主体信息,例如企业名称、注册号、注册地址,管理员信息等(PS:这里可以先由开发方人员承担管理员,便于开发过程使用,未来可以转让给客户指定人员)。 认…

初探Vue.js及Vue-Cli

一、使用vue框架的简单示例 我们本次的vue系列就使用webstorm来演示: 对于vue.js的安装我们直接使用script的cdn链接来实现 具体可以参考如下网址: https://www.bootcdn.cn/ 进入vue部分,可以筛选版本,我这里使用的是2.7.10版本的&#xff…

Python异常处理——走BUG的路,让BUG无处可走

作者:Insist-- 个人主页:insist--个人主页 本文专栏:Python专栏 专栏介绍:本专栏为免费专栏,并且会持续更新python基础知识,欢迎各位订阅关注。 目录 一、了解python异常 1、BUG 单词的由来 2、什么是异…

分布式系统第三讲:全局唯一ID实现方案

分布式系统第三讲:全局唯一ID实现方案 本文主要介绍常见的分布式ID生成方式,大致分类的话可以分为两类:一种是类DB型的,根据设置不同起始值和步长来实现趋势递增,需要考虑服务的容错性和可用性; 另一种是类snowflake型…

【Redis】Redis 的学习教程(九)之 发布 Pub、订阅 Sub

1. Pub/Sub 介绍 Redis 的发布订阅(Pub/Sub)模式是一种消息传递机制,它允许在发送者和接收者之间建立松耦合的通信关系。在这种模式中,发送者(发布者)将消息发布到一个指定的频道或模式,而接收…

Mysql--技术文档--索引-《索引为什么查找数据快?》-超底层详细说明索引

索引的概念 在MySQL中,索引是一种数据结构,它被用于快速查找、读取或插入数据。索引能够极大地提高数据库查询的速度。 索引的工作方式类似于图书的索引。如果你想在图书馆找到一本书,你可以按照书名进行查找。书名就像是一个索引&#xf…

C#winform导出DataGridView数据到Excel表

前提:NuGet安装EPPlus,选择合适的能兼容当前.net framwork的版本 主要代码: private void btn_export_Click(object sender, EventArgs e) {SaveFileDialog saveFileDialog new SaveFileDialog();saveFileDialog.Filter "Excel Files…

TCP三次握手和四次挥手

目录 TCP连接建立 问题思考 1.为什么要三次握手? 2.三次握手一定要保证成功吗? TCP连接释放 问题思考 ​ 1.理解TIME-WAIT状态 2.理解CLOSE-WAIT状态 TCP连接建立 TCP建立连接的过程叫作握手,握手需要在客户和服务器之间交换三个TCP…

【LeetCode-简单题】844. 比较含退格的字符串

文章目录 题目方法一:单指针方法二:双指针方法三:栈 题目 方法一:单指针 首先每次进入循环处理之前需要对第一个字符进行判断,若是退格符,直接删掉,结束此次循环fast从0开始,如果fa…

无涯教程-JavaScript - COUPNCD函数

描述 COUPNCD函数返回一个数字,该数字表示结算日期之后的下一个息票日期。 语法 COUPNCD (settlement, maturity, frequency, [basis])争论 Argument描述Required/OptionalSettlement 证券的结算日期。 证券结算日期是指在发行日期之后将证券交易给买方的日期。 RequiredMa…

OSPF路由计算

1、Router LSA LSA 链路状态通告,是OSPF进行路由计算的主要依据,在OSPF的LSU报文中携带,其头重要字段及解释: LS Type(链路状态类型):指示本LSA的类型。 在域内、域间、域外…

OpenResume简历解析官方技术文档(翻译)

OpenResume简历解析官方技术文档(翻译) 本文是对OpenResume建立解析器官方技术文档《Resume Parser Playground》的翻译。 相关连接: OpenResume官网 OpenResume简历解析器的官方地址 OpenResume的Github 简历解析测试环境 该测试环境展示了 OpenResume 简历…

vue页面添加水印(可用于H5,APP)

vue页面添加水印 背景实现新建vue组件使用效果 尾巴 背景 最近实现了一个小功能,就是给页面添加背景水印。实现思路就是定义一个宽高充满屏幕的组件,然后使用绝对定位并通过层级控制让水印显示在页面的最前端。 实现 代码相对简单,相信有点…

2023-9-11 高斯消元解异或线性方程组

题目链接&#xff1a;高斯消元解异或线性方程组 #include <iostream> #include <algorithm>using namespace std;const int N 110;int n; int a[N][N];int gauss() {int c, r;for(c r 0; c < n; c ){int t r;for(int i r; i < n; i )if(a[i][c]){t i;b…

超图聚类论文阅读1:Kumar算法

超图聚类论文阅读1&#xff1a;Kumar算法 《超图中模块化的新度量&#xff1a;有效聚类的理论见解和启示》 《A New Measure of Modularity in Hypergraphs: Theoretical Insights and Implications for Effective Clustering》 COMPLEX NETWORKS 2020, SCI 3区 具体实现源码见…

vue checkbox-group和checkbox动态生成,问题解决

源码 <el-checkbox-group v-model"form[keyItem.name]"><el-checkboxv-for"(checkboxItem,cindex) in keyItem.options.split(,)":key"cindex":label"checkboxItem"></el-checkbox></el-checkbox-group> 我是…

不关闭Tamper Protection(篡改保护)下强制卸载Windows Defender和安全中心所有组件

个人博客: xzajyjs.cn 背景介绍 由于微软不再更新arm版本的win10系统&#xff0c;因此只能通过安装insider preview的镜像来使用。而能找到的win10 on arm最新版镜像在安装之后由于内核版本过期&#xff0c;无法打开Windows安全中心面板了&#xff0c;提示如下&#xff1a; 尝…

——二叉树

二叉树种类 二叉树有两种主要的形式&#xff1a;满二叉树和完全二叉树。 满二叉树 如果一棵二叉树只有度为0的结点和度为2的结点&#xff0c;并且度为0的结点在同一层上&#xff0c;则这棵二叉树为满二叉树。 完全二叉树 在完全二叉树中&#xff0c;除了最底层节点可能没…

buuctf web 前5题

目录 一、[极客大挑战 2019]EasySQL 总结&#xff1a; 二、[极客大挑战 2019]Havefun 总结&#xff1a; 三、[HCTF 2018]WarmUp 总论&#xff1a; 四、[ACTF2020 新生赛]Include 总结&#xff1a; 五、[ACTF2020 新生赛]Exec 总结&#xff1a; 一、[极客大挑战 2019]…