Как эффективно вычислить сходство между документами в потоке документов

Я собираю текстовые документы (в Node.js), где один документ i представлен в виде списка слов. Каков эффективный способ вычисления сходства между этими документами, принимая во внимание, что новые документы поступают как своего рода поток документов?

В настоящее время я использую косоподобие для нормализованной частоты слов в каждом документе. Я не использую TF-IDF (частота терминов, частота инверсных документов) из-за проблем с масштабируемостью, поскольку я получаю все больше и больше документов.

Первоначально

Моя первая версия заключалась в том, чтобы начать с доступных в настоящее время документов, вычислить большую матрицу Term-Document A, а затем вычислить S = A^T x A так, чтобы S(i, j) было (после нормализации как norm(doc(i)), так и norm(doc(j))) кос-сходством между документами i и j, частоты слов которых соответственно doc(i) и doc(j).

Для новых документов

Что мне делать, когда я получу новый документ doc(k)? Что ж, мне нужно вычислить сходство этого документа со всеми предыдущими, для чего не нужно строить целую матрицу. Я могу просто взять внутреннее произведение doc(k) dot doc(j) для всех предыдущих j, и в результате получится S(k, j), и это здорово.

Проблемы

  1. Вычисление S в Node.js занимает очень много времени. На самом деле слишком долго! Поэтому я решил создать модуль C++, который делал бы все это намного быстрее. И это так! Но я не могу дождаться этого, я должен иметь возможность использовать промежуточные результаты. И то, что я имею в виду, не ждите, это и то, и другое.

    а. дождаться завершения вычислений, а также
    b. подождите, пока будет построена матрица A (она большая).

  2. При вычислении нового S(k, j) можно использовать тот факт, что в документах слов намного меньше, чем в наборе всех заданных слов (который я использую для построения всей матрицы A). Таким образом, в Node.js это выглядит быстрее, избегая использования большого количества дополнительных ресурсов для доступа к данным.

Но есть ли лучший способ сделать это?

Примечание: причина, по которой я начал вычислять S, заключается в том, что я могу легко построить A в Node.js, где у меня есть доступ ко всем данным, а затем выполнить матричное умножение в C++ и получить его обратно в Node. js, что значительно ускоряет все это. Но теперь, когда вычисление S становится невыполнимым, оно выглядит бесполезным.

Примечание 2: да, мне не нужно вычислять все S, я могу просто вычислить верхние правые элементы (или нижние левые), но это не проблема. Проблема вычисления времени не из этого порядка.


person Alexandre Kaspar    schedule 21.12.2012    source источник
comment
Вы смотрели на случайную проекцию lsh?   -  person Thomas Ahle    schedule 30.03.2015


Ответы (1)


Если вам нужно решить это сегодня, просто используйте предварительно обученные векторы слов из fasttext или word2vec.

person vumaasha    schedule 06.03.2018