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

张开发
2026/5/23 4:07:10 15 分钟阅读
第三篇:一眼看穿相似度:余弦相似度原理详解
一眼看穿相似度余弦相似度原理详解前言在上一篇《手把手实现文本向量数据库》中我们用余弦相似度来判断两段文字是否相似。但有一个关键问题没讲清楚为什么用一个数学公式就能判断语义是否相似这篇文章我们专门聊聊余弦相似度背后的原理。读完这篇你就明白余弦相似度是怎么算的为什么它适合判断文本相似度为什么不用正弦或其他方法一、先说个直观的例子还记得我们知识库里的两句话吗句子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| ... 1100110111 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°相同→ sin0最小值这让人很难理解余弦刚刚好相同方向0°→ cos1最大→ 相似度最高 ✅垂直方向90°→ cos0 → 完全无关相反方向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长度 √(0010110100) √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{dotProducta[i]*b[i]}// 第二步算各自的长度lengthA:0.0lengthB:0.0fori:rangea{lengthAa[i]*a[i]lengthBb[i]*b[i]}lengthAmath.Sqrt(lengthA)lengthBmath.Sqrt(lengthB)// 第三步相除得到相似度iflengthA0||lengthB0{return0// 防止除以0}returndotProduct/(lengthA*lengthB)}对照上面的步骤一行行看就懂了十、总结余弦相似度 看方向像不像不看长度差多少核心思想把文字变成一串数字向量用余弦公式算相似度结果越接近1内容越像为什么用余弦不用正弦余弦相同→1不同→0相反→-1直观正弦相同→0不同→1反了系列文章Go Ollama 构建tinyRAG应用Prompt提示工程用阿尔忒弥斯2号讲透文本向量化本文一眼看穿相似度余弦相似度原理详解下一篇手把手实现文本向量数据库预告系列文章Go Ollama 构建tinyRAG应用Prompt提示工程用阿尔忒弥斯2号讲透文本向量化本文一眼看穿相似度余弦相似度原理详解手把手实现文本向量数据库

更多文章