K近邻原理和距离

K近邻

  • 基本思想
  • 欧氏距离
  • 算法流程
  • 代码
  • 基于近邻用户的协同过滤
  • 基于近邻物品的协同过滤
  • 杰卡德相似度

基本思想

在这里插入图片描述
我们根据涂色样本点和未涂色样本点 X 的距离给涂色样本点编号1-6,即:1号样本点距离X最近,其余次之。

那么问题来了:样本点 X 应该属于哪种颜色呢?是蓝色还是绿色?

其实,我们可以根据 X 的相邻样本点来判定。例如,和 X 距离最近的三个样本点中绿色占多数,那么 X 就属于为绿色;和 X 距离最近的 5 个样本点中蓝色占多数,那么 X 就属于蓝色。

这种解决问题的思路正是 K 近邻算法的基本思想:根据 K 个近邻样本的 y 值来预测自身的 y 值。具体到上面例子中的 y 值就是样本点的颜色。

K 近邻是监督学习中比较简单的一种算法,它既可以解决分类问题,也可以解决回归问题。

上面的涂色问题本质上就是利用 K 近邻算法给颜色未知的样本进行分类。颜色已知的样本属于训练样本,颜色未知的样本属于测试样本。

我们已经知道 K 近邻算法的基本思想是根据 K 个近邻样本的 y 值来预测自身的 y 值。具体到分类问题中,y 值就是样本类别的取值,一般采用多数表决的原则来对测试样本的类别进行预测。

那么如何使用 K 近邻来解决回归问题呢?请看下图:
在这里插入图片描述
回归问题中预测的 y 值是一个连续值,上图中每个样本点周围的数字代表其 y 值,K近邻是将离 X 最近的 K个样本的 y 值的平均值作为 X 的预测 y 值。例如:K=3 时,X 的预测输出 y = (1.2+3.4+8.3)/3 = 4.3;K=5 时,X 的预测输出 y = (1.2+3.4+8.3+5.5+4.5)/5 = 4.58 。

欧氏距离

在这里插入图片描述
图中的 a 和 b 代表两个样本,更具体一点说是样本的特征向量,每个样本的特征向量维度是2,即:每个样本都有两个特征。

a 和 b 其实是二维特征空间中的两个点,拓展到更高维的空间的距离公式是类似的:
在这里插入图片描述
发现规律了吗?其实就是先计算向量 a 和向量 b 对应维度数值差的平方和,然后再开方。由此我们可以写出任意维特征向量 a 和 b 的欧式距离公式:
在这里插入图片描述

算法流程

本门课中主要探讨 K 近邻在分类问题上的应用,下面我们来看一下 K 近邻分类算法的流程:

第一步:准备训练样本集:data = {[x1,x2,…,xn,y],…},其中 x1,x2,…,xn 是样本特征,y 是样本类别取值。

例如我们有一个特征维数为 2、样本数量为 3 的训练集:data = {[1,2,0],[3,1,0],[2,3,1]},则其中的样本分别为 [1,2,0]、[3,1,0]、[2,3,1],样本特征分别为 [1,2]、[3,1]、[2,3],样本类别分别为 0、0、1。

第二步:输入测试样本 A:[x1,x2,…,xn],例如测试样本的特征是二维的 [1,4]

第三步:计算测试样本 A 和所有训练样本的距离。

具体来讲,可以是第二步中的测试样本 [1,4] 和第一步中的训练样本 [1,2]、[3,1]、[2,3] 分别计算欧式距离。

第四步:按照距离递增排序。

第五步:选取与 A 距离最小的 K 个样本。

第六步:计算这 K 个样本所在类别的出现频率。

第七步:返回出现频率最高的类别作为 A 的预测分类。

K 近邻中的 K 值是人为设定的参数, K 值的选取会对预测结果产生影响。除了 K 值外,K 近邻的预测结果还受距离度量和决策规则的影响。
距离度量实际上是衡量两个样本的相似程度:距离越小,相似程度越高。常见的相似性度量函数有:欧氏距离、余弦相似性、皮尔逊相关系数

