Технологии

Что такое косинусная близость

Мера схожести двух векторов через угол между ними. Главное ограничение для памяти: высокая близость означает «та же тема», а вовсе не «ответ на ваш вопрос».

Косинусная близость — косинус угла между двумя векторами:

cos(a, b) = (a · b) / (|a| × |b|)

В числителе скалярное произведение, в знаменателе — произведение длин. Значение лежит от −1 до 1: единица означает сонаправленность, ноль — перпендикулярность, минус единица — противоположность. Для эмбеддингов текста на практике почти всё попадает в интервал от 0 до 1.

Ключевая особенность: длина векторов не учитывается, важно только направление. Поэтому длинный документ и короткая заметка об одном и том же оказываются близки, хотя их векторы разной величины.

Практическая деталь: если векторы нормированы к единичной длине, знаменатель равен единице, и косинус превращается в скалярное произведение. Поэтому библиотеки нормируют векторы один раз при записи.

#Что означают конкретные числа

Разберём три пары запроса и фрагмента из архива:

Пара Отношение Ожидаемая близость
«когда встреча с Ивановым» — «встреча с Ивановым перенесена на среду» ответ на вопрос высокая
«когда встреча с Ивановым» — «надо бы назначить встречу с Ивановым» та же тема, ответа нет тоже высокая
«когда встреча с Ивановым» — «купить корм коту» ничего общего низкая

Первые две строки — суть проблемы. Обе фразы про встречу с Ивановым, обе получат высокую оценку, и векторный поиск их не различит. Отделить «ответ» от «та же тема» косинус не умеет в принципе.

Отсюда стандартное решение: векторный поиск отбирает кандидатов широко, а дальше их пересортировывает отдельная модель, которая сравнивает запрос и фрагмент напрямую — разбор в тексте про rerank-модели.

#Где путают

Заблуждение первое: есть универсальный порог релевантности. Нет. У каждой модели эмбеддингов своё распределение оценок: у одной несвязанные тексты дают 0,1, у другой — 0,7, потому что все её векторы лежат в узком конусе. Порог калибруется на своих данных: возьмите два десятка заведомо релевантных и заведомо нерелевантных пар и посмотрите, где проходит граница именно у вас.

Заблуждение второе: близость показывает правильность. Она показывает похожесть на запрос. Фрагмент с устаревшей информацией близок к запросу ровно так же, как свежий — различать их должна не метрика, а данные о времени и происхождении.

Заблуждение третье: отрицание учитывается. «Договор подписан» и «договор не подписан» отличаются одним словом и оказываются очень близки. Это известное слабое место эмбеддингов и одна из причин, почему чистый векторный поиск нельзя использовать для фактических вопросов без проверки текста — сравнение подходов в разборе семантического поиска против ключевых слов.

Заблуждение четвёртое: косинус и евклидово расстояние взаимозаменяемы. Для нормированных векторов они дают одинаковый порядок результатов, для ненормированных — нет. Ошибка проявляется не сбоем, а тихо съехавшей выдачей.

#Частые вопросы

#Почему близость двух совершенно разных текстов не равна нулю?

Потому что векторы одной модели занимают не всё пространство, а его часть. Смещение общее для всех текстов, и оно поднимает базовый уровень. Ориентироваться нужно на разницу между парами, а не на абсолютное значение.

#Можно ли сравнивать векторы, полученные разными моделями?

Нельзя. У каждой модели своя система координат; числа из разных моделей несопоставимы, даже если совпала размерность. При смене эмбеддера индекс строится заново, целиком.

#Как ускорить сравнение на большом архиве?

Нормировать векторы при записи и заменить косинус скалярным произведением, а при действительно больших объёмах — перейти на приближённый индекс; когда это оправдано, разобрано в справке про KNN и приближённый поиск соседей.

#Что делать, если поиск находит «примерно про то»?

Это штатное поведение метрики, а не поломка. Лечится вторым этапом: переранжированием кандидатов или комбинацией с текстовым поиском. Что вообще представляют собой сравниваемые векторы — в тексте про эмбеддинги простыми словами.

Остальные термины — в глоссарии терминов ИИ.

Хотите ИИ, который помнит вас?

Persona держит контекст между чатами и работает на вашем железе — если развернуть её у себя и подключить локальную модель.

Создать аккаунт