余弦相似度公式推导及代码实现

news2024/11/19 0:40:27

余弦相似度公式推导

  • 1. 为什么使用余弦值相似度?
  • 2. 公式推导
    • 2.1 三角函数余弦公式推导
    • 2.2 三角函数向量余弦公式推导
  • 3. 余弦相似度代码实现

1. 为什么使用余弦值相似度?

  • 空间维度上两个点之间相似定义
    • 在空间维度上两个点之间是有夹角和方向,夹角范围在 [0,180]
    • 两个点越相似方向越接近相同方向夹角应该越小,越接近0度
    • 两个点意思相反方向越接近相反方向夹角应该越大,越接近180度
    • 两个点不相似方向垂直夹角应该接近90度
  • 为什么使用余弦值不用正弦值
    • 根据上述相似定义,我们需要找到夹角范围在[0,180]单调性的函数
    • 如下图,正弦值夹角范围在 [0,180],不是单调取值 【不符合】
    • 余弦值夹角范围在 [0,180]具有单调性
      • 夹角0,应该越相似夹角值越大(1)
      • 夹角90,应该无相关性夹角值0
      • 夹角180,应该意思相反夹角值越小(-1)
        在这里插入图片描述
  • 总结
    • 余弦单调性符合我们在空间维度位置的关系,所以使用余弦相似度 【自我理解】

2. 公式推导

2.1 三角函数余弦公式推导

c o s ( θ ) = A B 2 + A C 2 − B C 2 2 ∗ A B ∗ A C \begin{aligned} {cos}(\theta)&=\frac{{AB}^{2}+{AC}^{2}-{BC}^{2}}{2*AB*AC} \end{aligned} cos(θ)=2ABACAB2+AC2BC2
在这里插入图片描述

  • 余弦公式
    c o s ( θ ) = A D A C \begin{aligned} {cos}(\theta)=\frac{AD}{AC} \end{aligned} cos(θ)=ACAD
  • 勾股定理原理可得
    A C 2 = A D 2 + C D 2 ( 1 ) B C 2 = B D 2 + C D 2 ( 2 ) \begin{aligned} {AC}^{2}={AD}^{2}+{CD}^{2}\quad\quad\quad(1)\\ {BC}^{2}={BD}^{2}+{CD}^{2}\quad\quad\quad(2) \end{aligned} AC2=AD2+CD2(1)BC2=BD2+CD2(2)
  • 公式1-公式2
    A C 2 − B C 2 = A D 2 − B D 2 ( 3 ) \begin{aligned} {AC}^{2}-{BC}^{2}&={AD}^{2}-{BD}^{2}\quad\quad\quad(3)\\ \end{aligned} AC2BC2=AD2BD2(3)
  • A B , A D , B D AB,AD,BD AB,AD,BD之间的关系, A D AD AD未知值(但余弦公式需要参数), A B AB AB已知值,所以得到 B D BD BD相关公式,把 B D BD BD消掉
    A B = A D + B D B D = A B − A D ( 4 ) \begin{aligned} AB&=AD+BD\\ BD&=AB-AD\quad\quad\quad(4) \end{aligned} ABBD=AD+BD=ABAD(4)
  • 公式4带入公式3
    A C 2 − B C 2 = A D 2 − ( A B − A D ) 2 A C 2 − B C 2 = A D 2 − A B 2 + 2 ∗ A B ∗ A D − A D 2 A C 2 − B C 2 = − A B 2 + 2 ∗ A B ∗ A D A D = A B 2 + A C 2 − B C 2 2 ∗ A B ( 5 ) \begin{aligned} {AC}^{2}-{BC}^{2}&={AD}^{2}-{(AB-AD)}^{2}\\ {AC}^{2}-{BC}^{2}&={AD}^{2}-{AB}^{2}+2*AB*AD-{AD}^{2}\\ {AC}^{2}-{BC}^{2}&=-{AB}^{2}+2*AB*AD\\ AD&=\frac{{AB}^{2}+{AC}^{2}-{BC}^{2}}{2*AB}\quad\quad\quad\quad\quad(5) \end{aligned} AC2BC2AC2BC2AC2BC2AD=AD2(ABAD)2=AD2AB2+2ABADAD2=AB2+2ABAD=2ABAB2+AC2BC2(5)
  • 公式5带入余弦公式
    c o s ( θ ) = A D A C = A B 2 + A C 2 − B C 2 2 ∗ A B A C = A B 2 + A C 2 − B C 2 2 ∗ A B ∗ A C \begin{aligned} {cos}(\theta)&=\frac{AD}{AC}\\ &=\frac{\frac{{AB}^{2}+{AC}^{2}-{BC}^{2}}{2*AB}}{AC}\\ &=\frac{{AB}^{2}+{AC}^{2}-{BC}^{2}}{2*AB*AC} \end{aligned} cos(θ)=ACAD=AC2ABAB2+AC2BC2=2ABACAB2+AC2BC2

