news 2026/4/16 11:59:56

第三篇:一眼看穿相似度:余弦相似度原理详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
第三篇:一眼看穿相似度:余弦相似度原理详解

一眼看穿相似度:余弦相似度原理详解

前言

在上一篇《手把手实现文本向量数据库》中,我们用余弦相似度来判断两段文字是否相似。但有一个关键问题没讲清楚:

为什么用一个数学公式就能判断"语义是否相似"?

这篇文章,我们专门聊聊余弦相似度背后的原理。

读完这篇,你就明白:

  • 余弦相似度是怎么算的
  • 为什么它适合判断文本相似度
  • 为什么不用正弦或其他方法

一、先说个直观的例子

还记得我们知识库里的两句话吗:

句子A:"阿尔忒弥斯2号是美国宇航局计划中的载人月球轨道飞行任务" 句子B:"该任务将使用太空发射系统火箭和猎户座飞船"

用户问:“月球任务是什么?”

你觉得哪句话更相关?

肯定是句子A对吧?因为A里有"月球"、"任务"这些词。

电脑也是这么想的。但它不会"感觉",它只会"算"。


二、把句子变成数字

我们用词汇表把句子变成一串数字:

词汇表:阿尔忒弥斯、月球、任务、宇航员、火箭、飞船、测试、系统、飞行、轨道

句子A出现了哪些词?数一数:

"阿尔忒弥斯2号是...载人月球轨道飞行任务" → 阿尔忒弥斯(1)、月球(1)、任务(1)、飞行(1)、轨道(1) 向量A = [1, 1, 1, 0, 0, 0, 0, 0, 1, 1]

句子B出现了哪些词?

"该任务将使用太空发射系统火箭和猎户座飞船" → 任务(1)、火箭(1)、飞船(1)、系统(1) 向量B = [0, 0, 1, 0, 1, 1, 0, 1, 0, 0]

现在两句话都变成数字了:

阿尔忒弥斯 月球 任务 宇航员 火箭 飞船 测试 系统 飞行 轨道 句子A: 1 1 1 0 0 0 0 0 1 1 句子B: 0 0 1 0 1 1 0 1 0 0

三、怎么算"像不像"?

方法一:直接比差距

把两个向量减一减,看差多少:

差距 = |1-0| + |1-0| + |1-1| + ... = 1+1+0+0+1+1+0+1+1+1 = 7

差距是7,看起来不太像?

但问题是:如果一个句子很长,出现很多词,另一个很短,差距就大了。可它们可能说的都是同一件事!

方法二:看"方向"像不像

我们换个思路:不管句子长短,只看"主要讲啥"。

想象一下,站在操场中央:

  • 句子A往"月球方向"走
  • 句子B往"火箭方向"走

走的方向不一样,所以不像。

但如果:

  • 句子A说:“月球任务月球任务”("月球"出现2次,"任务"出现2次)
  • 句子B说:“月球任务”

方向是一样的!都是往"月球任务"方向走。

这就是余弦相似度的核心思想:

方向一致 = 内容相似


四、用直角坐标系来理解

还记得学校里学的直角坐标系吗?画个十字,横轴竖轴。

我们把词汇表简化一下,只看两个词:月球、火箭

句子A:"月球任务" → 月球(1),火箭(0) 句子B:"火箭发射" → 月球(0),火箭(1) 句子C:"月球火箭" → 月球(1),火箭(1)

画在坐标系里:

Y轴(火箭) ↑ | ● 句子B(月球0,火箭1) | | | ● 句子C(月球1,火箭1) | / | / -----●--------/----→ X轴(月球) | / | / | ● 句子A(月球1,火箭0) |

从原点(0,0)到每个点画一条线:

  • 句子A往右走(月球方向)
  • 句子B往上走(火箭方向)
  • 句子C往右上方走(两个都有)

夹角越小 = 方向越像 = 内容越像


五、余弦是啥?为啥能判断像不像?

先记住这个规律

角度 余弦值 意思 0° → 1.0 完全一样 45° → 0.7 很像 60° → 0.5 有点像 90° → 0 完全不同

结论:余弦值越接近1,越像!

有人问:为什么不用正弦?

好问题!我们来对比一下:

