【Windows】MeCab で『分かち書き』する Python コード例【NEologd】

Python

MeCab でテキストを分かち書きにする Python コード例を書きました。

-O, --output-format-type の引数を使用します。

OS は Windows 10 (64 bit) です。

mecab-ipadic-NEologd から作成した『MeCab 用のユーザー辞書 (.dic)』を使用して、テキストを分かち書きにしました。

Python バインディングの外部ライブラリは、必要無かったです。

Python の subprocess.run() から mecab.exe を使用して結果を受け取りました。

MeCab マニュアル

辞書の文字コードは UTF-8 を使用しました

MeCab をインストールするときの『辞書の文字コードの選択 (SHIFT-JIS, UTF-8, UTF-16, EUC-JP)』についてです。

自分は UTF-8 を選んでインストールしました。

cmd.exemecab.exe のコンソール上では、UTF-8 形式の辞書の内容が文字化けしてしまいましたが、解析自体は正常にできていました。

cmd.exemecab.exe のコンソール上で、日本語を表示したい場合は、MeCab をインストールするときに『SHIFT-JIS』を選ぶと正常に表示することができました(その代わり、SHIFT-JIS で表せる範囲のテキストしか解析できなくなりました)。

UTF-8 形式でインストールすれば、『UTF-8 で記録したテキスト』も『SHIFT-JIS で記録したテキスト』も解析することができました。

詳細は割愛しますが、文字コードの違いは(エンコーディングの違いは)、Python で吸収しました。

Python で色々な文字コードのテキストを読み込んで、MeCab に渡すときに UTF-8 にエンコードして渡します。

これで、様々な文字コードで記録された日本語のテキストを、自在に解析できるようになりました。

(参考)(docs.python.org) Unicode HOWTO(Unicode 入門)(😊絵文字✨を含めて Python が Unicode や UTF-8 をどのように使用しているか?の説明です)

32 bit 版 MeCab

『MeCab の本体』とドキュメントの場所です。自分が取得した時の MeCab インストーラーは『mecab-0.996.exe』でした。

(taku910.github.io) MeCab (和布蕪)とは – MeCab: Yet Another Part-of-Speech and Morphological Analyzer

64 bit 版 MeCab

64 bit 版の MeCab でも mecab-dict-index.exe が一緒にインストールされましたので、同じ方法でユーザー辞書 (.dic) を作ることができました。

『64 bit 版の MeCab の本体』の場所です。自分が取得した時の MeCab インストーラーは『mecab-64-0.996.2.exe』でした。

(github.com) MeCab 0.996 64bit version

MeCab の引数

mecab.exe に渡す引数ひきすうの説明です。

(taku910.github.io) その他のコマンドラインオプション (-r, --rcfile, -d, --dicdir, -O, --output-format-type, -b, --input-buffer-size)

--rcfile に指定する『リソースファイル (mecabrc)』の書き方(ユーザー辞書の指定方法)。

(taku910.github.io) 単語の追加方法 ⇒ ユーザ辞書への追加 ⇒ userdic は CSV フォーマットで複数指定可能(2022年2月2日閲覧)

userdic = /home/foo/bar/foo.dic,/home/foo/bar2/usr.dic,/home/foo/bar3/bar.dic

(taku910.github.io) わかち書きをする (mecab -O wakati)

NEologd マニュアル

『NEologd (mecab-ipadic-NEologd) の本体』とドキュメントの場所です。自分は『緑色の Code▼ボタン ⇒ Download ZIP』から取得した『mecab-ipadic-neologd-master.zip』というファイルを使用しました。

(github.com) neologd/mecab-ipadic-neologd: Neologism dictionary based on the language resources on the Web for mecab-ipadic

(github.com) mecab-ipadic-NEologd とは

ユーザー辞書とリソースファイルの作り方

MeCab 用の『ユーザー辞書 (.dic)』と『リソースファイル (mecabrc)』の作り方を書きました。

【Windows】MeCab で NEologd の辞書を作ってインストールする方法【Python】

Python マニュアル

コード例で使用した Python 機能のマニュアルの場所です。

改行コードについて ('\n', '\r\n', '\r')

コード例の中に (改行コードは様々な要因で変わります) と書いたことの補足です。

mecab.exe の標準出力 (stdout) の末尾には、b'EOS\n' というバイト列 (bytes 型) が付いていました(EOS は、たぶん end of sequence の略です)。

(taku910.github.io) MeCab 出力フォーマット "EOS\n"

ですが、それを Windows の Python で文字列 (str 型) にデコードしたら、'EOS\r\n' になりました('\r' が自動的に追加されました)。

