関口宏司のLuceneブログ

OSS検索ライブラリのLuceneおよびそのサブプロジェクト(Solr/Tika/Mahoutなど)について
<< Solr新機能:ツッコミ検索とは? | main | CaboChaと京都コーパスで交差検定 >>
Lucene/Solr インデックスの中を覗いてジップの法則を確認する
単語の出現頻度の順位nと出現確率P(n)の間には、ジップの法則(Zipf's Law)と呼ばれる次の経験則が成り立つ:

P(n) = c / n


ジップは英語の場合、c=0.1であると推定している。

単語の出現頻度などはLucene/Solrのインデックスを調べれば簡単にわかるので、早速手元のインデックス(歴代の内閣総理大臣の所信表明演説が登録されている)でやってみたところ、下図のように見事に直線上に並んだ。ただし、c=0.162とした:

ZipfsLaw

プログラムは以下の通り。試すときは、INDEXとFのString定数に、それぞれインデックスの絶対パスと、調べる対象のフィールド名を指定する。
public final class TestZipfsLaw {
  
  final static String INDEX = "/path/to/index";
  final static String F = "fieldNameToBeChecked";

  public static void main(String[] args) throws Exception {
    Directory dir = getDir();
    List tfList = getTermFreqList(dir);
    dir.close();
    
    Collections.sort(tfList, new Comparator<TermFreq>() {
      public int compare(TermFreq o1, TermFreq o2) {
        return o1.freq == o2.freq ? 0
            : o1.freq < o2.freq ? 1 : -1;
      }
    }
    );
    
    int currentFreq = Integer.MAX_VALUE;
    int ranking = 0;
    for(TermFreq tf : tfList){
      ranking++;
      if(tf.freq < currentFreq){
        //System.out.println( ranking + ", term = " + tf.term + ", totalFreq = " + tf.freq );
        System.out.println( ranking + ", " + tf.freq );
        currentFreq = tf.freq;
      }
      //System.out.println( "term = " + tf.term + ", totalFreq = " + tf.freq );
    }
  }
  
  static Directory getDir() throws IOException {
    File dirFile = new File(INDEX);
    Directory dir = FSDirectory.open(dirFile);
    return dir;
  }

  static List getTermFreqList(Directory dir) throws IOException {
    IndexReader reader = IndexReader.open(dir);
    List results = new ArrayList();
    TermEnum te = reader.terms(new Term(F,""));
    while(true){
      Term t = te.term();
      int totalFreq = 0;
      if(t == null || !t.field().equals(F))
        break;
      TermPositions tp = reader.termPositions(t);
      while(tp.next()){
        totalFreq += tp.freq();
      }
      //System.out.println( "term = " + t.text() + ", totalFreq = " + totalFreq );
      results.add(new TermFreq(t.text(), totalFreq));
      tp.close();
      if(!te.next()) break;
    }
    te.close();
    reader.close();
    
    return results;
  }

  static class TermFreq {
    final String term;
    final int freq;
    public TermFreq(String term, int freq){
      this.term = term;
      this.freq = freq;
    }
  }
}


実行すると、標準出力に次のように2列の数値が表示されるので、これをExcelに貼り付けグラフを表示すると、上手のようになる(はず)。2列の数値の1列目は単語の出現頻度の順位で、2列目は出現回数である。
1, 4483
2, 2415
3, 1239
4, 1228
5, 1091
:    :




元ヤフー社員も大満足のロンウイットのSolrトレーニング・・・受講者インタビュー記事
Solr 3.6 7月 トレーニング受講者募集中

| 関口宏司 | NLP | 00:27 | comments(0) | trackbacks(0) |









http://lucene.jugem.jp/trackback/467
+ Solrによるブログ内検索
+ PROFILE
  12345
6789101112
13141516171819
20212223242526
2728293031  
<< August 2017 >>
+ LINKS
検索エンジン製品 - 比較のポイント
商用検索エンジンを購入した企業担当者は読まないでください。ショックを受けますから・・・
>>製品比較 10のポイント
+ Lucene&Solrデモ
+ ThinkIT記事
+ RECOMMEND
Apache Solr入門 ―オープンソース全文検索エンジン
Apache Solr入門 ―オープンソース全文検索エンジン (JUGEMレビュー »)
関口 宏司,三部 靖夫,武田 光平,中野 猛,大谷 純
+ RECOMMEND
Lucene in Action
Lucene in Action (JUGEMレビュー »)
Erik Hatcher,Otis Gospodnetic,Mike McCandless
FastVectorHighlighterについて解説記事を寄稿しました。
+ RECOMMEND
+ SELECTED ENTRIES
+ RECENT COMMENTS
+ RECENT TRACKBACK
+ CATEGORIES
+ ARCHIVES
+ MOBILE
qrcode
+ SPONSORED LINKS