代码

# 1. 导入工具包
import numpy as np
import pandas as pd
from collections import Counter# 2. 欧式距离定义
def euclidean_distance(vec1,vec2):return np.sqrt(np.sum(np.square(vec1 - vec2)))# 3. 构造数据集  
train_data = {'宝贝当家':[45,2,9,'喜剧片'],'美人鱼':[21,17,5,'喜剧片'],'澳门风云3':[54,9,11,'喜剧片'],'功夫熊猫3':[39,0,31,'喜剧片'],'谍影重重':[5,2,57,'动作片'],'叶问3':[3,2,65,'动作片'],'我的特工爷爷':[6,4,21,'动作片'],'奔爱':[7,46,4,'爱情片'],'夜孔雀':[9,39,8,'爱情片'],'代理情人':[9,38,2,'爱情片'],'新步步惊心':[8,34,17,'爱情片'],'伦敦陷落':[2,3,55,'动作片']}train_df =  pd.DataFrame(train_data).T
train_df.columns = ['搞笑镜头','拥抱镜头','打斗镜头','电影类型']test_data = {'唐人街探案':[23,3,17]} # 4. 确定K值和分类的电影
K = 5
movie = '唐人街探案'# 5. 计算欧式距离
distance_list = []
for train_X in train_df.values[:,:-1]:test_X = np.array(test_data[movie])distance_list.append(euclidean_distance(train_X,test_X))# 6. 按照距离递增排序
distance_df = pd.DataFrame({"欧式距离":distance_list},index=train_df.index)
result = pd.concat([train_df,distance_df],axis=1).sort_values(by="欧式距离")# 7. ToDo:输出分类结果
d = Counter(result.head(K)['电影类型'])
print(movie,max(d,key=d.get))

基于近邻用户的协同过滤

假定有一个场景:某个周日的下午,你感觉很无聊,然后从电脑上打开了一个视频网站,想看下最近有什么好看的电影。然而你发现网站上的热门电影基本都看过,其他的电影又太多,不知道该看什么。想使用搜索框去查一下,但是又不知道该搜什么关键词,这个时候你的内心很焦灼,总不能挨个去尝试吧,那时间成本也太大了…

仔细想想还是有办法的,那就是问一下你的好朋友,他最近喜欢看什么电影,让他给你推荐几部好看的电影,这样就省去了自己去挑选和尝试的时间了。

这种思想其实就是基于近邻用户的协同过滤算法(简称UserCF):给用户 A 推荐和他有着相似观影兴趣的用户 B 喜欢观看的电影。如图所示:
在这里插入图片描述
从图中可以看出,用户 A 的好友用户 B 喜欢看电影 2、3、4,恰好电影 3 和电影 4 用户 A 没有看过,所以就可以把电影 3 和电影 4 推荐给用户 A 。

基于近邻用户的协同过滤算法很容易给出的推荐理由是:和你兴趣相似的人还喜欢下面的电影。

那为什么说用户 A 和用户 B 的观影兴趣相似呢?生活中的经验告诉我们:物以类聚人以群分。既然 A 和 B 能够成为好朋友,那么他们必然就有着某些共同的价值观和兴趣爱好。

体现在上面的这幅图中为:用户 A 和用户 B 都观看过电影 2 。

基于近邻用户的协同过滤算法,第一个要理解的点是近邻用户,也就是兴趣相似的用户;第二个要理解的点是协同过滤算法到底指的是什么?

所谓的协同过滤,其实指的是一类算法的称呼:根据用户的行为数据给用户产生推荐结果的一类算法。

上面我们是根据用户的观影记录,即每个用户看过哪些电影,来进行电影推荐,所以它属于协同过滤的一种。

