こんにちは!!こんにちは!! moriyamaです
この記事は actindi Advent Calendar 2019 の21日目の記事です。
唐突ですが、以前書いた記事で、「いこーよ」という単語は固有名詞として扱われず、
「いく
」 「ー
」 「(空白文字)
」の3単語に分解されていると確認できました。
「いこーよ」は多くの方に認知されているので、辞書を使わずに形態素解析でも1単語にならないかと思い、
そこで今回は、NEologdを使った検索エンジン(Solr)の検証をしてみました。
そもそもNEologdとは?
冒頭でいきなり略語で書きましたが、正式には mecab-ipadic-NEologdと言います。
NEologdは、多数のWeb上の言語資源から得た新語を追加することでカスタマイズした MeCab 用のシステム辞書です。
作者様の記事によると、
- 週2回以上更新
- 新語・固有表現に強い
- 語彙数が多い
- オープンソース・ソフトウェア
といった特徴を挙げています。
さっそく使ってみる
何はともあれNEologdの辞書を生成しなきゃ話は始まらないですね。
公式サイトを参考に、3stepです!(簡単!)
# リポジトリをclone $ git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git # ディレクトリ移動 $ cd mecab-ipadic-neologd # インストールと単語リストの更新 # ※ 後続作業のため、"--max_baseform_length 15" のオプションを付与 $ ./bin/install-mecab-ipadic-neologd -n --max_baseform_length 15
完了したら動作確認してみましょう。
mecab -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd/
で実行できるので、 echo
して解析してみましょう。
$ echo "いこーよってサイトで見つけたよ!" | mecab -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd/ いこーよ 名詞,固有名詞,一般,*,*,*,いこーよ,イコーヨ,イコーヨ って 助詞,格助詞,連語,*,*,*,って,ッテ,ッテ サイト 名詞,一般,*,*,*,*,サイト,サイト,サイト で 助詞,格助詞,一般,*,*,*,で,デ,デ 見つけ 動詞,自立,*,*,一段,連用形,見つける,ミツケ,ミツケ た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ よ 助詞,終助詞,*,*,*,*,よ,ヨ,ヨ ! 記号,一般,*,*,*,*,!,!,! EOS
無事に、「いこーよ
」と固有名詞の1単語に形態素解析されましたね!
ちなみに、通常の mecab
で実行すると今まで通りの結果です。
~ $ echo "いこーよってサイトで見つけたよ!" | mecab いこ 動詞,自立,*,*,五段・カ行促音便,未然ウ接続,いく,イコ,イコ ー 名詞,一般,*,*,*,*,* よ 助詞,終助詞,*,*,*,*,よ,ヨ,ヨ って 助詞,格助詞,連語,*,*,*,って,ッテ,ッテ サイト 名詞,一般,*,*,*,*,サイト,サイト,サイト ...
jarファイルを生成する
NEologdの辞書を生成しただけなので、検索エンジンに反映しなければ当然、検索精度は向上しませんね。
そこで、Solrの形態素解析器である、kuromojiのjarファイルを生成してみようと思います。
SolrはAntでコンパイルするので、初期設定(ant ivy-bootstrap
の実行)が必要なので注意してください。
# リポジトリをclone $ git clone git@github.com:apache/lucene-solr.git # 辞書を反映するため、NEologdの中間生成物を取り込む # ※ yyyymmddは生成日で変わるので適宜変更してください。 $ cp -Rp [mecab-ipadic-neologd]/build/mecab-ipadic-2.7.0-20070801-neologd-yyyymmdd lucene-solr/lucene/build/analysis/kuromoji/ # ディレクトリ移動 $ cd lucene-solr/lucene/analysis/kuromoji
NEologdの辞書を反映したいので、build.xml
を少し弄って中間生成物を読み込むよう修正します。
<!-- NEologdの中間生成物を読み込むように指定 <property name="ipadic.version" value="mecab-ipadic-2.7.0-20070801" /> --> <property name="ipadic.version" value="mecab-ipadic-2.7.0-20070801-neologd-yyyymmdd" /> <!-- 文字コードをUTF-8指定に変更 <property name="dict.encoding" value="euc-jp"/> --> <property name="dict.encoding" value="utf-8"/> <!-- "download-dict" targetの実行は不要なので変更 <target name="build-dict" depends="compile-tools, download-dict"> --> <target name="build-dict" depends="compile-tools"> <!-- 単語数が多いためか、自分の環境だとOut Of Memoryが頻発したので変更 <java fork="true" failonerror="true" maxmemory="1g" classname="org.apache.lucene.analysis.ja.util.DictionaryBuilder"> --> <java fork="true" failonerror="true" maxmemory="4g" classname="org.apache.lucene.analysis.ja.util.DictionaryBuilder">
ここまで終わればほぼ完了で、あとはビルドするのみです!
# lucene-solr/lucene/analysis/kuromoji 配下で辞書をビルド $ ant build-dict # jarファイルの生成 $ ant jar-core
上記コマンドが成功し、
lucene-solr/lucene/build/analysis/kuromoji/
配下に lucene-analyzers-kuromoji-x.x.x-SNAPSHOT.jar
生成されていれば完了です!
※ ちなみにmecab-ipadic-neologdのインストール時に「--max_baseform_length 15
」オプションを付与したものでないと、辞書のビルドに失敗します
... build-dict: [java] dictionary builder [java] ... [java] input encoding: utf-8 [java] normalize entries: false [java] [java] building tokeninfo dict... [java] parse... [java] sort... [java] encode... [java] Exception in thread "main" java.lang.AssertionError [java] at org.apache.lucene.analysis.ja.util.BinaryDictionaryWriter.put(BinaryDictionaryWriter.java:129) [java] at org.apache.lucene.analysis.ja.util.TokenInfoDictionaryBuilder.buildDictionary(TokenInfoDictionaryBuilder.java:143) [java] at org.apache.lucene.analysis.ja.util.TokenInfoDictionaryBuilder.build(TokenInfoDictionaryBuilder.java:78) [java] at org.apache.lucene.analysis.ja.util.DictionaryBuilder.build(DictionaryBuilder.java:37) [java] at org.apache.lucene.analysis.ja.util.DictionaryBuilder.main(DictionaryBuilder.java:82)
理由としては、kuromojiの仕様が関係しているとのことです。@kazuhira_rさんの記事がとても参考になりました。
Solrへ反映してみる
生成したjarファイルの配置先は、[Solr Home]/server/solr-webapp/webapp/WEB-INF/lib
になります。
念の為、既存の lucene-analyzers-kuromoji-x.x.x.jar
は削除orリネームしておくと安全ですね。
さてさて、Solrに反映して確認してみると
反映前 | 反映後 | |
---|---|---|
→ |
パーフェクトですね!
まとめ
これだけでは大雑把で荒削りな結果なので、詳細な検証が必要ですが、
辞書をビルドして検索エンジンへ反映する一連の作業がわかりました。
検索精度の向上が見られれば、「いこーよ」に組み込んで、良質な検索結果が提供できたら幸いです。
さいごに、アクトインディでは一緒に働きたいエンジニアを募集しています!
是非ご応募ください!