2.2 三角函数向量余弦公式推导

c o s ( θ ) = a ⃗ ∗ b ⃗ ∥ a ∥ ∗ ∥ b ∥ \begin{aligned} {cos}(\theta)&=\frac{\vec{a}*\vec{b}}{\parallel a\parallel*\parallel b\parallel} \end{aligned} cos(θ)=aba b

  • 向量公式
    c ⃗ = a ⃗ − b ⃗ ( 1 ) A C = ∥ b ⃗ ∥ ( 2 ) A B = ∥ a ⃗ ∥ ( 3 ) B C = ∥ c ⃗ ∥ ( 4 ) \begin{aligned} \vec{c}&=\vec{a}-\vec{b}\quad\quad(1)\\ AC &=\parallel \vec{b} \parallel\quad\quad(2)\\ AB &=\parallel \vec{a} \parallel\quad\quad(3)\\ BC &=\parallel \vec{c} \parallel\quad\quad(4)\\ \end{aligned} c ACABBC=a b (1)=∥b (2)=∥a (3)=∥c (4)
    在这里插入图片描述
  • 公式 1 , 2 , 3 , 4 公式1,2,3,4 公式1234带入余弦公式
    c o s ( θ ) = A B 2 + A C 2 − B C 2 2 ∗ A B ∗ A C c o s ( θ ) = ∥ a ⃗ ∥ 2 + ∥ b ⃗ ∥ 2 − ( ∥ a ⃗ − b ⃗ ∥ ) 2 2 ∗ ∥ a ⃗ ∥ ∗ ∥ b ⃗ ∥ c o s ( θ ) = ∥ a ⃗ ∥ 2 + ∥ b ⃗ ∥ 2 − ∥ a ⃗ ∥ 2 + 2 ∗ a ⃗ ∗ b ⃗ − ∥ b ⃗ ∥ 2 2 ∗ ∥ a ⃗ ∥ ∗ ∥ b ⃗ ∥ c o s ( θ ) = a ⃗ ∗ b ⃗ ∥ a ∥ ∗ ∥ b ∥ \begin{aligned} {cos}(\theta)&=\frac{{AB}^{2}+{AC}^{2}-{BC}^{2}}{2*AB*AC}\\ {cos}(\theta)&=\frac{{\parallel \vec{a} \parallel}^{2}+{\parallel \vec{b} \parallel}^{2}-({\parallel\vec{a}-\vec{b}\parallel)}^{2}}{2*\parallel \vec{a} \parallel*\parallel \vec{b} \parallel}\\ {cos}(\theta)&=\frac{{\parallel \vec{a} \parallel}^{2}+{\parallel \vec{b} \parallel}^{2}-{\parallel \vec{a} \parallel}^{2}+2*\vec{a}*\vec{b}-{\parallel \vec{b} \parallel}^{2}}{2*\parallel \vec{a} \parallel*\parallel \vec{b} \parallel}\\ {cos}(\theta)&=\frac{\vec{a}*\vec{b}}{\parallel a\parallel*\parallel b\parallel} \end{aligned} cos(θ)cos(θ)cos(θ)cos(θ)=2ABACAB2+AC2BC2=2a b a 2+b 2(a b )2=2a b a 2+b 2a 2+2a b b 2=aba b

3. 余弦相似度代码实现

  • 代码来自于书籍:深度学习进阶:自然语言处理
    import numpy as np
    
    def preprocess(text):
        """
           语料库预处理
    
           :param text:句子字符串
           :return:
                corpus 是单词ID 列表
                word_to_id:是单词到单词 ID 的字典
                id_to_word 是单词 ID 到单词的字典
        """
        text = text.lower().replace('.', ' .') # 单词全为小写
        words = text.split(' ') # 以空格分隔
        word_to_id = {}
        id_to_word = {}
        for word in words:
         if word not in word_to_id:
             new_id = len(word_to_id)
             word_to_id[word] = new_id
             id_to_word[new_id] = word
        corpus = np.array([word_to_id[w] for w in words])
        return corpus, word_to_id, id_to_word
    def create_co_matrix(corpus, vocab_size, window_size=1):
        """
        语料库生成共现矩阵
    
           :param corpus:corpus 是单词 ID 列表
           :param vocab_size:词汇个数
           :param window_size:窗口大小
           :return:
                共现矩阵
        """
        corpus_size = len(corpus)
        co_matrix = np.zeros((vocab_size, vocab_size), dtype=np.int32)
        for idx, word_id in enumerate(corpus):
            for i in range(1, window_size + 1):
                left_idx = idx - i
                right_idx = idx + i
                if left_idx >= 0:
                    left_word_id = corpus[left_idx]
                    co_matrix[word_id, left_word_id] += 1
                if right_idx < corpus_size:
                    right_word_id = corpus[right_idx]
                    co_matrix[word_id, right_word_id] += 1
        return co_matrix
    def cos_similarity(x, y, eps=1e-8):
        """
        余弦相似度函数
    
        :param x:x坐标值
        :param y:y坐标值
        :param eps:默认值为1e-8,防止分母为0
        :return:
            余弦相似度值
        """
        nx = x / (np.sqrt(np.sum(x ** 2)) + eps)
        ny = y / (np.sqrt(np.sum(y ** 2)) + eps)
        return np.dot(nx, ny)
    text = 'I say hello and You say goodbye.'
    corpus, word_to_id, id_to_word = preprocess(text)
    print("corpus为:",corpus)
    print("word_to_id为:",word_to_id)
    print("id_to_word为:",id_to_word)
    vocab_size=len(set(corpus))
    C=create_co_matrix(corpus, vocab_size, window_size=1)
    print("共现矩阵为:",C)
    c0 = C[word_to_id['you']] # you的单词向量
    c1 = C[word_to_id['i']] # i的单词向量
    print('you和i的相似度为',cos_similarity(c0, c1))
    
    

