У меня есть (~ миллион) векторов признаков. Есть (~ миллион) бинарных объектов, но в каждом векторе только (~ тысяча) из них будет , остальные - . Я ищу пары векторов, которые имеют как минимум (~ сто) общих признаков ( в обоих). Количество таких пар имеет величину, аналогичную (~ миллион).
Я думаю, что это можно рассматривать как поиск пар близких точек в очень многомерном пространстве. Функция расстояния может быть такой, чтобы она основывалась на том, сколько признаков имеют два общих вектора. Но это, вероятно, было бы полезно с более обычной метрикой расстояния (такой как Евклидово) также.
Какие известные алгоритмы будут полезны для решения этой проблемы? Все, что является квадратичным по или , не будет практичным.
Примером реальной постановки проблемы является рассмотрение людей, перемещающихся между несколькими местами. Если два человека были в одном месте в одно и то же время, мы говорим, что они встретились. (Количество комбинаций времени и местоположения, в которых присутствует как минимум 1 человек, равно ) Мы ищем друзей: людей, которые встречались как минимум раз.
источник
Ответы:
Похоже, что подход, который вы ищете, представляет собой комбинацию сигнатур minhash и локального хеширования (LSH); (свободно доступный) pdf Mining Massive Datasets описывает этот подход (и другие меры сходства) в деталях в главе 3, но кратко:
Minhash подпись является сгущенное представление исходной матрицы , которая строится с применением некоторого числа п хеш - функций к функциям, уменьшая тем самым количество функций в наблюдении. Это уменьшает размер ваших данных, однако вы, вероятно, заметите, что это все еще оставляет вас с проблемой .O ( N2)
Чтобы решить эту проблему, MMDS рекомендует, чтобы, если все, что вы хотите найти, это пары выше определенного порога сходства (что, по-видимому, применимо в вашем случае), то вы можете сосредоточиться только на тех парах, которые, скорее всего, будут похожи - этот подход называется Хеширование с учетом локальных особенностей, и в разделе 3.4 они рассматривают пример того, как объединить подход с использованием сигнатуры minhash и LSH.
В дополнение к тексту, есть также лекции, доступные на курсе Coursera с тем же названием.
источник
Это просто внутреннее произведение векторов двоичных объектов. Когда внутреннее произведение больше, чем , пара будет иметь как минимум L общих элементов. Это должно быть относительно быстрое вычисление - по крайней мере, быстрее, чем евклидово расстояние, которое было бы расточительным и медленным для этих данных. Поскольку вы оговариваете, что ищете пары, это по сути означает, что вы должны выполнить вычисления для сравнения каждого вектора.L - 1 L ( N2)
Поиск точек, которые находятся близко друг к другу, действительно является проблемой кластеризации. Но первый шаг алгоритмов кластеризации, с которыми я знаком, - это вычисление парных расстояний или сходств. Я уверен, что кто-то разработал более эффективные альтернативы. Пункт о терминологии: наличие как минимум общих соседей выражается как сходство , а не расстояние! Внутренние продукты в этом случае являются ненормализованным косинусным сходством.L
Вы можете сделать это более удобным, выполнив вычисление внутреннего произведения только тогда, когда сумма вектора признаков (которая в данном случае совпадает с нормой) для наблюдения больше , поскольку для этого вектора двоичных объектов это невозможно иметь внутренний продукт с другим бинарным вектором признаков , который будет удовлетворять мой критерий , когда эта сумма меньше , чем . Очевидно, что вычисление этих сумм - только сложность, поэтому я - дешевый способ снизить величину шага внутреннего продукта.L O ( N )L - 1 L O ( N)
Но классический способ уменьшить масштабы этой проблемы - выполнить дополнительную предварительную фильтрацию. Вас особенно интересует, когда одна, несколько необычная функция принимает значение 1? Если это так, выполняйте вычисления только для этих векторов признаков.
Или, возможно, вы могли бы извлечь выгоду из переосмысления вашей проблемы. Например, известно, что выборка имеет хорошие свойства; Выводная статистика развивается по этой идее достаточно глубоко. Поэтому, возможно, невозможно проанализировать весь набор данных, но вполне возможно исследовать небольшую выборку. Я не знаю, на какой вопрос вы пытаетесь ответить, но если вы тщательно спланируете свой эксперимент, вам может не хватить только нескольких тысяч наблюдений, при этом данных для проверки осталось более чем достаточно.
После некоторой дополнительной мысли, у меня есть сильное подозрение , что данные вы работаете, какое - то граф . Весьма вероятно, что состоит из нескольких соединенных компонентов, и в этом случае вы можете разложить на набор графиков с приятным побочным эффектом уменьшения размерности данных. Даже если на графике только два соединенных компонента примерно одинакового размера, это означает, что ваши парные сравнения примерно равны общей стоимости!G G O ( N 2 ) 1г г г O ( N2) 14
Если график симметричен, могут быть полезны следующие наблюдения:
Если у вас есть двудольный граф, связывающий людей с поведением, вы можете думать об этом как о сети присоединения , где люди представляют собой строки, а поведения - как столбцы. Если вы хотите , чтобы соединить людей с людьми с помощью поведения , который они имеют в общем, вы можете вычислить . - это общее поведение людей. Очевидно, множество вершин, где отвечает на ваш вопрос.В B BT= A Aя ж Aя ж≥ L
источник
При поиске людей, встречающихся в пространственно-временных блоках:Ns p a c e Nт я м е
O ( N2)
разделите пространство на блоки (городские кварталы, квадратные километры и т. Д.) И время на блоки . Есть большая вероятность, что если люди встретятся, они встретятся в одном квартале. Так что запускайте NN в каждом блоке. Время выполнения и частота ошибок, конечно, будут зависеть от размеров и форм блоков (также от того, что вы можете распараллелить / MapReduce), но у вас есть параметры, с которыми можно поиграть - инженерный, а не широко открытый .N t i m e O ( N 2 )
См. Также:
поиск ближайших соседей для очень больших размерных данных на datascience.stackexchange
pairwise.py :
источник
Для каждой функции создайте словарь, содержащий индексы, разделяющие эту функцию. Надеемся, что это число не будет слишком большим (если у вас есть функция, которая используется всеми индексами, этот подход разрушен, вы можете перестать читать здесь).
Я применил этот метод для реализации KNN на большом текстовом наборе (поезд: 2 000 000 строк, тест 35 000 строк, количество объектов: 10 000, среднее количество объектов на элемент: 20), который выполнялся примерно через час. ,
источник
Л. Эроц, М. Штайнбах и В. Кумар. «Новый общий алгоритм кластеризации ближайшего соседа и его приложения». Труды 1-го семинара по кластеризации высокомерных данных и их приложений, 2002.
источник
Учитывая, что ваш k равен 100, а ваш n равен 1e6, это должно дать вам ~ 1e4x ускорение по сравнению с классическим FFT.
Если вам нужна еще 20-кратная скорость, и вы рискуете, то вместо того, чтобы сворачивать все строки в домене и искать пик, вы можете загрузить подмножество строк.
Вы также можете предварительно отфильтровать столбцы, удалив столбцы, суммы которых меньше 50, или некоторый другой порог, который составляет порядка половины числа строк, которые вы хотите сопоставить. По крайней мере, вы должны удалить столбцы всех нулей и всех 1 как неинформативные. То же самое со строками, которые полностью пусты или достаточно пусты, или строками, которые настолько полны, что они не имеют значения.
Дела: я должен привести пример с использованием синтетических данных и сравнить некоторые методы.
источник
Я только что натолкнулся на статью, которая имеет прямое отношение к делу.
На самом деле это реализовано в https://github.com/soundcloud/cosine-lsh-join-spark, где я его и нашел.
Он основан на локальном хешировании (уже упоминалось в других ответах). После того, как он уменьшил векторы объектов до низкоразмерного пространства, он использует быстрое соединение Хэмминга на расстоянии, чтобы найти ближайших соседей.
источник