そのあたりの Python の挙動の説明は割愛しますが、自分が見た Python マニュアルの場所を紹介します。

(docs.python.org) class io.TextIOWrapper(buffer, encoding=None, errors=None, newline=None, line_buffering=False, write_through=False)

(docs.python.org) universal newlines テキストストリームの解釈法 ('\n', '\r\n', '\r')(改行コード)

(docs.python.org) str.splitlines([keepends])

コード例

Windows の Mecab で、テキストを分かち書きにする Python コード例です。

Neologd の辞書から生成した『ユーザー辞書 (.dic)』も使用しました。

MeCab は 32 bit 版でも 64 bit 版でも使用できました。

"""
mecab.exe を使用して、テキストを
『分かち書き』に変換する Python コード例です。

『アウトプット フォーマット タイプ』の引数
(-O, --output-format-type=TYPE) を使用します。

Neologd の辞書から生成した『ユーザー辞書』も使用して、
『分かち書き』に変換しました。
"""
from pathlib import Path
import subprocess, sys, datetime

# 実行ファイル (.exe) の場所です。
exe_file = Path(r'C:\Program Files (x86)\MeCab\bin\mecab.exe')
# exe_file = Path(r'C:\Program Files\MeCab\bin\mecab.exe') # 64-bit

# システム辞書のフォルダの場所です。
system_dic_dir = Path(r'C:\Program Files (x86)\MeCab\dic\ipadic')
# system_dic_dir = Path(r'C:\Program Files\MeCab\dic\ipadic') # 64-bit

# rcfile (resource file) の場所です。
# この中に『ユーザー辞書』のファイルパスたちを書いて
# mecab.exe に渡します。
rc_file = Path(r'F:\user_dic\mecabrc')

# (デバッグ)
print(f'(Python) {sys.version}')
print(f'(exe_file) {exe_file}')
print(f'(system_dict_dir) {system_dic_dir}')
print(f'(rc_file) {rc_file}\n')


