Поиск наилучшего косинусного сходства в наборе векторов
У меня есть N векторов, каждый с m элементами (вещественное число). Я хочу найти пару, где косинусное сходство является максимальным среди всех пар.
простое решение потребует O (n2m) время.
есть ли лучшее решение?
обновление
Косинус сходства / расстояние и треугольник уравнение вдохновляет меня, что я мог бы заменить "косинусное сходство" на "длину аккорда", которая теряет точность, но увеличивает скорость много. ( существует много существующих решений, решающих ближайшего соседа в метрическом пространстве, например Энн )
2 ответов
Косинус сходство sim(a,b)
is связанные с евклидовым расстоянием |a - b|
by
|a - b|² = 2(1 - sim(a,b))
для единичных векторов a
и b
.
это означает, что косинусное сходство является наибольшим, когда евклидово расстояние наименьшее после нормализации по норме L2, и проблема сводится к ближайшая пара точек проблема, который может быть решен за O (N lg n) время.
вы можете проверить с помощью проекта simbase https://github.com/guokr/simbase, это база данных NoSQL векторного подобия.
использование Simbase ниже понятий:
- векторный набор: набор векторов
- Базис: базис для векторов, векторы в одном векторном наборе имеют одинаковый базис
- рекомендация: однонаправленная двоичная связь между двумя векторными наборами, имеющими одинаковый базис
вы можете использовать redis-cli непосредственно для задач администрирования, или вы можете использовать привязки клиента redis на другом языке непосредственно в программировании. Вот пример
import redis
dest = redis.Redis(host='localhost', port=7654)
schema = ['a', 'b', 'c']
dest.execute_command('bmk', 'ba', *schema)
dest.execute_command('vmk', 'ba', 'va')
dest.execute_command('rmk', 'va', 'va', 'cosinesq')