Я собираю текстовые документы (в 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)
, и это здорово.
Проблемы
Вычисление
S
в Node.js занимает очень много времени. На самом деле слишком долго! Поэтому я решил создать модуль C++, который делал бы все это намного быстрее. И это так! Но я не могу дождаться этого, я должен иметь возможность использовать промежуточные результаты. И то, что я имею в виду, не ждите, это и то, и другое.а. дождаться завершения вычислений, а также
b. подождите, пока будет построена матрицаA
(она большая).При вычислении нового
S(k, j)
можно использовать тот факт, что в документах слов намного меньше, чем в наборе всех заданных слов (который я использую для построения всей матрицыA
). Таким образом, в Node.js это выглядит быстрее, избегая использования большого количества дополнительных ресурсов для доступа к данным.
Но есть ли лучший способ сделать это?
Примечание: причина, по которой я начал вычислять S
, заключается в том, что я могу легко построить A
в Node.js, где у меня есть доступ ко всем данным, а затем выполнить матричное умножение в C++ и получить его обратно в Node. js, что значительно ускоряет все это. Но теперь, когда вычисление S
становится невыполнимым, оно выглядит бесполезным.
Примечание 2: да, мне не нужно вычислять все S
, я могу просто вычислить верхние правые элементы (или нижние левые), но это не проблема. Проблема вычисления времени не из этого порядка.