jollen.org

Jollen 的 Blog
Jollen's email: jollen # jollen.org
more:  Jollen's Training

RAG 向量距離計算:餘弦相似度(Cosine Similarity)概論

.作者:Jollen/
.日期:Sun Nov 09 2025 08:00:00 GMT+0800 (台北標準時間)


之前的教學,我們將語言變成可運算的數學表達式。接下來,就是要實際寫程式判斷兩個句子是否「語意相近」,最基本的方法,就是:餘弦相似度(Cosine Similarity)。

何謂「餘弦」相似度

假設我們把每個句子看作是一個向量,它在語意空間中都有一個方向。兩個向量的「夾角」越小,代表語意越接近;夾角越大,代表語意越不同。我們不關心句子的「長度」有多長,而是關心它們「指向的方向」是否一致。這正是餘弦相似度的核心觀念。

餘弦相似度的數學定義如下:

[ \text{similarity}(A, B) = \frac{A \cdot B}{|A||B|} ]

其中:

  • (A \cdot B):兩個向量的內積(dot product)
  • (|A|) 與 (|B|):分別是兩個向量的長度(norm)
  • 結果範圍介於 (-1) 到 (1)。

計算角度(語意差距)

在語意搜尋的應用中,要從語意判斷轉化為距離計算,可以分為四個步驟:

  1. 語句轉向量:透過 Embedding 模型將每句話轉為向量。
  2. 向量正規化:確保所有向量在相同維度下可比較。
  3. 計算內積:求出兩個向量之間的夾角關係。
  4. 取得相似度:以 (\frac{A \cdot B}{|A||B|}) 的結果作為語意相似度。

這樣,我們就能在數學空間中衡量語言的距離。計算結果如下:

結果值 語意關係
接近 1 兩句話語意非常相似
接近 0 幾乎無關聯
接近 -1 語意相反(自然語言中較少見)

也就是說,餘弦相似度不僅僅是一個數學計算,而是一種「語意角度」的量化方式。它將抽象的語意關聯轉換為具體的可比數值。

Node.js 實作:語意相似度運算

以下範例展示如何以 Node.js 實際計算句子之間的餘弦相似度。此範例承接前述的 Embedding 範例:

// src/examples/cosine-similarity.js
import OpenAI from 'openai';
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

// 餘弦相似度函式
function cosineSimilarity(a, b) {
  const dot = a.reduce((sum, val, i) => sum + val * b[i], 0);
  const normA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0));
  const normB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0));
  return dot / (normA * normB);
}

async function main() {
  const sentences = ['退貨政策', '退款流程', '物流延誤'];

  // 生成向量
  const { data } = await client.embeddings.create({
    model: 'text-embedding-3-small',
    input: sentences
  });

  const [v1, v2, v3] = data.map(d => d.embedding);

  console.log('\n語意相似度:');
  console.log(`退貨政策 vs 退款流程 → ${cosineSimilarity(v1, v2).toFixed(3)}`);
  console.log(`退貨政策 vs 物流延誤 → ${cosineSimilarity(v1, v3).toFixed(3)}`);
}

main();

Text Embedding 模型會回傳每句話的 embedding 物件,裡面包含該句子的向量值;接著,以餘弦來計算其相似度。執行後可得到類似輸出:

語意相似度:
退貨政策 vs 退款流程 → 0.436
退貨政策 vs 物流延誤 → 0.395

我們針對「退貨政策」與這二句話的距離做比較。以此例來看:

  • 「退貨政策」與「退款流程」的語意距離較近
  • 「退貨政策」與「物流延誤」的距離較遠

這表示語意空間中的「距離」,確實能對應到人類概念上的「語意理解能力」。


Tags: rag, llm, text-embedding

純手工打造說明:技術專欄文章為 Jollen 原創,內容皆為人工撰寫,無 AI 生成。轉載請註明出處與作者,並全文引用。轉載時請在文章開頭或結尾明顯處註明「本文出處: https://www.jollen.org, 已取得原作者同意並授權使用.」。

Copyright(c) 2001–2025 www.jollen.org. All rights reserved.
Last update: November 10, 2025 at 7:30 PM