mecabの新語辞書をインストールする

非常に便利な形態素解析ソフトMeCabですが、デフォルトの辞書は最近登場した単語に弱いと言う欠点があります。
自分で辞書を改善していけたらいいのですがそれも工数が大きくめんどくさい。

以上の状況において、定期的にメンテナンスされている非常にありがたい辞書があります。
mecab-ipadic-neologd

インストール手順はリポジトリの README.ja.mdにある通りです。


$ cd ~/Downloads
$ git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
$ cd mecab-ipadic-neologd
# -a をつけると全部入り
$ ./bin/install-mecab-ipadic-neologd -n -a

途中で
Do you want to install mecab-ipadic-NEologd? Type yes or no.
と聞かれるのでこれは yes.

ドキュメントにある通り、インストール先は次のコマンドで確認できます。
(出力は僕の環境の例)


$ echo `mecab-config --dicdir`"/mecab-ipadic-neologd"
/usr/local/lib/mecab/dic/mecab-ipadic-neologd

動作確認してみましょう。
まずデフォルト辞書の場合。


~$ mecab
志村五郎先生は偉大な数学者でした。
志村	名詞,固有名詞,人名,姓,*,*,志村,シムラ,シムラ
五郎	名詞,固有名詞,人名,名,*,*,五郎,ゴロウ,ゴロー
先生	名詞,一般,*,*,*,*,先生,センセイ,センセイ
は	助詞,係助詞,*,*,*,*,は,ハ,ワ
偉大	名詞,形容動詞語幹,*,*,*,*,偉大,イダイ,イダイ
な	助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ
数学	名詞,一般,*,*,*,*,数学,スウガク,スーガク
者	名詞,接尾,一般,*,*,*,者,シャ,シャ
でし	助動詞,*,*,*,特殊・デス,連用形,です,デシ,デシ
た	助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
。	記号,句点,*,*,*,*,。,。,。
EOS

neologdの場合


~$ mecab -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd
志村五郎先生は偉大な数学者でした。
志村五郎	名詞,固有名詞,人名,一般,*,*,志村五郎,シムラゴロウ,シムラゴロー
先生	名詞,一般,*,*,*,*,先生,センセイ,センセイ
は	助詞,係助詞,*,*,*,*,は,ハ,ワ
偉大	名詞,形容動詞語幹,*,*,*,*,偉大,イダイ,イダイ
な	助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ
数学者	名詞,固有名詞,一般,*,*,*,数学者,スウガクシャ,スーガクシャ
でし	助動詞,*,*,*,特殊・デス,連用形,です,デシ,デシ
た	助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
。	記号,句点,*,*,*,*,。,。,。
EOS

志村五郎先生の名前が固有名詞として認識されていますね。
数学者も。

cloneしてきた辞書ファイルの中を見るとこのように登録されていることがわかります。


mecab-ipadic-neologd$ grep 志村五郎 * -r
build/mecab-ipadic-2.7.0-20070801-neologd-20190610/mecab-user-dict-seed.20190610.csv:志村五郎,1289,1289,4757,名詞,固有名詞,人名,一般,*,*,志村五郎,シムラゴロウ,シムラゴロー

MeCabの出力フォーマット

しばらくふれない間にまたど忘れしてしまったので、MeCabの出力フォーマットのメモです。

公式サイトの使い方 に書いてあります。

表層形\t品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用型,活用形,原形,読み,発音

よくある例の「すもももももももものうち」を形態素解析してみても * が多くてわかりにくいので、
先の公式ページの説明を読んだ方が早いです。


~$ mecab
すもももももももものうち
すもも	名詞,一般,*,*,*,*,すもも,スモモ,スモモ
も	助詞,係助詞,*,*,*,*,も,モ,モ
もも	名詞,一般,*,*,*,*,もも,モモ,モモ
も	助詞,係助詞,*,*,*,*,も,モ,モ
もも	名詞,一般,*,*,*,*,もも,モモ,モモ
の	助詞,連体化,*,*,*,*,の,ノ,ノ
うち	名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
EOS