角度 余弦值 正弦值 哪个更合理? 0° → 1.0 0.0 余弦:完全一样 ✅ 正弦:??? 45° → 0.7 0.7 一样 90° → 0.0 1.0 余弦:完全不同 ✅ 正弦:完全一样?❌ 180° → -1.0 0.0 余弦:完全相反 ✅ 正弦:和0°一样?❌

正弦有两个大问题

问题一:方向相反也算"一样"?

  • 两个句子意思完全相反(夹角180°)
  • 正弦值 = 0
  • 和夹角0°(意思完全相同)的正弦值一样!
  • 没法区分"相同"和"相反"

问题二:直觉反了

  • 我们希望:越相似 → 数值越大
  • 正弦:θ=0°(相同)→ sin=0(最小值)
  • 这让人很难理解

余弦刚刚好

  • 相同方向(0°)→ cos=1(最大)→ 相似度最高 ✅
  • 垂直方向(90°)→ cos=0 → 完全无关
  • 相反方向(180°)→ cos=-1 → 完全相反

六、实际计算演示

用户问:“月球任务是什么?”

先算用户问题的向量:

"月球任务" → 月球(1),任务(1) 问句向量 = [0, 1, 1, 0, 0, 0, 0, 0, 0, 0] (为了简化,只标出非0的位置)

然后和知识库里的句子比一比:

和句子A比

问句向量 = [0, 1, 1, 0, 0, 0, 0, 0, 0, 0] 句子A = [1, 1, 1, 0, 0, 0, 0, 0, 1, 1] ↑ ↑ ↑ ↑ ↑ | | | | | 阿尔忒弥斯 月球 任务 ... 飞行 轨道 第一步:算乘积之和(把对应位置乘起来,再加到一起) = 0×1 + 1×1 + 1×1 + 0×0 + ... = 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 = 2 ← 这个2代表:问句和句子A有2个词是"重叠"的(月球、任务) 第二步:算各自的"长度" 问句长度 = √(0² + 1² + 1² + 0² + ...) = √2 ≈ 1.41 ↑ 这个√2里的2代表:问句有2个词(月球、任务) 句子A长度 = √(1² + 1² + 1² + 0² + 0² + 0² + 0² + 0² + 1² + 1²) = √4 = 2 ↑ 这个2代表:句子A有4个"1",开根号后等于2 第三步:算相似度 2(乘积之和:共同词的数量) 相似度 = ─────────────────────────── = 2 / 2.82 ≈ 0.71 1.41 × 2(两个向量的长度相乘) ↑ ↑ | └── 句子A的长度 └── 问句的长度

和句子B比

问句向量 = [0, 1, 1, 0, 0, 0, 0, 0, 0, 0] 句子B = [0, 0, 1, 0, 1, 1, 0, 1, 0, 0] 乘积之和 = 0×0 + 1×0 + 1×1 + ... = 1 问句长度 = 1.41 句子B长度 = √(0+0+1+0+1+1+0+1+0+0) = √3 ≈ 1.73 相似度 = 1 / (1.41 × 1.73) ≈ 0.41

结果对比

句子A相似度 = 0.71 ← 更像! 句子B相似度 = 0.41

对!句子A确实更相关,因为它有"月球"和"任务"两个词都匹配上了。


七、为什么这个方法好?

好处一:不怕句子长短

句子长了,词就多,向量里的数字就大。但没关系!

"月球月球月球" → 向量 [0, 3, 0, ...] "月球" → 向量 [0, 1, 0, ...] 相似度 = 1.0(完全一样!)

因为余弦相似度只看"方向",不看"长度"。两个句子都在讲月球,方向一致!

好处二:结果好理解

相似度 意思 0.9+ 几乎一样 0.7-0.9 非常相关 0.5-0.7 比较相关 0.3-0.5 有点关系 0-0.3 基本无关

就像考试打分,一眼就看懂。

好处三:能理解"意思相近"的词

知识库里写的是"执行",用户问的是"发射":

知识库:"任务计划在2025年执行" 用户问:"什么时候发射?"

虽然词不一样,但"执行"和"发射"都会出现在相似的句子里,所以向量方向会接近,余弦相似度就会高。

这就是语义理解


八、公式总结

完整公式

