Индексация для поиска сходства

У меня есть около 100 миллионов числовых векторов (отпечатки Minhash), каждый вектор содержит 100 целых чисел от 0 до 65536. , и я пытаюсь выполнить быстрый поиск сходства в этой базе данных отпечатков пальцев, используя сходство Jaccard, то есть, учитывая вектор запроса (например, [1,0,30, 9, 42,...]), найдите отношение пересечения/объединения этого набора запросов к базе данных из 100 миллионов наборов.

Требование состоит в том, чтобы вернуть k «ближайших соседей» вектора запроса за ‹1 секунду (не включая время индексирования/ввода файла) на ноутбуке. Таким образом, очевидно, что требуется какая-то индексация, и вопрос заключается в том, какой подход будет наиболее эффективным.

примечания: я думал об использовании SimHash, но в этом случае на самом деле нужно знать размер пересечения наборов для идентификации сдерживание, а не чистое сходство/подобие, но Симхэш потерял бы эту информацию.

Я пробовал использовать простой метод хеширования с учетом местоположения, как описано в главе 3 Джеффри Уллмана, разделив каждый вектор на 20 "полос" или фрагментов длиной 5, преобразовав эти фрагменты в строки (например, [1, 2, 45, 2, 3] -> "124523") и используя эти строки в качестве ключей в хэш-таблице, где каждый ключ содержит "соседей-кандидатов". Но проблема в том, что это создает слишком много кандидатов для некоторых из этих фрагментов, и изменение количества полос не помогает.


person alex    schedule 30.05.2013    source источник


Ответы (4)


Один из способов сделать это заключается в следующем:

(1) Упорядочить векторы в дерево (дерево счисления).

(2) Запросить дерево с нечеткими критериями, другими словами, совпадение, если разница в значениях в каждом узле дерева находится в пределах порога

(3) Из (2) сгенерируйте поддерево, содержащее все совпадающие векторы

(4) Теперь повторите процесс (2) для поддерева с меньшим порогом

Продолжайте, пока в поддереве не будет K элементов. Если в K слишком мало элементов, возьмите предыдущее дерево и вычислите расстояние Джакара для каждого члена поддерева и отсортируйте, чтобы исключить наихудшие совпадения, пока у вас не останется только K элементов.

person Tyler Durden    schedule 30.05.2013

Я могу немного опоздать, но я бы предложил индексацию IVFADC от Jegou et al. : квантизация продукта для поиска ближайшего соседа

Он работает для мер подобия L2 Distance/dot product и немного сложен, но особенно эффективен с точки зрения времени и памяти.

Он также реализован в библиотеке FAISS для поиска по сходству, так что вы тоже можете на это взглянуть.

person fzk    schedule 19.05.2017

Отвечая на мой собственный вопрос спустя 6 лет, существует эталон для приблизительного поиска ближайшего соседа со многими алгоритмами для решения этой проблемы: https://github.com/erikbern/ann-benchmarks, текущий победитель — «Иерархические навигационные графики малого мира»: https://github.com/nmslib/hnswlib

person alex    schedule 14.11.2019
comment
ann-benchmarks.com — более прямая ссылка. Обратите внимание, что они не проверяют бинарный поиск по сходству (например, minhash); и что у графиков маленького мира есть свои проблемы (для построения требуется квадратичное время; не работайте с жесткими наборами данных) - person Thomas Ahle; 15.11.2019
comment
спасибо, под бинарным поиском подобия, я думаю, вы имеете в виду поиск подобия с помощью жаккардового набора коэффициента сходства, как в минхэше (в отличие от евклидова расстояния, косинуса или метрики расстояния Хэмминга) - person alex; 15.11.2019
comment
Жаккара, а также другие меры подобия двоичных данных: arxiv.org/pdf/1612.07710 - person Thomas Ahle; 16.11.2019

Вы можете использовать готовые сервисы поиска по сходству, такие как AWS-ES или Pinecone.io.

person Ron    schedule 31.05.2021