Поиск наилучшего косинусного сходства в наборе векторов

У меня есть 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')