EN

2.4 相似度搜尋:找出相關向量

兩個向量有多像、怎麼量,以及資料很多時怎麼快速找到最接近的那幾個。

RAG下一篇 →

文字都變成向量之後,檢索就變成一個數學問題:給一個問題的向量,在一大堆向量裡,找出離它最近的 k 個。這就是相似性搜尋(similarity search)。

先要回答的是:怎麼量「兩個向量有多像」?

三種常見的量法

餘弦相似度(Cosine similarity)

看兩個向量方向的夾角。夾角越小,方向越一致,越相似。

cos(θ) = (A · B) / (‖A‖ × ‖B‖)

分子是兩個向量的內積,分母是兩個向量長度相乘。結果介於 -1 到 1:

  • 接近 1:方向幾乎一樣,意思很像。
  • 接近 0:沒什麼關係。
  • 接近 -1:方向相反。

餘弦相似度:兩個向量夾角越小,值越接近 1;夾角約 90 度,值接近 0

餘弦相似度是文字檢索最常用的量法,因為它只看方向、不看長度。一段話寫得長或短,不會影響它判斷意思像不像。

內積(Dot product)

直接把兩個向量對應位置的數字相乘再加起來。如果向量已經正規化(長度都調成 1),內積就等於餘弦相似度,而且算起來更快。很多嵌入模型的輸出本來就是正規化的。

歐氏距離(Euclidean distance)

兩個點之間的直線距離。越小越相似,跟前兩個相反(越大越相似)。

怎麼選

量法 數值方向 備註
餘弦相似度 越大越像 文字檢索最常用
內積 越大越像 向量正規化後等於餘弦相似度,速度快
歐氏距離 越小越像 向量正規化後,排名結果跟餘弦一致

最重要的是看嵌入模型的說明文件,它會告訴你建議用哪一種。向量資料庫建立索引時,也要設定同樣的量法。

暴力搜尋和近似搜尋

最直接的做法是暴力搜尋(brute force):把問題向量和知識庫裡每一個向量都算一次相似度,再排序取前 k 個。結果是最準確的,但資料量越大越慢。

  • 幾千筆:暴力搜尋完全沒問題。
  • 幾百萬筆以上:每次提問都要全部算一遍,太慢了。

大規模時會用近似最近鄰搜尋(Approximate Nearest Neighbor,ANN):事先建一個特別的索引結構,搜尋時只看一小部分最有希望的候選,換取速度。代價是偶爾會漏掉真正最近的那一個,但通常差距很小,大部分應用都能接受。

常見的 ANN 做法有:

  • HNSW:把向量組織成多層的圖,由上往下一路靠近目標,速度快、效果好,應用很廣。
  • IVF:先把向量分成很多群,搜尋時只去離問題最近的幾群找。

這些細節向量資料庫都會幫你處理,你通常只要知道它們存在,以及「速度」和「準確度」之間有取捨。

取回之後

搜尋的結果是一份排好序的清單:每一筆是一段內容和它的相似度分數。常見的後續處理有:

  • 只取前 k 段。
  • 設一個分數門檻,低於門檻的就算找不到,避免把完全不相關的內容硬塞給模型。
  • 之後還可以用更精細的重排序(rerank),把候選再排一次,這是進階的優化。
← 全部文章