3

私は、ベクトルでエンコードされた単語を使用しているプロジェクトに取り組んでおり、これは約 2000 フロートの長さです。これらを未加工のテキストで使用する場合、各単語に出くわしたときにベクトルを取得し、それを使用していくつかの計算を行う必要があります。言うまでもなく、大きなボキャブラリ (~100k ワード) の場合、これには大きなストレージ要件 (テキスト ファイルで約 8 GB) があります。

私は当初、大きなテキスト ファイルを小さなファイルに分割し、特定の単語についてそのファイルを読み取り、そのベクトルを取得するシステムを持っていました。ご想像のとおり、これは遅すぎました。

次に、すべてをRAMに読み込もうとしました(約40GBのRAMが必要です)。すべてが読み込まれると、非常に高速になると考えました。ただし、読み込みには長い時間がかかり、これを行うには十分な空き RAM がある特定のマシンのみを使用する必要があるという欠点があります。ただし、データが読み込まれると、他のアプローチよりもはるかに高速になります。

データベースがこれらのアプローチとどのように比較されるのか疑問に思っていました. 取得は RAM アプローチよりも遅くなりますが、オーバーヘッド要件はありません。また、他のアイデアは大歓迎です。私自身も他のアイデアを持っています(つまり、キャッシュ、RAMにすべてがロードされたサーバーの使用など)。データベースのベンチマークを行うかもしれませんが、ここに投稿して、他の人が何を言わなければならないかを確認したいと思いました.

ありがとう!

アップデート

タイラーの提案を使用しました。私の場合、BTree が必要だとは思いませんでした。単語とそのオフセットをハッシュしただけです。次に、単語を検索して、実行時にそのベクトルを読み取ることができました。テキストに出現する単語をキャッシュしたので、各ベクトルはせいぜい 1 回だけ読み込まれますが、これにより、不要な単語を読み込んで保存するオーバーヘッドが節約され、RAM アプローチよりも優れています。

参考までに、私は Java の RamdomAccessFile クラスを使用し、readLine()、getFilePointer()、および seek() 関数を使用しました。

このスレッドに貢献してくれたすべての人に感謝します。

更新 2

パフォーマンスをさらに改善するには、http://minddumped.blogspot.com/2009/01/buffered-javaiorandomaccessfile.html からバッファリングされた RandomAccessFile をチェックして ください。

どうやら RandomAccessFile からの readLine はバイト単位で読み取るため非常に遅いようです。これにより、いくつかの素晴らしい改善が得られました。

4

2 に答える 2

3

原則として、効率的にコーディングしたと仮定すると、カスタム コーディングされたものは汎用データベースよりもはるかに高速になるはずです。

B ツリーを使用してこの問題を解決するための特定の C ライブラリがあります。昔、「B-trieve」という有名なライブラリがあり、高速で人気がありました。このアプリケーションでは、データベースをいじるよりも B ツリーの方が高速で簡単です。

最適なパフォーマンスが必要な場合は、サフィックス ツリーと呼ばれるデータ構造を使用します。サフィックス ツリーを作成して使用するように設計されたライブラリがあります。これにより、最速の単語検索が可能になります。

いずれの場合も、データセット全体をメモリに保存する理由はなく、B ツリー (またはサフィックス ツリー) をメモリ内のデータへのオフセットと共に保存するだけです。これには、約 3 ~ 5 メガバイトのメモリが必要です。ツリーをクエリすると、オフセットが返されます。次に、ファイルを開き、オフセットを前方にシークし、ディスクからベクトルを読み取ります。

于 2013-05-26T18:47:56.890 に答える
2

単語をインデックスにマッピングするだけの単純なテキスト ベースのインデックス ファイルと、各単語の生のベクトル データを含む別のファイルを使用できます。最初は、各単語をデータファイルのインデックスにマップするハッシュマップにインデックスを読み取り、それをメモリに保持するだけです。単語のデータが必要な場合は、データ ファイルのオフセット (2000 * 32 * インデックス) を計算し、必要に応じて読み取ります。おそらく、このデータを RAM にキャッシュする必要があります (Java を使用している場合は、出発点として弱いマップを使用するだけです)。

これは基本的に独自のプリミティブ データベースを実装していますが、データベースのセットアップや展開の複雑さを回避できるため、依然として好ましい場合があります。

于 2013-05-26T19:39:32.150 に答える