文章目录
- 前言
- 场景设定:披萨特征向量化
- 顾客到来:生成查询向量
- 相似度计算实战
- 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)²
计算与玛格丽特披萨的距离:
√[(7-3)² + (9-8)² + (2-1)²]
= √(16 + 1 + 1)
= √18 ≈ 4.24
与辣香肠的距离:
√[(7-7)² + (9-6)² + (2-5)²]
= √(0 + 9 + 9)
= √18 ≈ 4.24
与四季披萨的距离:
√[(7-5)² + (9-5)² + (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
分母:√(7²+9²+2²) * √(3²+8²+1²)
= √(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 * √(7²+6²+5²) = 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 * √(5²+5²+2²) = 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
结语
这个美味的例子展示了:不同的相似度度量会导致不同的推荐结果,实际应用中需要根据业务需求选择合适的度量方式。向量数据库的价值就在于它能高效处理这类比较操作,即使面对百万级"菜单"也能快速响应。