【Python】MeCabで形態素解析してみる - 加賀百万石ですが何か?

【Python】MeCabで形態素解析してみる

MeCabとは

まずはMeCabとは何かを簡単に書いておきます。使い方だけ見たいという方は下に行ってください。

MeCabは形態素解析をするためのOSSのひとつです。形態素解析は自然言語処理の分野でよく使われる手法のことですが,文章を最小単位の単語に分割するもののことを言います。

例えばこんな文章があったとします。

これはMeCabで形態素解析するための例文です。

これを形態素解析して最小単位の単語に分割するとこうなります。

これ ['名詞', '代名詞', '一般', '*', '*', '*', 'これ', 'コレ', 'コレ']
は ['助詞', '係助詞', '*', '*', '*', '*', 'は', 'ハ', 'ワ']
MeCab ['名詞', '一般', '*', '*', '*', '*', '*']
で ['助詞', '格助詞', '一般', '*', '*', '*', 'で', 'デ', 'デ']
形態素 ['名詞', '一般', '*', '*', '*', '*', '形態素', 'ケイタイソ', 'ケイタイソ']
解析 ['名詞', 'サ変接続', '*', '*', '*', '*', '解析', 'カイセキ', 'カイセキ']
する ['動詞', '自立', '*', '*', 'サ変・スル', '基本形', 'する', 'スル', 'スル']
ため ['名詞', '非自立', '副詞可能', '*', '*', '*', 'ため', 'タメ', 'タメ']
の ['助詞', '連体化', '*', '*', '*', '*', 'の', 'ノ', 'ノ']
例文 ['名詞', '一般', '*', '*', '*', '*', '例文', 'レイブン', 'レイブン']
です ['助動詞', '*', '*', '*', '特殊・デス', '基本形', 'です', 'デス', 'デス']
。 ['記号', '句点', '*', '*', '*', '*', '。', '。', '。']

何となくイメージはつかめましたでしょうか。

MeCabを使ってみる

ではさっそくMeCabで形態素解析をしてみましょう。

インストール方法については,巷に色々情報がありますので適当にググってインストールしてみて下さい。

Windowsだと少し面倒だった覚えがあるのですが,だいたいこの辺を見ればインストールできたような気がします。

では早速ですが,以下がサンプルコードです。

import MeCab

# 形態素解析したい文
text = 'これはMeCabで形態素解析するための例文です。'

# パースする
tagger = MeCab.Tagger()
tagger.parse('') # エラー回避のために空文字を一度パースする・・・※注釈①
node = tagger.parseToNode()

# 形態素を順に処理
while node:

    if node.surface == '': # 空文字は BOS もしくは EOS の意味・・・※注釈②
        node = node.next
        continue

    """
    自由に処理する
    """
    print(node.surface, node.feature.split(','))

    # 次の形態素へ
    node = node.next

注釈①部分ですが,もし空文字を先に一度パースしていなかったら,たまにエラーが出ることがあります。原因はMeCabのバグらしいのですが,とりあえず一度空文字をパースしておけば回避できるので,もしエラーが出るようでしたらこの1行を入れておいて下さい。

また,注釈②部分ですが,BOS(Beginning Of Sentence)とEOS(End Of Sentence)は空文字が入ることになっています。形態素解析した結果だけ欲しい場合は,この空文字は特に使いませんのでスキップします。

node.featureには品詞名とか読みの情報が入っているので,必要に応じて取り出して自由に使いましょう。

以上,MeCabの使い方でした。

あとは個人的な好みの問題ですが,こんな感じでgeneratorにしておくと使いやすかなーと思いますので,その例も載せておきます。

import MeCab

def morpheme_generator(text):
    tagger = MeCab.Tagger()
    tagger.parse('')
    node = tagger.parseToNode(text)

    while node:
        if node.surface == '':
            node = node.next
            continue

        yield node.surface, node.feature.split(',')
        node = node.next

if __name__ == '__main__':
    text = 'これはMeCabで形態素解析するための例文です。'
    morphemes = morpheme_generator(text)

    for morpheme, features in morphemes:
        print(morpheme, '\t', features)

テキストを渡すと,形態素に分割するgeneratorを返す関数を作っておくと便利です。

スポンサーリンク