Luceneに同梱されている形態素解析のKuromojiですが、以下の3種類の辞書を取ることができます。
IPA辞書はこちら。
http://mecab.googlecode.com/files/mecab-ipadic-2.7.0-20070801.tar.gz
NAIST辞書はこちら。
http://sourceforge.jp/projects/naist-jdic/
UniDicはこちら。
http://sourceforge.jp/projects/unidic/
で、今回、全パターンを試してみようと思ったのですが、UniDicは使えませんでした。辞書のビルドに失敗します。
ライセンス上の理由で、現在はIPA形式の辞書のみの対応だとか。
Japanese Tokenizer (Kuromoji) cannot build UniDic dictionary
https://issues.apache.org/jira/browse/LUCENE-4056
まあ、今回そこまで頑張る気はないので、UniDicはとりあえずいいかな…。
で、辞書を変えるということはLucene Kuromoji自体をビルドすることになります。
というわけで、まずはLucene 4.5.1のタグをエクスポート。
$ svn export http://svn.apache.org/repos/asf/lucene/dev/tags/lucene_solr_4_5_1/
ちょっと時間がかかりますが、しばし待ちましょう。
なお、この後のビルドにはAntとIvyが必要です。Ivyは「ant ivy-bootstrap」で入るのかもしれませんが、確認する前にAntとIvy合わせちゃいました。
エクスポートできたら、とりあえずLuceneをビルド。Solrはビルドしなくていいですからね。
$ cd lucene_solr_4_5_1/lucene/
$ ant compile
久々にantコマンド実行しましたね〜。依存ライブラリは、Ivyがダウンロードしてきてくれます。
antよろしく、以下のようなメッセージが出ればビルドは成功です。
compile-core: BUILD SUCCESSFUL Total time: 1 minute 10 seconds
IPA辞書を使ってビルド
続いて、Kuromojiをビルドしましょう。まずは、普通にIPA辞書を使ってビルド。
$ cd analysis/kuromoji/
$ ant regenerate
この手順では、辞書のみのビルドになります。辞書自体は、Ivyが取得してきてくれます。
途中、こんなのが出たり
[ivy:retrieve] :: resolution report :: resolve 85ms :: artifacts dl 1ms --------------------------------------------------------------------- | | modules || artifacts | | conf | number| search|dwnlded|evicted|| number|dwnlded| --------------------------------------------------------------------- | ipadic | 1 | 0 | 0 | 0 || 1 | 0 | --------------------------------------------------------------------- [ivy:retrieve] :: retrieving :: org.apache.lucene#analyzers-kuromoji
こういう表示が出ます。
[java] dictionary format: IPADIC [java] input directory: /xxxxx/lucene_solr_4_5_1/lucene/build/analysis/kuromoji/mecab-ipadic-2.7.0-20070801 [java] output directory: /xxxxx/lucene_solr_4_5_1/lucene/analysis/kuromoji/src/resources [java] input encoding: euc-jp [java] normalize entries: false [java] [java] building tokeninfo dict... [java] parse... [java] sort... [java] encode... [java] 53645 nodes, 253185 arcs, 1716191 bytes... done [java] done [java] building unknown word dict...done [java] building connection costs...done
もちろん、こういう表示が出たらビルド完了です。
BUILD SUCCESSFUL Total time: 27 seconds
この後、IPA辞書を使ってKuromojiをビルドします。
$ ant jar-core
こんな感じで、JARファイルができあがります。
jar-core: [jar] Building jar: /xxxxx/lucene_solr_4_5_1/lucene/build/analysis/kuromoji/lucene-analyzers-kuromoji-4.5.1-SNAPSHOT.jar BUILD SUCCESSFUL Total time: 6 seconds
このJARファイルを、どこかに取っておきましょう。というか、これってデフォルトのKuromojiなので、別になくてもいいんですけどね…。
自分は、こんな名前で保存しておきました。
lucene-analyzers-kuromoji-4.5.1-mecab-ipadic.jar
NAIST辞書を使ってビルド
続いて、NAIST辞書を使うようにします。
最初に、前回のビルド結果を削除。
$ ant clean Buildfile: /xxxxx/lucene_solr_4_5_1/lucene/analysis/kuromoji/build.xml [echo] Building analyzers-kuromoji... clean: [delete] Deleting directory /xxxxx/lucene_solr_4_5_1/lucene/build/analysis/kuromoji BUILD SUCCESSFUL Total time: 1 second
続いて、Kuromojiのbuild.xmlを修正します。この部分を
<!-- default configuration: uses mecab-ipadic --> <property name="ipadic.type" value="ipadic"/> <property name="ipadic.version" value="mecab-ipadic-2.7.0-20070801" /> <!-- alternative configuration: uses mecab-naist-jdic <property name="ipadic.type" value="naist"/> <property name="ipadic.version" value="mecab-naist-jdic-0.6.3b-20111013" /> -->
こうなるように修正します。
<!-- default configuration: uses mecab-ipadic --> <!-- <property name="ipadic.type" value="ipadic"/> <property name="ipadic.version" value="mecab-ipadic-2.7.0-20070801" /> --> <!-- alternative configuration: uses mecab-naist-jdic --> <property name="ipadic.type" value="naist"/> <property name="ipadic.version" value="mecab-naist-jdic-0.6.3b-20111013" />
要は、コメントアウトを入れ替えただけですね。
では、先ほどと同じ手順を実施。
$ ant regenerate
途中表示。こちらも、辞書はIvyが取得してきてくれます。
[ivy:retrieve] :: resolution report :: resolve 105ms :: artifacts dl 9ms --------------------------------------------------------------------- | | modules || artifacts | | conf | number| search|dwnlded|evicted|| number|dwnlded| --------------------------------------------------------------------- | naist | 1 | 0 | 0 | 0 || 1 | 0 | --------------------------------------------------------------------- [ivy:retrieve] :: retrieving :: org.apache.lucene#analyzers-kuromoji
同じく。
[java] dictionary format: IPADIC [java] input directory: /xxxxx/lucene_solr_4_5_1/lucene/build/analysis/kuromoji/mecab-naist-jdic-0.6.3b-20111013 [java] output directory: /xxxxx/lucene_solr_4_5_1/lucene/analysis/kuromoji/src/resources [java] input encoding: euc-jp [java] normalize entries: false [java] [java] building tokeninfo dict... [java] parse... [java] sort... [java] encode... [java] 58670 nodes, 289550 arcs, 1974184 bytes... done [java] done [java] building unknown word dict...done [java] building connection costs...done
以下の表示が見れたら
BUILD SUCCESSFUL
Total time: 41 seconds
Kuromoji本体をビルドします。
$ ant jar-core
JARファイルは、IPA辞書の時と同じところにできるので、取っておくようにしてください。
こちらは、こういう名前にしました。
lucene-analyzers-kuromoji-4.5.1-mecab-naist-jdic.jar
使ってみる
動作確認のため、こんなソースを用意。
build.sbt
name := "lucene-kuromoji-dict" version := "0.0.1-SNAPSHOT" scalaVersion := "2.10.3" organization := "littlewings" libraryDependencies ++= Seq( "org.apache.lucene" % "lucene-core" % "4.5.1", "org.apache.lucene" % "lucene-analyzers-common" % "4.5.1" )
sbtの依存関係には、Kuromojiは含めていません。Kuromojiは、libディレクトリに入れます。
src/main/scala/LuceneKuromojiDict.scala
import org.apache.lucene.analysis.ja.JapaneseAnalyzer import org.apache.lucene.analysis.tokenattributes.CharTermAttribute import org.apache.lucene.util.Version object LuceneKuromojiDict { def main(args: Array[String]): Unit = { val luceneVersion = Version.LUCENE_45 val analyzer = new JapaneseAnalyzer(luceneVersion) for (text <- Array("すもももももももものうち。", "メガネは顔の一部です。", "日本経済新聞でモバゲーの記事を読んだ。", "Java, Scala, Groovy, Clojure", "LUCENE、SOLR、Lucene, Solr", "アイウエオカキクケコさしすせそABCXYZ123456", "Lucene is a full-featured text search engine library written in Java.", "このComputerは、10回に1回の割合で起動中に青い画面が表示されます。")) { println(s"Original[$text]") val tokenStream = analyzer.tokenStream("", text) val charTermAttribute = tokenStream.addAttribute(classOf[CharTermAttribute]) tokenStream.reset() println { Iterator .continually(tokenStream) .takeWhile(_.incrementToken()) .map(t => charTermAttribute.toString) .mkString("Tokenize[", " ", "]") } tokenStream.close() println() } } }
前回の例と、あんまり変わりませんね。
$ mv lucene-analyzers-kuromoji-4.5.1-mecab-ipadic.jar lib/
実行。
> run [info] Running LuceneKuromojiDict Original[すもももももももものうち。] Tokenize[すもも もも もも] Original[メガネは顔の一部です。] Tokenize[メガネ 顔 一部] Original[日本経済新聞でモバゲーの記事を読んだ。] Tokenize[日本 日本経済新聞 経済 新聞 モバゲ 記事 読む] Original[Java, Scala, Groovy, Clojure] Tokenize[java scala groovy clojure] Original[LUCENE、SOLR、Lucene, Solr] Tokenize[lucene solr lucene solr] Original[アイウエオカキクケコさしすせそABCXYZ123456] Tokenize[アイウエオカキクケコ しす そ abcxyz 123456] Original[Lucene is a full-featured text search engine library written in Java.] Tokenize[lucene is a full featured text search engine library written in java] Original[このComputerは、10回に1回の割合で起動中に青い画面が表示されます。] Tokenize[computer 10 回 1 回 割合 起動 中 青い 画面 表示] [success] Total time: 1 s, completed 2013/11/16 1:41:50
こういう結果になりました。
続いて、IPA辞書版を退避して
$ mv lib/lucene-analyzers-kuromoji-4.5.1-mecab-ipadic.jar ./.
NAIST辞書版と入れ替え。
$ mv lucene-analyzers-kuromoji-4.5.1-mecab-naist-jdic.jar lib/
実行。
> run [info] Running LuceneKuromojiDict Original[すもももももももものうち。] Tokenize[すもも もも もも] Original[メガネは顔の一部です。] Tokenize[メガネ 顔 一部] Original[日本経済新聞でモバゲーの記事を読んだ。] Tokenize[日本 日本経済新聞 経済 新聞 モバゲ 記事 読む] Original[Java, Scala, Groovy, Clojure] Tokenize[java scala groovy clojure] Original[LUCENE、SOLR、Lucene, Solr] Tokenize[lucene solr lucene solr] Original[アイウエオカキクケコさしすせそABCXYZ123456] Tokenize[アイウエオカキクケコ しす そ abcxyz 1 2 3 4 5 6] Original[Lucene is a full-featured text search engine library written in Java.] Tokenize[lucene i s a full featured text search engine library written i n java] Original[このComputerは、10回に1回の割合で起動中に青い画面が表示されます。] Tokenize[computer 1 0 回 1 回 割合 起動 中 青い 画面 表示] [success] Total time: 1 s, completed 2013/11/16 1:43:13
パッと見たところ、変わりはないように見えますが、よくよく見ると
### IPA版 Original[アイウエオカキクケコさしすせそABCXYZ123456] Tokenize[アイウエオカキクケコ しす そ abcxyz 123456] ### NAIST版 Original[アイウエオカキクケコさしすせそABCXYZ123456] Tokenize[アイウエオカキクケコ しす そ abcxyz 1 2 3 4 5 6] ### IPA版 Original[Lucene is a full-featured text search engine library written in Java.] Tokenize[lucene is a full featured text search engine library written in java] ### NAIST版 Original[Lucene is a full-featured text search engine library written in Java.] Tokenize[lucene i s a full featured text search engine library written i n java] ### IPA版 Original[このComputerは、10回に1回の割合で起動中に青い画面が表示されます。] Tokenize[computer 10 回 1 回 割合 起動 中 青い 画面 表示] ### NAIST版 Original[このComputerは、10回に1回の割合で起動中に青い画面が表示されます。] Tokenize[computer 1 0 回 1 回 割合 起動 中 青い 画面 表示]
が異なります。NAIST版は、アルファベットと数字の扱いが違いますね。分解しちゃうというか、ものによっては半角フィルタをかけているはずなのに、全角のままだったりします。
辞書を変えるだけで動きが変わることを、自分で確認できましたね。
形態素解析の辞書って、何を選ぶのがいいんでしょ?