在这里插入图片描述

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

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

相关文章

计算机操作系统实验:页面置换算法的实现

目录 前言实验目的实验内容实验过程最佳置换算法代码实现算法流程流程图设计思路运行结果 先进先出算法代码实现算法流程流程图设计思路运行结果 最近最久未使用算法代码实现算法流程流程图设计思路运行结果 总结 前言 本实验的目的是通过编程模拟不同的页面置换算法&#xff…

基于思科模拟器的路由与交换实训报告(单臂路由、三层交换机实现vlan通信、ospf、rip、dhcp、acl、nat技术总结)

本博客是路由与交换实训报告&#xff0c;基于思科模拟器分别做了单臂路由、三层交换机实现vlan间通信、ospf、rip、dhcp、nat的实验&#xff0c;最后的nat综合实验是本次实训的大拓扑&#xff0c;综合了上述的几个技术。 大家可以当作一些思科小实验的总结&#xff0c;供网络工…

数据库管理-第七十二期 复盘(20230505)

数据库管理 2023-05-05 第七十二期 复盘1 再测试2 对照分析&#xff1a; 3 如何解决总结 第七十二期 复盘 上一期的内容&#xff0c;我承认主要是在放假&#xff0c;分析过程还是水了一点&#xff0c;SR转回国内之后&#xff0c;处理效率还是提升了一大截。 1 再测试 在客户…

Linux - 第11节 - 网络基础(一)

1.计算机网络背景 1.1.网络发展 独立模式&#xff1a;计算机之间相互独立 在早期的时候&#xff0c;计算机之间是相互独立的&#xff0c;此时如果多个计算机要协同完成某种业务&#xff0c;那么就只能等一台计算机处理完后再将数据传递给下一台计算机&#xff0c;然后下一台计…

Python进阶——实现人脸识别

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 今天我们来实现一下人脸识别~ 先问大家一个问题 什么是百度Aip模块&#xff1f; 百度AI平台提供了很多的API接口供开发者快速的调用运用在项目中 本文写的是使用百度AI的在线接口SDK模块&#xff08;baidu-aip&#…

单链表——单链表的定义及基本操作(初始化、头插法尾插法建表、查找、插入、删除、判空等)

单链表的定义 由于顺序表存在以下缺陷&#xff0c;所以衍生出了链表&#xff0c;而链表种类有很多种&#xff0c;今天我们讲的是单链表。 顺序表存在的问题如下 1.中间/头部的插入删除&#xff0c;时间复杂度为O(N) 2. 增容需要申请新空间&#xff0c;拷贝数据&#xff0c;释…

CPU 架构(x86/ARM)简介

CPU 架构通过指令集的方式一般可分为 复杂指令集&#xff08;CISC&#xff09; 和 精简指令集&#xff08;RISC&#xff09; 两类&#xff0c;CISC 主要是 x86 架构&#xff0c;RISC 主要是 ARM 架构&#xff0c;还有 MIPS、RISC-V、PowerPC 等架构。 本文重点介绍 x86 和 ARM…

idea中maven的几个操作按钮:clean、validate、compile...

idea中Maven生命周期指令 clean命令 清除由项目编译创建的target validate命令 验证项目是否正确&#xff0c;并且所有必要的信息均可用 compile命令 编译项目的源代码 test命令 使用合适的单元测试框架来测试编译的源代码。 这些测试不应要求将代码打包或部署 verify命令 …

智安网络|一文看懂内核平台和系统服务的联系

内核平台和系统服务是操作系统中两个非常重要的组成部分。内核平台是系统底层的核心&#xff0c;负责管理和控制计算机硬件和资源的访问。而系统服务则是在内核之上运行的程序集合&#xff0c;为操作系统提供各种功能和服务。 内核平台和系统服务的关联非常密切。系统服务必须…

