code up

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Lucene 4.4.0でunidic

調べてもほとんど出てこないので需要があまりないんだろうけど、Lucene 4.4.0でデフォルトの辞書(IPAdic)をUniDic 2.1.2に変えてみた。

準備

  1. SVNクライアントでLuceneのlucene_solr_4_4ブランチをチェックアウト。

  2. lucene_solr_4_4\lucene\analysis\kuromoji\src\tools\javaにあるorg以下をEclipseの自分のプロジェクトに投入。

  3. 自分のプロジェクトではIvyを使って、Lucene関連のライブラリはダウンロード済み。

    <dependency org="org.apache.lucene" name="lucene-core" rev="${org.apache.lucene.lucene}" transitive="false" />
    <dependency org="org.apache.lucene" name="lucene-analyzers-common" rev="${org.apache.lucene.lucene}" transitive="false" />
    <dependency org="org.apache.lucene" name="lucene-analyzers-kuromoji" rev="${org.apache.lucene.lucene}" transitive="false" />
  4. 足りないライブラリがあれば追加、今回の環境ではicu4jが足りなかったので追加。

    <dependency org="com.ibm.icu" name="icu4j" rev="${com.ibm.icu.icu4j}" transitive="false" conf="provided->default" />
  5. unidic-mecab-2.1.2_src.zipをダウンロードして解凍。

コードの修正

そのままではArrayIndexOfBoundsExceptionまたはAssetionErrorが出るので、微修正。

UniDic形式のマッピングも正しくないようなので、そこも修正。

Index: lucene/analysis/kuromoji/src/tools/java/org/apache/lucene/analysis/ja/util/BinaryDictionaryWriter.java
===================================================================
--- lucene/analysis/kuromoji/src/tools/java/org/apache/lucene/analysis/ja/util/BinaryDictionaryWriter.java	(???r?W???? 1513057)
+++ lucene/analysis/kuromoji/src/tools/java/org/apache/lucene/analysis/ja/util/BinaryDictionaryWriter.java	(?・ニ?R?s?[)
@@ -111,7 +111,7 @@
     }
 
     assert leftId == rightId;
-    assert leftId < 4096; // there are still unused bits
+    assert leftId < 8192; // there are still unused bits
     // add pos mapping
     int toFill = 1+leftId - posDict.size();
     for (int i = 0; i < toFill; i++) {
Index: lucene/analysis/kuromoji/src/tools/java/org/apache/lucene/analysis/ja/util/TokenInfoDictionaryBuilder.java
===================================================================
--- lucene/analysis/kuromoji/src/tools/java/org/apache/lucene/analysis/ja/util/TokenInfoDictionaryBuilder.java	(???r?W???? 1513057)
+++ lucene/analysis/kuromoji/src/tools/java/org/apache/lucene/analysis/ja/util/TokenInfoDictionaryBuilder.java	(?・ニ?R?s?[)
@@ -211,7 +211,7 @@
       features2[7] = features[7];
       features2[8] = features[8];
       features2[9] = features[9];
-      features2[10] = features[11];
+      features2[10] = features[14];
       
       // If the surface reading is non-existent, use surface form for reading and pronunciation.
       // This happens with punctuation in UniDic and there are possibly other cases as well
Index: lucene/analysis/kuromoji/src/tools/java/org/apache/lucene/analysis/ja/util/UnknownDictionaryBuilder.java
===================================================================
--- lucene/analysis/kuromoji/src/tools/java/org/apache/lucene/analysis/ja/util/UnknownDictionaryBuilder.java	(???r?W???? 1513057)
+++ lucene/analysis/kuromoji/src/tools/java/org/apache/lucene/analysis/ja/util/UnknownDictionaryBuilder.java	(?・ニ?R?s?[)
@@ -33,7 +33,7 @@
 import org.apache.lucene.analysis.ja.dict.CharacterDefinition;
 
 public class UnknownDictionaryBuilder {
-  private static final String NGRAM_DICTIONARY_ENTRY = "NGRAM,5,5,-32768,記号,一般,*,*,*,*,*,*,*";
+  private static final String NGRAM_DICTIONARY_ENTRY = "NGRAM,5,5,-32768,記号,一般,*,*,*,*,*,*,*,*";
   
   private String encoding = "euc-jp";
   
@@ -71,7 +71,7 @@
     while ((line = lineReader.readLine()) != null) {
       // note: unk.def only has 10 fields, it simplifies the writer to just append empty reading and pronunciation,
       // even though the unknown dictionary returns hardcoded null here.
-      final String[] parsed = CSVUtil.parse(line + ",*,*"); // Probably we don't need to validate entry
+      final String[] parsed = CSVUtil.parse(line + ",*,*,*"); // Probably we don't need to validate entry
       lines.add(parsed);
     }

辞書作成

Eclipse上で実行する場合はRun Configurationsなどから実行プログラムを指定する。

Mainクラスはorg.apache.lucene.analysis.ja.util.DictionaryBuilder

Program argumentsに以下のいずれかを指定。

IPAdic(デフォルトと同じ辞書)
ipadic [解凍したフォルダ]\mecab-ipadic-2.7.0-20070801 [どこか適当な場所]\src\main\resources euc-jp false
NAIST Japanese Dictionary (naist-jdic)(IPAdicの後継らしい)
ipadic [解凍したフォルダ]\\mecab-naist-jdic-0.6.3b-20111013 [どこか適当な場所]\src\main\resources euc-jp false
UniDic 2.1.2(今回目的の辞書)
unidic [解凍したフォルダ]\\unidic-mecab-2.1.2_src [どこか適当な場所]\src\main\resources UTF-8 false
UniDic 1.3.12(UniDicの古いバージョン)
unidic [解凍したフォルダ]\\unidic-mecab1312src [どこか適当な場所]\src\main\resources UTF-8 false

VM argumentsにassertを有効にするため、-eaを追加。あとはRun。

上記例であれば [どこか適当な場所]\src\main\resourcesにorg\apache\lucene\analysis\ja\dict\*.datファイルが出来上がるので、orgの場所を起点としてWEB-INF/classesまたはクラスパスの前の方に含まれるようにする。

Lucene本体(Kuromoji部分)の修正

上記だけでは今度は別のArrayIndexOfBoundsExceptionが出るので本体も修正する。サブクラスなどでの対応は難しそうだったのでチェックアウトしたソースコードをそのままEclipseに投入して修正。

Index: lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/dict/BinaryDictionary.java
===================================================================
--- lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/dict/BinaryDictionary.java	(???r?W???? 1513057)
+++ lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/dict/BinaryDictionary.java	(?・ニ?R?s?[)
@@ -152,12 +152,14 @@
   
   @Override
   public int getLeftId(int wordId) {
-    return buffer.getShort(wordId) >>> 3;
+    // return buffer.getShort(wordId) >>> 3;
+    return (buffer.getShort(wordId) & 0xffff) >>> 3;
   }
   
   @Override
   public int getRightId(int wordId) {
-    return buffer.getShort(wordId) >>> 3;
+    // return buffer.getShort(wordId) >>> 3;
+    return (buffer.getShort(wordId) & 0xffff) >>> 3;
   }
   
   @Override

コンパイルされたクラスを、上と同様にorgの場所を起点としてWEB-INF/classesまたはクラスパスの前の方に含まれるようにする。

完成。

Apache Solr入門 ―オープンソース全文検索エンジン
関口 宏司 三部 靖夫 武田 光平 中野 猛 大谷 純
技術評論社
売り上げランキング: 45,025

関連記事
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。