文章目錄
- 前言
- 場景設定:披薩特征向量化
- 顧客到來:生成查詢向量
- 相似度計算實戰
- 1. 歐氏距離計算(值越小越相似)
- 2. 余弦相似度計算(值越大越相似)
- 關鍵發現:度量選擇影響結果
- 現實啟示
- 結語
前言
想象你走進一家數字化的披薩餐廳,這里用AI技術優化了點餐流程。讓我們通過這個生動場景來解釋向量數據庫的核心概念。
場景設定:披薩特征向量化
這家餐廳把每種披薩用3個特征表示(實際應用中可能有幾百維):
- 咸度(0-10)
- 芝士量(0-10)
- 辣度(0-10)
現有3種披薩在"向量菜單"中:
披薩類型 | 向量表示 |
---|---|
瑪格麗特 | [3, 8, 1] |
辣香腸 | [7, 6, 5] |
四季披薩 | [5, 5, 2] |
顧客到來:生成查詢向量
你說:“我想要一份比較咸、芝士多但不太辣的披薩”,AI將其轉換為查詢向量:
[7, 9, 2]
相似度計算實戰
1. 歐氏距離計算(值越小越相似)
數學定義
L2(x,y) = √Σ(x_i - y_i)2
計算與瑪格麗特披薩的距離:
√[(7-3)2 + (9-8)2 + (2-1)2]
= √(16 + 1 + 1)
= √18 ≈ 4.24
與辣香腸的距離:
√[(7-7)2 + (9-6)2 + (2-5)2]
= √(0 + 9 + 9)
= √18 ≈ 4.24
與四季披薩的距離:
√[(7-5)2 + (9-5)2 + (2-2)2]
= √(4 + 16 + 0)
= √20 ≈ 4.47
結果:瑪格麗特和辣香腸并列最近(4.24)
2. 余弦相似度計算(值越大越相似)
數學定義:
cos(x,y) = (x·y)/(||x||*||y||)
計算與瑪格麗特披薩的相似度:
分子:7*3 + 9*8 + 2*1 = 21 + 72 + 2 = 95
分母:√(72+92+22) * √(32+82+12)
= √(49+81+4) * √(9+64+1)
= √134 * √74 ≈ 11.58 * 8.60 ≈ 99.6
相似度:95/99.6 ≈ 0.954
與辣香腸的相似度:
7*7 + 9*6 + 2*5 = 49 + 54 + 10 = 113
√134 * √(72+62+52) = 11.58 * √110 ≈ 11.58*10.49≈121.5
相似度:113/121.5 ≈ 0.930
與四季披薩的相似度:
7*5 + 9*5 + 2*2 = 35 + 45 + 4 = 84
√134 * √(52+52+22) = 11.58 * √54 ≈ 11.58*7.35≈85.1
相似度:84/85.1 ≈ 0.987
結果:四季披薩最相似(0.987)!
關鍵發現:度量選擇影響結果
- 歐氏距離推薦:
- 瑪格麗特(咸度3)和辣香腸(咸度7)
- 雖然瑪格麗特咸度不符合要求,但芝士量接近
- 余弦相似度推薦:
- 四季披薩(咸度5)
- 因為它的特征比例最接近查詢(咸:芝士:辣 ≈ 7:9:2 vs 5:5:2)
現實啟示
- 歐氏距離像"絕對匹配":適合找特征值接近的產品
- 余弦相似度像"比例匹配":適合找風味組合相似的菜品
- 向量數據庫就是這位聰明的服務員,能快速比較數百種披薩的特征
# 用代碼驗證我們的計算
import numpy as npmenu = {"Margherita": np.array([3, 8, 1]),"Pepperoni": np.array([7, 6, 5]),"Quattro": np.array([5, 5, 2])
}query = np.array([7, 9, 2])# 歐氏距離計算
print("歐氏距離:")
for name, vec in menu.items():dist = np.linalg.norm(query - vec)print(f"{name}: {dist:.2f}")# 余弦相似度計算
print("\n余弦相似度:")
for name, vec in menu.items():cosine = np.dot(query, vec) / (np.linalg.norm(query)*np.linalg.norm(vec))print(f"{name}: {cosine:.3f}")
輸出結果:
歐氏距離:
Margherita: 4.24
Pepperoni: 4.24
Quattro: 4.47余弦相似度:
Margherita: 0.954
Pepperoni: 0.930
Quattro: 0.987
結語
這個美味的例子展示了:不同的相似度度量會導致不同的推薦結果,實際應用中需要根據業務需求選擇合適的度量方式。向量數據庫的價值就在于它能高效處理這類比較操作,即使面對百萬級"菜單"也能快速響應。