一通り例が見たい場合、*になってばかりでなかなか登場しないのが品詞細分類3ですが、
文章に地名や人名が含まれている時に登場するので、次のような文章はいかがでしょうか。


~$ mecab
渋谷で働くデータサイエンティスト
渋谷	名詞,固有名詞,地域,一般,*,*,渋谷,シブヤ,シブヤ
で	助詞,格助詞,一般,*,*,*,で,デ,デ
働く	動詞,自立,*,*,五段・カ行イ音便,基本形,働く,ハタラク,ハタラク
データ	名詞,一般,*,*,*,*,データ,データ,データ
サイエンティスト	名詞,一般,*,*,*,*,サイエンティスト,サイエンティスト,サイエンティスト
EOS

自分は表層形、品詞、原形をよく使うので、
‘\t’でsplitした結果の、index 0 が、表層形、
index 1をさらに’,’ split して、 index 0 が品詞、index 6が原型、
ってのだけ把握していればなんとかなることが多いです。

それで、適当なテキストを試しに形態素解析して、
もも 名詞,一般,*,*,*,*,もも,モモ,モモ
と出てきて、何番目が原型だ?? となって公式サイト見に行く、ということを何度もやらかしています。

MeCab.Tagger()はかなり遅いという話

昔、形態素解析にかかる時間を短縮するために調べた内容のメモです。

以前の記事で、mecab-python3 の使い方を書いたとき、tagger = MeCab.Tagger() という処理を関数の外側で行なっていました。

実は初めてmecab-python3を使った頃、僕は次のように書いてました。


def mecab_tokenizer(text):
    # 関数の中で、MeCab.Tagger()を呼び出す。これが遅い
    tagger = MeCab.Tagger()
    parsed_text = tagger.parse(text)
    parsed_lines = parsed_text.split("\n")[:-2]
    surfaces = [l.split('\t')[0] for l in parsed_lines]
    features = [l.split('\t')[1] for l in parsed_lines]
    bases = [f.split(',')[6] for f in features]
    # ここに、必要な品詞の単語だけ選抜する処理を入れることもある
    result = [b if b != '*' else s for s, b in zip(surfaces, bases)]
    return result

1個や2個のテキストを処理する分にはこの書き方で問題なかったのですが、
数十万件のテキストを処理するとこの関数がとても遅いという問題があり、調査をしていました。

結果わかったことは、タイトルの通り、MeCab.Tagger()が遅いということです。
jupyter で コードの前に %timeit とつけると時間を測れるのでやってみます。


%timeit tagger=MeCab.Tagger()
```
結果:
217 µs ± 6.17 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
```

ちなみに、形態素解析自体(parse)の実行時間はこちら


# 100文字のテキストを事前に用意しておきます
print(len(text))
```
100
```
%timeit parsed_text = tagger.parse(text)
```
結果:
26.9 µs ± 151 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
```

テキストがもっと長くなると話も変わるのですが、100文字くらいのテキストであれば、
parseにかかる時間よりも、Taggerのオブジェクトを作るのにかかる時間の方が8くらいかかっています。

対象のテキスト数(=関数が呼び出される回数)が数十万〜数百万件になってくると、
体感スピードがかなり違うので、
tagger = MeCab.Tagger()
は関数の中ではなく、事前に行うようにしておきます。

名前空間を汚染したりすることが気になる場合は、 class化するなどの対応をとりましょう。
また、形態素解析するテキストの数が少ない場合はあまり気にしなくても大丈夫です。

完全に余談ですが、この記事を書くために私物のMacで時間を計測したとき、職場のMacよりはるかに速いので感動しました。
職場の端末だとMeCab.Tagger()に 1.2ms (6倍!)かかります。
端末が5年物とそこそこ古いだけでなく、辞書指定などの問題もあるかもしれません。

mecab-python3をつかってみる

前回の記事でインストールした mecab-python3 の使い方を書いておきます。
MeCabについてはWikiがあるのですが、このライブラリについては詳細なマニュアルはなく、
リポジトリの test.py を読むようにとそっけなく書いてあります。

ただ、実際のところつかのは非常に簡単です。
次の例のようにMeCab.Tagger() と parse を呼び出すだけで結果を得られます。


