Sphinxの分かち書きアルゴリズムにMeCabを使用する

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。サービスグループの武田です。

ドキュメントやマニュアル、作成してますか?作成・管理する上でのツールとしてWikiシステムやWordなどのワープロソフトがありますね。ちなみに、現在のプロダクトではSphinxを使用しています。

Sphinxで作成したドキュメントには検索窓が付いており全文検索が可能です。Sphinxはデフォルトの分かち書きアルゴリズムとしてTinySegmenterを採用しています。そのままでも結構よいインデックスが作成されますが、マッチしてほしい単語がインデックスされていないという問題にあたりました。そこで今回、使用される全文検索のインデックス作成アルゴリズムをデフォルトからMeCabに変更することを検証しましたので、その方法を紹介します。

環境

今回は次の環境で検証しました。なおSphinxの言語は日本語を指定しています(language = 'ja')。

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.13.6
BuildVersion:	17G65

$ python3 -V
Python 3.6.5

$ pip -V
pip 18.0 from /usr/local/lib/python3.6/site-packages/pip (python 3.6)

$ pip list | grep Sphinx
Sphinx                   1.7.4

$ brew --version
Homebrew 1.7.2
Homebrew/homebrew-core (git revision 10b4f; last commit 2018-08-27)

MeCabを使用する準備

何はともあれMeCabをインストールしないと始まりません。

$ brew install mecab mecab-ipadic
$ pip install mecab-python3

続いてmecab-ipadic-NEologdという、標準の辞書に新語を追加したカスタム辞書をインストールします。詳細はmecab-ipadic-NEologdを参照してください。

$ mkdir /path/to/neologd && cd $_
$ git clone --depth 1 git@github.com:neologd/mecab-ipadic-neologd.git
$ ./bin/install-mecab-ipadic-neologd -n -a
$ echo "$(mecab-config --dicdir)/mecab-ipadic-neologd"
/usr/local/lib/mecab/dic/mecab-ipadic-neologd

最後に表示されたパスはSphinxの設定ファイルに設定するためメモしておきます。

SphinxでMeCabを使用する

それではSphinxの設定ファイルであるsource/conf.pyに、MeCabを使用するための設定をします。ファイル内の任意の場所に次のスニペットを追加します。

html_search_options = {
    'type': 'sphinx.search.ja.MecabSplitter',
    'dic_enc': 'utf-8',
    'dict': '/usr/local/lib/mecab/dic/mecab-ipadic-neologd'
}

ちなみに、この設定方法は公式ドキュメントに書かれていますが、そのとおりtypeにsphinx.search.ja.MeCabSplitterを指定するとビルドに失敗します。正しくはsphinx.search.ja.MecabSplitterと指定する必要がありますので気をつけてください。

2018-09-04追記
MeCabSplitterの名前を修正したコミットをPRしたところマージされました。

あとは普通にビルドすれば、MeCabを使用したインデックスが作成されます。

$ make html

作成されたインデックスはbuild/html/searchindex.jsです。このファイルはUnicodeエスケープおよびminifyされているため、DefaultとMeCabで作成されたインデックスを比較したい場合などは次のようにすると比較しやすいです。

$ pip install jsbeautifier
$ cat build/html/searchindex.js \
  | python3 -c 'from sys import stdin; print(stdin.readline().encode().decode("unicode-escape"))' \
  | js-beautify \
  > searchindex_mecab.js

まとめ

分かち書きアルゴリズムをMeCabに変更してみることで作られるインデックスの差分を検証できました。おおむねインデックスの精度は向上しましたが、逆にインデックスされなくなってしまった単語もありました(クラスメソッド など)。アルゴリズムを変更することでプラスだけでなくマイナスもありますので、変更する際はよく検証をしましょう。