既然可以将用户 B 喜欢的电影推荐给用户 A,那么用户 A 喜欢的电影也可以推荐给用户 B。所以,基于近邻用户的协同过滤算法是在观影兴趣相似的用户间互相推荐电影。如图所示:
在这里插入图片描述
细心观察可以发现,电影 2 并没有在用户 A 和用户 B 中进行推荐。原因是:推荐系统的本质是建立用户和物品的连接,电影 2 在用户 A 和用户 B 上已经存在连接了,所以也就不需要再进行推荐了。

另一方面,看过的电影一般就不再推荐了,这个也符合生活常识。

假如用户 A 前两天刚看过电影 2,然后你又给他推荐电影 2,这显然不是用户 A 想要的结果。

这里有一个发散性的想法:如果电影 2 是用户 A 和用户 B 十多年前看过的电影,是不是可以再推荐给他们怀旧一下呢,哈哈~

通过这个发散性的想法,我想表达的一个观点是:推荐系统要做的事情其实是分析用户的心理,让用户满意,给到他们想要的东西,也给到使他们惊喜和意外的东西。

下面我们来梳理一下基于近邻用户的协同过滤算法实现的流程:

比如我们需要给用户 A 推荐电影,那么首先要找到和用户 A 观影兴趣最相似的 K 个用户,然后再从这 K 个用户喜欢的电影中,找到用户 A 没有看过的电影,推荐给 A。
在这里插入图片描述
如图所示,先不考虑相似度的计算方法,K=3 的情况下,和用户 A 最相似的 3 个用户依次是用户 B、C、D,从这 3 个用户喜欢的电影集合中过滤掉用户 A 看过的电影,然后计算 A 对剩下的电影感兴趣的程度,从中选取最感兴趣的的 3 个电影推荐给用户 A 。这里的推荐数量根据产品需求来设定,不一定是 3。

这里的感兴趣程度计算方法是将每个电影上有观看行为的用户相似度求和得到的,例如 A 对电影 2 的感兴趣程度为:用户 B 的 0.8 + 用户 C 的 0.6 = 1.4

基于近邻物品的协同过滤

推荐系统会根据你过往看过的电影,从电影库中查找相似的电影推荐给你,这种方法叫做基于近邻物品的协同过滤算法(简称ItemCF)。如图所示:
在这里插入图片描述
用户 A 看过电影 1,那么就给他推荐相似的电影 2;用户 D 看过电影 2,那么就给他推荐相似的电影 1。电影 1 和电影 2 相似是因为他们有着共同的观影群体(B和C)。基于近邻物品的协同过滤算法常见的推荐理由是:看了该电影的用户还看了如下电影

基于近邻物品的协同过滤算法,第一个要理解的点是近邻物品,也就是用户群体相似的物品;第二个要理解的点是协同过滤,这个前面已经讲过,核心是利用了用户行为数据,此处不再赘述。

从上面的图中可以看出,推荐系统只在电影 2 和用户 A 之间、电影 1 和用户 D 之间建立了推荐路线,原因是用户 B 和用户 C 之前都和这两个电影有过观看连接。

换个说法,因为用户 B 看过电影 1 和电影 2,所以只能给用户 B 推荐和电影 1 或电影 2 相似的电影,而不是推荐电影 1 和电影 2 本身。图示仅作示意,实际上还有很多电影可以和用户 B 建立连接,前提是要满足用户 B 的兴趣。

总结一下:基于近邻物品的协同过滤算法是给用户推荐和他过去喜欢的电影相似的电影。具体的算法流程是:比如我们要给用户 A 推荐电影,首先要在用户 A 喜欢的电影中分别找到 K 个最相似的电影,然后再从这些电影中找到用户 A 没看过的电影推荐给 A 。
在这里插入图片描述
这里的感兴趣程度计算方法是将每个候选电影上的电影相似度求和得到的,例如 A 对电影 4 的感兴趣程度为:电影 4 和电影 1 的相似度 0.5 + 电影 4 和电影 2 的相似度 0.4 = 0.9

杰卡德相似度

前面我们讲的两种基于近邻的协同过滤算法有一个共同点,那就是计算相似度。其实在本章第 1节课中我们已经提到了几种相似度的计算方法,比如欧氏距离、余弦相似性、皮尔逊相关系数。

