mecab-python3 で形態素解析する方法

🍪この記事の内容:
  • mecab-python3 で形態素解析する。
日本語文章を形態素解析する (意味を持つ最小単位に分割し品詞をタグ付けする) ソフトウェアの一つに MeCab [1] があるが、MeCab には Python ラッパー mecab-python3 [2] もあり Python からの利用も便利である。mecab-python3 は MeCab の厳密なラッパーなので、出力をカスタマイズしたいときなどは MeCab 本体のマニュアルを参照するとよい。

参考文献

  1. MeCab: Yet Another Part-of-Speech and Morphological Analyzer, , 2025年10月12日参照.
    • 上記や以下のマニュアルは MeCab に同梱されている。C:\Program Files\MeCab\doc などにある。
      • 出力フォーマット:
  2. SamuraiT/mecab-python3: 🐍 mecab-python. you can find original version here:http://taku910.github.io/mecab/, , 2025年10月12日参照.
  3. 辞書のフィールド | Yuta Hayashibe, , 2025年10月12日参照.
    • 辞書が UniDic の場合に MeCab から取得できる形態素の特徴がある。辞書が UniDic でなく IPADIC や JUMAN の場合のフィールドも上記サイト内の別ページにある。

形態素解析する (形態素の表層文字列のみ取得する)

文章を分割するだけであれば、出力フォーマットをわかち書き [1] (の 1.) として形態素間に空白を挿入し、必要に応じて .split() すればよい。

import MeCab

if __name__ == '__main__':
    dict_path = 'C:/Program Files/MeCab/dic/unidic-csj-3.1.1-full'
    tagger = MeCab.Tagger(f'-d "{dict_path}" -O wakati')  # わかち書き

    s = 'ヒンメルはもういないじゃない'
    tokens = tagger.parse(s).split()
    print(tokens)

['ヒンメル', 'は', 'もう', 'い', 'ない', 'じゃ', 'ない']
クラスにしておくと常に何らかの前処理や後処理をしたいときに便利である。

import MeCab

class MyParser:
    def __init__(self):
        dict_path = 'C:/Program Files/MeCab/dic/unidic-csj-3.1.1-full'
        self.tagger = MeCab.Tagger(f'-d "{dict_path}" -O wakati')
    def parse(self, s):
        return self.tagger.parse(s).split()

if __name__ == '__main__':
    parser = MyParser()
    s = 'ヒンメルはもういないじゃない'
    print(parser.parse(s))

形態素解析する (形態素の特徴も取得する)

各形態素の表層文字列だけでなく、品詞や基本形や読みなどの形態素自体の特徴や、分割するにあたって用いられた生起コストや連接コストなどの特徴がほしいこともある。
  • 前者の形態素自体の特徴については、何が取得できるかは辞書に依存する。UniDic の場合に取得できるフィールドは参考文献 [3] にある (配布元の国語研コーパスポータルを参照するべきだが、この記事を書いている2025年10月12日現在、不明な原因で手元からアクセスできない)。
  • 後者の分割時の特徴はマニュアル [1] (の 1.) に詳しい。
これらを踏まえて、各形態素の「表層文字列, 品詞大分類, 中分類, 小分類, 細分類, 生起コスト, 1つ前の形態素との連接コスト, 累積コスト」を取得すると以下のようになる。

import MeCab

class MyParser:
    def __init__(self):
        dict_path = 'C:/Program Files/MeCab/dic/unidic-csj-3.1.1-full'
        self.tagger = MeCab.Tagger(
            f'-d "{dict_path}" -O ""'
            # 表層文字列, 品詞大分類, 中分類, 小分類, 細分類, 
            # 生起コスト, 1つ前の形態素との連接コスト, 累積コスト
            ' --node-format="%m, %f[0], %f[1], %f[2], %f[3], %c, %pC, %pc\n"'
            ' --bos-format="<BOS>, , , , , %c, 0, %pc\n"'
            ' --eos-format="<EOS>, , , , , %c, %pC, %pc"'
        )
    def parse(self, s):
        tokens = self.tagger.parse(s).split('\n')
        return [token.split(', ') for token in tokens]

if __name__ == '__main__':
    parser = MyParser()
    s = 'ヒンメルはもういないじゃない'
    tokens = parser.parse(s)
    for token in tokens:
        print(token)

['<BOS>', '', '', '', '', '0', '0', '0']
['ヒンメル', '名詞', '普通名詞', '一般', '', '5147', '5250', '10397']
['は', '助詞', '係助詞', '', '', '-994', '3123', '12526']
['もう', '副詞', '', '', '', '-1851', '4259', '14934']
['い', '動詞', '非自立可能', '', '', '5709', '2805', '23448']
['ない', '助動詞', '', '', '', '4517', '-8053', '19912']
['じゃ', '助動詞', '', '', '', '1848', '744', '22504']
['ない', '形容詞', '非自立可能', '', '', '2107', '-5702', '18909']
['<EOS>', '', '', '', '', '0', '2568', '21477']
なお、マニュアル [1] (の 1.) にある通り、出力フォーマットは使用している辞書の設定ファイル (例えば C:/Program Files/MeCab/dic/unidic-csj-3.1.1-full/dicrc) に定義することもできる。以下 3 行を追記した上で self.tagger = MeCab.Tagger(f'-d "{dict_path}" -O hoge') とタガーを生成しても同じ結果が得られる。

node-format-hoge = %m, %f[0], %f[1], %f[2], %f[3], %c, %pC, %pc\n
bos-format-hoge = <BOS>, , , , , %c, 0, %pc\n
eos-format-hoge = <EOS>, , , , , %c, %pC, %pc