Метрики близости: косинус, L2 и скалярное произведение
Какую метрику близости выбрать при создании индекса и почему это важно.
Метрика — правило, по которому база решает, какие векторы «ближе». В RAG обычно выбирают из трёх: косинус, L2 и dot product.
Три метрики
| Метрика | Что мерит | Ближе = |
| Косинус | угол (направление) | значение ближе к 1 |
| L2 (евклид) | прямое расстояние | значение ближе к 0 |
| Dot (скалярное) | проекция, учитывает и угол, и длину | больше значение |
Считаем все три на одной паре
import math
a = [1.0, 2.0, 3.0]
b = [2.0, 1.0, 3.0]
dot = sum(x * y for x, y in zip(a, b))
l2 = math.sqrt(sum((x - y) ** 2 for x, y in zip(a, b)))
cos = dot / (math.sqrt(sum(x * x for x in a)) * math.sqrt(sum(y * y for y in b)))
print(f"dot (больше = ближе): {dot:.3f}")
print(f"L2 (меньше = ближе): {l2:.3f}")
print(f"cos (к 1 = ближе): {cos:.3f}")Вывод:
dot (больше = ближе): 13.000 L2 (меньше = ближе): 1.414 cos (к 1 = ближе): 0.929
Почему dot без нормализации коварен
Скалярное произведение учитывает не только направление, но и длину векторов. На практике это значит, что длинный документ может получить высокий dot-скор просто потому, что его вектор «больше», а не потому, что он релевантнее. Тогда выдача перекосится в сторону длинных чанков. Косинус от этого защищён по построению: он делит на длины и сравнивает только направления. Поэтому, если вы не уверены, нормализованы ли ваши эмбеддинги, безопаснее брать косинус — он даёт честное сравнение по смыслу независимо от величины векторов.
Как выбрать
- Косинус — выбор по умолчанию для текстовых эмбеддингов: важен смысл (направление), а не длина.
- L2 — когда длина вектора несёт информацию или так советует автор модели.
- Dot — быстро и эквивалентно косинусу, если векторы нормализованы (длина = 1).
Важная связь: на нормализованных векторах ранжирование по косинусу, dot и L2 даёт один и тот же порядок соседей. Поэтому многие модели рекомендуют нормализовать эмбеддинги и использовать dot — это самый дешёвый вариант.
Главное правило
Используйте ту метрику, под которую обучалась модель эмбеддингов. Если в карточке модели написано «cosine similarity» — ставьте косинус в индексе. Несовпадение метрики обучения и поиска ухудшает качество без явных ошибок — коварная проблема.
Итог
- Косинус — угол, L2 — расстояние, dot — проекция (угол + длина).
- Для текста по умолчанию косинус; на нормализованных векторах берут dot.
- Метрику в индексе берите ту, под которую обучена модель.