下面我们再介绍一种相似度的计算方法:杰卡德(Jaccard)相似度,杰卡德相似度是指两个集合的交集元素个数在并集中所占的比例。先来看一幅图片:
在这里插入图片描述
图中展现的是代表用户观影记录的行为矩阵,矩阵中的 1 表示用户看过对应的电影,0 表示没看过。据此,我们可以根据杰卡德相似度定义分别计算出用户的相似度矩阵和电影的相似度矩阵。先来看用户相似度矩阵:
在这里插入图片描述
图中用户相似度矩阵的取值是关于对角线对称的,实际上我们需要的只有右上角的 6个值。那么这些值是怎么算出来的呢?

就拿用户 B 和用户 D 的相似度 1/3 举例吧,杰卡德相似度其实就是交集和并集的占比,如图所示:
在这里插入图片描述

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

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

相关文章

模型 A/B测试(科学验证)

系列文章 分享 模型,了解更多👉 模型_思维模型目录。控制变量法。 1 A/B测试的应用 1.1 Electronic Arts(EA)《模拟城市》5游戏网站A/B测试 定义目标: Electronic Arts(EA)在发布新版《模拟城…

Git merge 和 rebase的区别(附图)

在 Git 中,merge 和 rebase 是两种用于整合分支变化的方法。虽然它们都可以将一个分支的更改引入到另一个分支中,但它们的工作方式和结果是不同的。以下是对这两者的详细解释: Git Merge 功能:合并分支,将两个分支的…

耐蚀镍基合金的焊接技术与质量控制

耐蚀镍基合金是一类在腐蚀环境中具有优异性能的合金材料,广泛应用于化工、海洋工程、石油天然气等领域。其焊接技术与质量控制对于确保合金的使用性能和安全性至关重要。以下是对耐蚀镍基合金焊接技术与质量控制的详细探讨。 一、焊接技术 焊条选择 耐蚀镍基合金的焊…

机器视觉与OpenCV--01篇

计算机眼中的图像 像素 像素是图像的基本单位,每个像素存储着图像的颜色、亮度或者其他特征,一张图片就是由若干个像素组成的。 RGB 在计算机中,RGB三种颜色被称为RGB三通道,且每个通道的取值都是0到255之间。 计算机中图像的…

操作系统(14)请求分页

前言 操作系统中的请求分页,也称为页式虚拟存储管理,是建立在基本分页基础上,为了支持虚拟存储器功能而增加了请求调页功能和页面置换功能的一种内存管理技术。 一、基本概念 分页:将进程的逻辑地址空间分成若干个大小相等的页&am…

git企业开发的相关理论(一)

目录 一.初识git 二.git的安装 三.初始化/创建本地仓库 四.配置用户设置/配置本地仓库 五.认识工作区、暂存区、版本库 六.添加文件__场景一 七.查看 .git 文件/添加到本地仓库后.git中发生的变化 1.执行git add后的变化 index文件(暂存区) log…

wxpython图形用户界面编程

wxpython图形用户界面编程 一、wxpython的基础 1.1 wxpython的基础 作为图形用户界面开发工具包 wxPython,主要提供了如下 GUI 内容: 窗口。控件。事件处理。布局管理。 1.2 wxpython的类层次机构 1.3 wxpython的安装 Windows 和 macOS 平台安装&a…

水仙花数(流程图,NS流程图)

题目:打印出所有的100-999之间的"水仙花数",并画出流程图和NS流程图。所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个"水仙花数",因为1531的三次方&#…

不配置python环境,直接用PyCharm就可以?

有的伙伴可能遇到不安装python环境只安装pycharm也可以进行运行代码。 所以自认为是不需要解释器就可以运行? 这个是不现实的,有很多伙伴可能是安装了Pycharm,但Pycharm看你电脑上没有解释器,所以在安装的时候给你默认安装在C盘…

前端面试汇总(不定时更新)