Emqx的简单使用

Emqx 是一个mqtt 的服务器产品。之前activemq可以作为mqtt协议的服务器&#xff0c;但是功能相对来说比较单一。Emqx作为跟Mqtt协议相关的新一代产品&#xff0c;功能实际上更为强大。 它的功能也主要体现在可视化/认证/规则/httpApi 上面。 1.Emqx 的安装 这里采用了docker…

JMeter 计算上一个接口取值到本次接口进行四则运算赋值

项目场景&#xff1a; 公司项目需要接口关联计算进行赋值&#xff1a; 项目场景&#xff1a;A接口提取的返回值&#xff0c;在传到B接口使用时&#xff0c;需要先进行四则运算后&#xff0c;再赋值使用。 A接口提取的值 B接口需要使用计算后的值 问题描述 使用beanshell预…

必须掌握的ArrayList,LinkedList,HashMap,HashTable,Collection,Colections

人的自由并不在于可以做他想做的事&#xff0c;而在于可以不做他不想做的事。 ArrayList和linkedList的区别 Array数组是基于索引&#xff08;index&#xff09;的数据结构&#xff0c;它使用索引在数组中搜索和读取数据是很快的 Array获取数据的时间复杂度是o(1)&#xff…

南卡OE系列再添新成员,造型犀利有型,性能强劲动听!

科技的快速发展让消费者对智能互联、操作体验、设计审美、安全健康等需求越发高涨&#xff0c;蓝牙耳机也正在由功能性向舒适性方向发展。如何提高蓝牙耳机的舒适度、拥有更舒适的听歌体验&#xff0c;成为蓝牙耳机品牌和消费者共同努力的方向。 Nank南卡&#xff1a;更专业的骨…

【Linux】单机版QQ之管道中的命名管道

还记得上一篇的匿名管道吗&#xff1f; 文章目录 前言一、命名管道总结 前言 命名管道是什么呢&#xff1f; 管道应用的一个限制就是只能在具有共同祖先&#xff08;具有亲缘关系&#xff09;的进程间通信。 如果我们想在不相关的进程之间交换数据&#xff0c;可以使用FIFO文…

一百零七、MySQL数据库的数据备份与数据恢复

MySQL数据库的数据备份与恢复主要有3种方法&#xff0c;前两种都是MySQL dump命令&#xff0c;第三种则是用Navicat工具直接备份。相比而言&#xff0c;第三种方法更加简单&#xff01; 1 方法一&#xff08;MySQL dump命令&#xff09; 1.1 登录MySQL [roothurys22 ~]# mysq…

Maya云渲染如何使用,Maya云渲染流程实操!

Maya 是一款专业的 3D 软件&#xff0c;用于创建逼真的角色和大片的效果&#xff0c;Maya可以加速工作流程&#xff0c;帮助您专注于创造力并按时完成任务。也可以为角色和场景添加精美的细节&#xff0c;并提供让客户满意的优质作品。更有无数业内顶级艺术家依靠 Maya来创作更…

【Halcon】新建程序 读取图片 路径设置

文章目录 1 新建程序2 读取一张图片3 图片路径4 图片格式读取报错5 快速添加 绝对路径 1 新建程序 点击新程序图标&#xff0c;即可新建&#xff1b; 程序另存为&#xff0c;会弹出保存路径 2 读取一张图片 read_image(Image,fabrik)此时工程路径下并没有图片&#xff1b; …

SpringBoot2 集成 ELK 实现日志收集

目录 一 简介 二 ELK 各组件作用 三 ELK 各组件安装 四 Spring Boot2 集成 logstash 一 简介 ELK 即 Elasticsearch、Logstash、Kibana 组合起来可以搭建线上日志系统&#xff0c;本文主要讲解使用ELK 来收集 SpringBoot2 应用产生的日志。 二 ELK 各组件作用 Elasticsea…

基于FPGA和Matlab实现的FFT功能验证

一 、FFT设计验证思路 1、基于Matlab与FPGA的混频sin信号的FFT验证&#xff0c;分别在Matlab和FPGA开发环境上实现相同的FFT功能设计。 2、Matlab平台开发&#xff0c;使用自带的fft函数与相关操作函数&#xff0c;绘制出混频sin信号&#xff0c;经过fft功能处理后的频谱图。 3…

2022 ios APP最新开发测试教程

转载&#xff1a;2022 ios APP最新开发测试教程1.本文详细介绍最新的在windows上进行ios app开发编译打包安装到手机测试的完整流程。介绍ios开发经常遇到的问题和解决方法&#xff0c;包括ios开发证书&#xff0c;ios开发描述文件等。http://kxdang.com/topic/appuploader/ios…