余弦相似度 = cos(θ) = (A · B) / (|A| × |B|) 其中: - A · B = a₁×b₁ + a₂×b₂ + ... + aₙ×bₙ (点积:对应位置相乘再相加) - |A| = √(a₁² + a₂² + ... + aₙ²) (向量长度:各元素平方和开根号) - |B| = √(b₁² + b₂² + ... + bₙ²)

三个步骤

第一步:算点积(共同词的数量) 第二步:算长度(各自有多少词) 第三步:点积除以长度乘积

九、代码实现

// 计算余弦相似度(三个步骤)funccosineSimilarity(a,b[]float64)float64{// 第一步:算乘积之和dotProduct:=0.0fori:=rangea{dotProduct+=a[i]*b[i]}// 第二步:算各自的"长度"lengthA:=0.0lengthB:=0.0fori:=rangea{lengthA+=a[i]*a[i]lengthB+=b[i]*b[i]}lengthA=math.Sqrt(lengthA)lengthB=math.Sqrt(lengthB)// 第三步:相除得到相似度iflengthA==0||lengthB==0{return0// 防止除以0}returndotProduct/(lengthA*lengthB)}

对照上面的步骤,一行行看就懂了!


十、总结

余弦相似度 = 看"方向"像不像,不看"长度"差多少

核心思想:

  1. 把文字变成一串数字(向量)
  2. 用余弦公式算相似度
  3. 结果越接近1,内容越像

为什么用余弦不用正弦:

  • 余弦:相同→1,不同→0,相反→-1(直观!)
  • 正弦:相同→0,不同→1(反了!)

系列文章

  1. Go + Ollama 构建tinyRAG应用:Prompt提示工程
  2. 用阿尔忒弥斯2号讲透文本向量化
  3. 本文:一眼看穿相似度:余弦相似度原理详解
  4. 下一篇:手把手实现文本向量数据库(预告)

系列文章

  1. Go + Ollama 构建tinyRAG应用:Prompt提示工程
  2. 用阿尔忒弥斯2号讲透文本向量化
  3. 本文:一眼看穿相似度:余弦相似度原理详解
  4. 手把手实现文本向量数据库
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 11:59:15

田间小气候监测站 十要素农业气象站

农田生态气象站,作为高标准农田标配的气象监测设备,聚焦“四情”监测中的气象刚需,可实时采集农田周边核心气象要素,为“四情”监测提供基础数据支撑,实现“气象数据四情监测”联动,助力农业工作人员精准掌…

作者头像 李华
网站建设 2026/4/16 11:55:21

新手避坑指南:C++原子操作中compare_exchange_weak的5个常见误用场景

C原子操作实战:避开compare_exchange_weak的五大深坑 第一次接触C原子操作时,compare_exchange_weak就像个神秘的黑盒子——看似简单,却总在关键时刻给你"惊喜"。记得我刚用这个函数实现自旋锁时,程序偶尔会莫名其妙地卡…

作者头像 李华
网站建设 2026/4/16 11:54:54

华为OD Python面试通关指南:从高频考点到实战解析

1. 高频考点深度解析 1.1 Python执行效率优化实战 在华为OD的Python面试中,性能优化是必考题。我当年面试时就遇到过这样的场景:面试官给出一段存在明显性能问题的代码,要求现场优化。这里分享几个真正有效的优化手段: 算法层面的…

作者头像 李华
网站建设 2026/4/16 11:52:25

利用组策略与VBS脚本自动化管理域用户登录权限及设备信息收集

1. 为什么需要自动化管理域用户登录权限 在企业IT管理中,经常会遇到这样的场景:公司希望员工只能在自己的办公电脑上登录域账号,而不能随意在其他电脑上使用个人账号。这种需求在金融、研发等对数据安全要求较高的行业尤为常见。 传统做法是…

作者头像 李华
网站建设 2026/4/16 11:51:30

3大核心优化方案:让暗黑破坏神2在现代PC上焕发新生

3大核心优化方案:让暗黑破坏神2在现代PC上焕发新生 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在为…

作者头像 李华
网站建设 2026/4/16 11:50:20

Excel数据验证进阶:打造动态智能下拉菜单的三种实战方案

1. 为什么需要动态智能下拉菜单? 相信很多Excel用户都遇到过这样的场景:每个月都要手动更新产品清单下拉菜单,省市区三级联动要反复维护,或者要从几千个商品里找到目标选项。传统静态下拉菜单不仅效率低下,还容易出错。…

作者头像 李华