目录 HTML & CSS1. XML、HTML、XHTML 有什么区别?⭐2. XML和JSON的区别?3. 是否了解W3C的规范?⭐4. 什么是语义化标签?⭐⭐5. 行内元素和块级元素的区别?⭐6. 行内元素和块级元素的转换?⭐7. 常用的块级…

SpringCloud微服务实战系列:03spring-cloud-gateway业务网关灰度发布

目录 spring-cloud-gateway 和zuul spring webflux 和 spring mvc spring-cloud-gateway 的两种模式 spring-cloud-gateway server 模式下配置说明 grayLb://system-server 灰度发布代码实现 spring-cloud-gateway 和zuul zuul 是spring全家桶的第一代网关组件&#x…

ActiveMQ 反序列化漏洞CVE-2015-5254复现

文章目录 一、产生原因二、利用条件三、利用过程四、PoC(概念验证)五、poc环境验证使用find搜索vulhub已安装目录打开activeMQ组件查看配置文件端口启动镜像-文件配置好后对于Docker 镜像下载问题及解决办法设置好镜像源地址,进行重启docker查…

vue3监听横向滚动条的位置;鼠标滚轮滑动控制滚动条滚动;监听滚动条到顶端

1.横向取值scrollLeft 竖向取值scrollTop 2.可以监听到最左最右侧 3.鼠标滚轮滑动控制滚动条滚动 效果 <template><div><div class"scrollable" ref"scrollableRef"><!-- 内容 --><div style"width: 2000px; height: 100…

WPF xaml 文件详解

<div id"content_views" class"htmledit_views"><h2><a name"t0"></a>1.总述</h2> 创建好了WPF项目后&#xff0c;最重要的是对 App和MainWindow的理解&#xff0c;在一开始的时候&#xff0c;极容易就直接在Main…

鸿蒙开发-ArkTS 创建自定义组件

在 ArkTS 中创建自定义组件是一个相对简单但功能强大的过程。以下是如何在 ArkTS 中创建和使用自定义组件的详细步骤&#xff1a; 一、定义自定义组件 使用Component注解&#xff1a;为了注册一个组件&#xff0c;使其能够在其他文件中被引用&#xff0c;你需要使用Component…

水表的数字表盘分割数据集labelme格式3023张13类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;3023 标注数量(json文件个数)&#xff1a;3023 标注类别数&#xff1a;13 标注类别名称:["readbox_1","center",&q…

跟着AI 学 AI, 开发一个ChatBot, 集成 Json 数据和查询

按照规律&#xff0c;使用AI生成一个架构图 直接上代码&#xff0c;为了方便学习&#xff0c;直接按照如下方式&#xff0c;复制到你的开发环境即可调试&#xff0c;运行代码。做学习参考。 代码注释多次说明这里&#xff0c;不在赘述。 "type": "carousel&qu…

使用枚举实现单例模式,不会反序列化破坏攻击,不会被反射破坏攻击。(附带枚举单例的简单实现)

原因分析 1.反序列化方法 ① jdk8中的Enum源码中对反序列化方法进行重写&#xff0c;抛出异常。 java.lang.Enum#readObject方法截图如下 ②java.io.ObjectInputStream#readObject 方法中的 readEnum 方法处理了枚举类型的反序列化&#xff0c;从而确保了枚举的单例特性。 …

MongoDB-副本集

一、什么是 MongoDB 副本集&#xff1f; 1.副本集的定义 MongoDB 的副本集&#xff08;Replica Set&#xff09;是一组 MongoDB 服务器实例&#xff0c;它们存储同一数据集的副本&#xff0c;确保数据的高可用性和可靠性。副本集中的每个节点都有相同的数据副本&#xff0c;但…

《数据结构》(408代码题)

2009 单链表&#xff08;双指针&#xff09; 分析&#xff1a;首先呢&#xff0c;给我们的数据结构是一个带有表头结点的单链表&#xff0c;也不允许我们改变链表的结构。链表的长度不是直接给出的啊&#xff0c;所以这个倒数也很棘手。那我们该如何解决这个“k”呢&#xff0c…