0

私は約1500のドキュメントのコレクションを持っています。各ドキュメントを解析し、トークンを抽出しました。これらのトークンはハッシュマップに (キーとして) 保存され、コレクション内で発生する合計回数 (頻度) が値として保存されます。

逆索引を作成するには、これを拡張する必要があります。つまり、用語(キー)| 発生するドキュメントの数 -->DocNo|そのドキュメントの頻度。たとえば、

    Term       DocFreq    DocNum      TermFreq  
  data           3           1            12  
                            23            31  
                            100           17  
  customer       2          22            43  
                            19            2  

現在、私はJavaで以下を持っています、

hashmap<string,integer>  
for(each document)  
{  
    extract line  
    for(each line)  
    {  
        extract word   
        for(each word)  
        {  
            perform some operations  
            get value for word from hashmap and increment by one  
        }  
    }  
}  

このコードに基づいて構築する必要があります。逆インデックスを実装する良い方法が思いつきません。ここまでで、value を 2D 配列にすることを考えました。したがって、用語がキーになり、値 (つまり、2D 配列) に docId と termFreq が格納されます。

私の論理が正しいかどうか教えてください。

4

4 に答える 4

3

を使用してそれを行いますMap<String, TermFrequencies>。このマップは、見つかった用語ごとに TermFrequencies オブジェクトを維持します。TermFrequencies オブジェクトには次のメソッドがあります。

void addOccurrence(String documentId);
int getTotalNumberOfOccurrences();
Set<String> getDocumentIds();
int getNumberOfOccurrencesInDocument(String documentId);

内部的にを使用してMap<String, Integer>、用語が出現する各ドキュメントをドキュメント内の用語の出現回数と関連付けます。

アルゴリズムは非常に単純です。

for(each document) {  
    extract line  
    for(each line) {  
        extract word   
        for(each word) {  
            TermFrequencies termFrequencies = map.get(word);
            if (termFrequencies == null) {
                termFrequencies = new TermFrequencies(word);
            }
            termFrequencies.addOccurrence(document);
        }  
    }  
}  

このaddOccurrence()メソッドは、総発生回数のカウンターを単純にインクリメントし、internam マップに発生回数を挿入または更新します。

于 2012-10-27T16:46:53.013 に答える
2

Map<docnum, Map<term,termFreq>>aとaの2つの構造を持つのが最善だと思いますMap<term, Set<docnum>>。docFreqsset.sizeは、2番目のマップの値のように読み取ることができます。このソリューションにはカスタムクラスが含まれておらず、必要なものすべてをすばやく取得できます。

最初のマップにはすべての情報が含まれており、2番目のマップは用語による迅速な検索を可能にする派生物です。ドキュメントを処理するときに、最初のマップを塗りつぶします。後で2番目のマップを導出できますが、1回のパスで簡単に導出することもできます。

于 2012-10-27T16:45:09.787 に答える
0

私はかつてあなたが求めているものを実装しました。あなたのアプローチの問題は、それが十分に抽象的でないことです。オブジェクトを使用して、用語、ドキュメント、およびそれらの関係をモデル化する必要があります。最初の実行では、用語インデックスとドキュメント オブジェクトを作成し、用語インデックスを作成しながらドキュメント内のすべての用語を反復処理します。その後、目的の出力に簡単に変換できる表現がメモリに作成されます。オブジェクト指向言語で 2 次元配列について考えることから始めないでください。数学的な問題を解決したり、何かを最適化したりしない限り、ほとんどの場合、それは正しいアプローチではありません。

于 2012-10-27T16:48:29.727 に答える
0

これがまだホットな質問かどうかはわかりませんが、次のようにすることをお勧めします。

すべてのドキュメントを実行し、昇順で ID を付与します。ドキュメントごとに、すべての単語を実行します。

これで、文字列 (単語) を DocTermObject の配列にマップする Hashmap ができました。DocTermObject には、docId と TermFrequency が含まれています。

ドキュメント内の各単語について、作成した DocTermObjects の配列が含まれていない場合は HashMap で検索し、それ以外の場合はその最後の要素のみを調べます (これはランタイムのために重要です。考えてみてください) )。この要素に現在扱っている docId がある場合は、TermFrequency を増やします。それ以外の場合、または配列が空の場合は、実際の docId を使用して新しい DocTermObject を追加し、TermFrequency を 1 に設定します。

後でこのデータ構造を使用して、たとえばスコアを計算できます。もちろん、DoctermObjects にスコアを保存することもできます。

それが役に立ったことを願っています:)

于 2013-03-12T13:50:58.637 に答える