def main():
    # (1/5) エンコーディング (文字コード) を決めます。
    # MeCab の辞書 (システム辞書 & ユーザー辞書) と
    # 同じエンコーディングを選びます。
    # UTF-8 で辞書を作ったなら 'utf-8' を選びます。
    # SHIFT-JIS で辞書を作ったなら 'shift-jis' を選びます。
    encoding = 'utf-8'

    # (2/5) 文章を用意します。
    src_text = 'ジャパンネット銀行がPayPay銀行に変わりました。'

    # 文字列 (str 型, Unicode コードポイントの文字列) を
    # エンコードして、バイト列 (bytes 型) に変換します。
    src_bytes = src_text.encode(encoding, errors='strict')

    # mecab.exe の『入力バッファサイズ』を決めます。
    # 文章の『バイト列の長さ + 1』の数を指定します。
    len_src_bytes = len(src_bytes) + 1
    # +1 しないと、mecab.exe が標準エラー出力 (stderr) に
    # 以下のエラーメッセージを出しました。
    # input-buffer overflow. The line is split. use -b #SIZE option.

    # (デバッグ) --input-buffer-size を使わなかったときの
    # 文字数の限界例です (MeCab 辞書が UTF-8 の場合です)。
    # ※ 自分の環境で試した結果です ※
    # src_text = 'あ' * 2730 # OK (2730文字) 入力バッファサイズの指定無し。
    #   len(src_text.encode('utf-8')) ⇒ 8190
    # src_text = 'あ' * 2731 # NG (2731文字) --input-buffer-size 8194 で OK。
    #   len(src_text.encode('utf-8')) ⇒ 8193

    # (デバッグ)
    print(f'(src_text) {src_text}')
    print(f'len(src_text) {len(src_text)}')
    print(f'(encoding) {encoding}')
    print(f'len(src_bytes) {len(src_bytes)}')
    print(f'(--input-buffer-size) {len_src_bytes}\n')

    # (3/5) コマンドを作ります。
    # タプル (tuple) でもリスト (list) でも OK です。
    cmd = (
        exe_file,
        '--rcfile', rc_file,
        '--dicdir', system_dic_dir,
        '--output-format-type', 'wakati',
        '--input-buffer-size', str(len_src_bytes),
        )
    # (以下の書き方でも OK)
    # cmd = (
    #     exe_file,
    #     '-r', rc_file,
    #     '-d', system_dic_dir,
    #     '-O', 'wakati',
    #     '-b', str(len_src_bytes),
    #     )

    # (システム辞書だけを使用する場合)
    # cmd = (
    #     exe_file,
    #     '--dicdir', system_dic_dir,
    #     '--output-format-type', 'wakati',
    #     '--input-buffer-size', str(len_src_bytes),
    #     )

    # (補足)『ユーザー辞書 (rc_file)』を使うときは、
    # システム辞書のフォルダも指定しないと、以下のエラーが出ました。
    # param.cpp(69) [ifs] no such file or directory: .\dicrc

    # (4/5) mecab.exe で解析します。
    cp = subprocess.run(
        cmd,
        input=src_bytes,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        timeout=30.0,
        )
    # cp は CompletedProcess の略です。

    # stdout=subprocess.PIPEは、結果を
    # cp.stdout から受け取るために設定しました。

    # stderr=subprocess.PIPE は、mecab.exe の標準エラー出力 (stderr) を
    # cp.stderr から受け取るために設定しました。
    # 例えば mecab.exe は、
    # input-buffer overflow. The line is split. use -b #SIZE option.
    # というエラーメッセージを標準エラー出力に出していました。

    # timeout=30.0 は、一応指定しています。
    # たいていは一瞬で完了するテキストしか扱わないので、
    # 30 秒かかっても終わらないなら異常とみなすことにしました。
    # その時は、exception subprocess.TimeoutExpired が発生しました。

    # (デバッグ) 標準エラー出力の内容を表示します (通常は空文字列のはず)。
    stderr = cp.stderr.decode(encoding, errors='backslashreplace')
    # errors には 'strict', 'ignore', 'replace', 'backslashreplace'
    # などが設定できました。
    print(f'(stderr) {stderr}')

    # (デバッグ) 戻り値を表示します。
    print(f'(returncode) {cp.returncode}')
    # 成功時は cp.returncode = 0 でしたが、エラー時もたいてい 0 でした。

    # (5/5)『分かち書き』の結果を取得します。
    stdout = cp.stdout.decode(encoding, errors='strict')

    # 結果の末尾には余分な
    # 『半角スペース (' ', '\x20')』と
    # 『復帰文字 ('\r', '\x0d')』と
    # 『改行文字 ('\n', '\x0a')』が
    # 付いてきたので、除去します。
    # (改行コードは様々な要因で変わります)
    wakati_data = stdout.rstrip(' \r\n')
    # 以下の書き方でも OK です。
    # wakati_data = stdout.rstrip('\x20\x0d\x0a')

    # (デバッグ) 結果を表示します。
    print('(結果 ここから)')
    print(wakati_data)
    print('(結果 ここまで)')

    # (デバッグ) cmd の内容を表示します。
    print(f'(cmd)\n{cp.args}')
    return


if __name__ == '__main__':
    print('start')
    start_time = datetime.datetime.now()
    try:
        main()
    finally:
        elapsed_time = datetime.datetime.now() - start_time
        print(f'\n(経過時間) {elapsed_time}')
        print('end')

実行結果

コード例の実行結果です。

(Python) 3.8.6 (tags/v3.8.6:db45529, Sep 23 2020, 15:52:53) [MSC v.1927 64 bit (AMD64)]
(exe_file) C:\Program Files (x86)\MeCab\bin\mecab.exe    
(system_dict_dir) C:\Program Files (x86)\MeCab\dic\ipadic
(rc_file) F:\user_dic\mecabrc

start
(src_text) ジャパンネット銀行がPayPay銀行に変わりました。
len(src_text) 26
(encoding) utf-8
len(src_bytes) 66
(--input-buffer-size) 67

(stderr)
(returncode) 0
(結果 ここから)
ジャパンネット銀行 が PayPay 銀行 に 変わり まし た 。
(結果 ここまで)
(cmd)
(WindowsPath('C:/Program Files (x86)/MeCab/bin/mecab.exe'),
'--rcfile', WindowsPath('F:/user_dic/mecabrc'),
'--dicdir', WindowsPath('C:/Program Files (x86)/MeCab/dic/ipadic'),
'--output-format-type', 'wakati',
'--input-buffer-size', '67')

(経過時間) 0:00:00.020965
end

『分かち書き』のテキストを得ることができました。

『ジャパンネット銀行』の固有名詞は、Neologd の辞書を使用したことで得ることができました。

システム辞書だけの場合は、『ジャパン ネット 銀行』の3つに分かれていました。

以上です。

スポンサーリンク
シェアする(押すとSNS投稿用の『編集ページ』に移動します)
フォローする(RSSフィードに移動します)
スポンサーリンク
シラベルノート
タイトルとURLをコピーしました