>>> import MeCab
>>> text = 'すもももももももものうち'
>>> tagger = MeCab.Tagger()
>>> print(tagger.parse(text))
すもも	名詞,一般,*,*,*,*,すもも,スモモ,スモモ
も	助詞,係助詞,*,*,*,*,も,モ,モ
もも	名詞,一般,*,*,*,*,もも,モモ,モモ
も	助詞,係助詞,*,*,*,*,も,モ,モ
もも	名詞,一般,*,*,*,*,もも,モモ,モモ
の	助詞,連体化,*,*,*,*,の,ノ,ノ
うち	名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
EOS

各行の出力結果は次の形です。

表層形\t品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用型,活用形,原形,読み,発音

注意点としては、 parseした戻り値は一つのテキストなので非常に使いにくいことです。

多くの場合、必要なのは原型の列です。
そこでプログラムでこのテキストから原形の情報を取り出すことになります。
僕はいつも下記のような関数を作って実行しています。


tagger = MeCab.Tagger()


def mecab_tokenizer(text):
    parsed_text = tagger.parse(text)
    parsed_lines = parsed_text.split("\n")[:-2]
    surfaces = [l.split('\t')[0] for l in parsed_lines]
    features = [l.split('\t')[1] for l in parsed_lines]
    bases = [f.split(',')[6] for f in features]
    # ここに、必要な品詞の単語だけ選抜する処理を入れることもある
    result = [b if b != '*' else s for s, b in zip(surfaces, bases)]
    return result

Mac(Mojave) に pip で mecab-python3をインストールする時にはまった

環境
MacOS Mojave 10.14.2 (OS)
mecab-python3==0.996.1 (入れようとしたライブラリ)

本当はサクッとインストールして使い方について説明するはずだったのに、非常に苦戦したので記録しておきます。
MeCabをpythonから使うために、mecab-python3をインストールしようとしました。
コマンドはサイトに書いてある通り、こちらです。


pip install mecab-python3

これ、自分のや職場のPC,クラウド環境など、過去にいろんな環境で実行してきましたが、今回初めて失敗しました。

まず最初のエラーは、swig が入ってないとのことだったので、Homebrewで入れます。


brew install swig

この後再実行すると、別のエラー。しかもかなりの長文が出て失敗しました。
問題の箇所を抜粋したのがこちらです。


  warning: include path for stdlibc++ headers not found; pass '-std=libc++' on the command line to use the libc++ standard library instead [-Wstdlibcxx-not-found]
  MeCab_wrap.cpp:3051:10: fatal error: 'stdexcept' file not found
  #include 
           ^~~~~~~~~~~
  1 warning and 1 error generated.
  error: command 'gcc' failed with exit status 1

なにかのheaderがないと言われています。
これについて調べた結果、ネット上各所に command Line Toolsの
最新バージョンが問題であると指摘がありました。
ということで、command Line Toolsのバージョンを落とします。
こちらにアクセス
https://developer.apple.com/download/more/

どこまで古いバージョンなら良いのか確信が持てませんでしたが、
試しにXcode 9.4 向けのdmgファイルをダウンロードしてインストールしました。
その後、改めて最初のpipコマンドを打つと無事にpythonからMeCabが使えるようになりました。

MacにMeCabをインストールする

Mac Book Proに 形態素解析ソフトのMeCabをインストールします。

homebrewを導入済みであれば簡単です。
ソフトウェア本体と、IPA辞書を順番にインストールします。


brew install mecab
brew install mecab-ipadic

入ったらテストしましょう。mecabコマンドで起動したあと、形態素解析したい文章を入力します。


~$ mecab
すももももももものうち
すもも	名詞,一般,*,*,*,*,すもも,スモモ,スモモ
もも	名詞,一般,*,*,*,*,もも,モモ,モモ
も	助詞,係助詞,*,*,*,*,も,モ,モ
もも	名詞,一般,*,*,*,*,もも,モモ,モモ
の	助詞,連体化,*,*,*,*,の,ノ,ノ
うち	名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
EOS

終了は Ctrl + d です。