LoginSignup
12
13

More than 3 years have passed since last update.

Pythonから呼び出すMeCabのデフォルト辞書を変更する

Last updated at Posted at 2020-05-05

はじめに

ターミナルなどで使うMeCabのデフォルト辞書はmecabrcを編集することで変えられますが、mecab-python3をインストールしてpythonプログラムからMeCabをつかうときのデフォルト辞書はそれだけでは変えられません。"-d"オプションで毎回指定するのも面倒です。
やり方を調べても日本語記事がぱっと見つからなかったので、最終的に自分の環境でうまくできた方法をメモとして残しておきます。

環境

  • OS
    • macOS Catalina 10.15.4
  • MeCab
    • mecab 0.996 (brewでインストール)
    • mecab-ipadic-NEologd
  • Python
    • python3.8.0 (pyenvでインストール)
    • mecab-python3 (pipでインストール)

MeCabなどのインストールは下記サイトの手順にほぼ倣いました。
https://qiita.com/taroc/items/b9afd914432da08dafc8

やったこと

MECABRCという環境変数に読み込むべきmecabrcのパスを設定したところ、pythonから呼び出すMeCabのデフォルト辞書を変える事ができました。

参考
https://pypi.org/project/mecab-python3/

具体的に、僕の環境では下記のような操作をしました。

1.通常のmecabが読み込むmecabrcを編集してデフォルト辞書を変更する

% nano /usr/local/etc/mecabrc

#書き換え前
dicdir =  /usr/local/lib/mecab/dic/ipadic

#書き換え後
;dicdir =  /usr/local/lib/mecab/dic/ipadic
dicdir =  /usr/local/lib/mecab/dic/mecab-ipadic-neologd

2.環境変数MECABRCに1で編集したmecabrcのパスを代入する

% nano ~/.zshrc

#下記を追記
export MECABRC=/usr/local/etc/mecabrc

ターミナルを再起動(またはsource ~/.zshrc)したあと、「インスタ映え」などの新語が一単語として認識されれば成功です。

% python
>>> import MeCab
>>> MeCab.Tagger().parse('インスタ映え')
'インスタ映え\t名詞,固有名詞,一般,*,*,*,インスタ映え,インスタハエ,インスタハエ\nEOS\n'

補足(興味ある人向け)

以下、余談ですが、「MECABRCという環境変数を設定する」という解決方法だけわかっても今ひとつピンとこなかったので、ライブラリソースも参照しつつ、mecab-python3のデフォルト辞書がどのように決定されているのか調べてみました。不正確な点や補足すべき情報があればご指摘いただけると幸いです。

下記のサイトが参考になりました。
https://pypi.org/project/mecab-python3/

このサイトよるとmecab-python3はipa辞書のコピーをパッケージ内にもっていて、デフォルトではその辞書を使うようです。

ためしに僕の環境(pyenvで管理しているpipでmecab-python3をインストール)でのMeCabライブラリをみてみます。

% cd ~/.pyenv/versions/3.8.0/lib/python3.8/site-packages/MeCab
% ls
_MeCab.cpython-38-darwin.so
__init__.py
__pycache__
dic
mecabrc.in

ここにあるdicがpythonから呼び出すMeCabがデフォルトで参照する辞書です。同様に設定ファイルはmecabrc.inの情報を使っています。

これらのファイルをデフォルト値として参照する手続きは__init__.pyにかかれています。(下記、5、6行目)。

__init__.py
def _init_bundled_info():
    global BUNDLED_DICDIR
    global _BUNDLED_MECABTMPL
    pkgdatadir = os.path.dirname(__file__)
    dicdir = os.path.join(pkgdatadir, "dic")
    mecabtmpl = os.path.join(pkgdatadir, "mecabrc.in")
    if os.path.isdir(dicdir) and os.path.isfile(mecabtmpl):
        BUNDLED_DICDIR = os.path.abspath(dicdir)
        _BUNDLED_MECABTMPL = os.path.abspath(mecabtmpl)
    else:
        BUNDLED_DICDIR = None
        _BUNDLED_MECABTMPL = None

またその数行下には以下の記述があり、4行目のif文でMECABRCという環境変数がないときにはデフォルト値を使うような挙動になっていることが分かります。

__init__.py
@contextlib.contextmanager
def _mecabrc_for_bundled_dictionary():
    dicdir = BUNDLED_DICDIR
    if dicdir is not None and "MECABRC" not in os.environ:
        mecabtmpl = _BUNDLED_MECABTMPL

したがってMECABRCという環境変数を明に設定すると、デフォルトの辞書を変更できるようです。
よくわかっていないのは、環境変数の値(os.environ['MECABRC'])を具体的に取得している記述がどこかということですが、__init__.pyや他のファイルをみてもそういう場所が見つけられなかったので、pip installではダウンロードされないファイルにかかれているのかもしれません。

おわりに

pythonからMeCabを使うときのデフォルト辞書の変更方法について、自分の環境でうまくいった方法についてまとめました。
ついでにせっかくなので、mecab-python3のソースを読んで、デフォルト辞書がどのように決定されているのか調べてみました。完全な理解には至りませんでしたが、調べる前よりはいくらかスッキリできました。
なにかの参考になれば幸いです。

12
13
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
13