i
1 つのドキュメントが単語のリストとして表されるテキスト ドキュメントを (Node.js で) 収集します。新しいドキュメントがドキュメントの一種のストリームとして来ることを考慮して、これらのドキュメント間の類似性を計算する効率的な方法は何ですか?
私は現在、各ドキュメント内の単語の正規化頻度に cos-similarity を使用しています。ますます多くのドキュメントを取得するため、スケーラビリティの問題があるため、TF-IDF (用語頻度、逆ドキュメント頻度) は使用しません。
最初は
私の最初のバージョンは、現在利用可能なドキュメントから始めて、大きな Term-Document 行列A
を計算し、 ( と の両方で正規化した後) ドキュメント間の cos-similarityとその単語頻度がそれぞれとであるように計算する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++ モジュールを作成することにしました。そして、そうです!しかし、私はそれを待つことができません。中間結果を使用できるはずです。そして、「それを待たない」というのは、a. 計算が完了するのを待ちますが、
b. マトリックスA
が構築されるのを待ちます (これは大きなものです)。コンピューティング new
S(k, j)
は、ドキュメントが与えられたすべての単語のセットよりもはるかに少ない単語を持っているという事実を利用できます (これを使用して、マトリックス全体を構築しますA
)。したがって、Node.js で実行する方が高速に見え、データにアクセスするために多くの余分なリソースが必要になるのを回避できます。
しかし、それを行うより良い方法はありますか?
注: 私がコンピューティングを始めた理由は、すべてのデータにアクセスできる Node.js でS
簡単に構築できA
、C++ で行列乗算を実行して Node.js に戻すことができるためです。これにより、全体が大幅に高速化されます。 . しかし、コンピューティングS
が実用的でなくなった今、それは役に立たないように見えます。
注 2 : ええ、全体を計算する必要はありません。S
右上の要素 (または左下の要素) を計算するだけで済みますが、それは問題ではありません。時間計算の問題はその順序ではありません。