Hatena::ブログ(Diary)

Subspace at Life

2011-04-18

形態素解析エンジンMeCab-pythonを使ってみた.

| 13:52

これから自然言語処理をかじっていこうと思うので,

今回は日本語を単語ごとに分解してくれる「形態素解析エンジン」をPythonで使ってみました.

フリーで使える形態素解析エンジンとしては,

Yahoo!JapanのAPIMeCab(めかぶ)というもの

が一般的らしく,今回はオフラインでも使えるMeCabを利用します.

Windowsにおけるmecab-pythonインストール方法

MeCabの導入はココを参考にさせてもらいました.

具体的には以下の手順で行います.

  1. まずmecab-0.98.exeインストール.(辞書の形式はutf-8を選択)
  2. そしてlibmecab-1.dll、MeCab.py、MeCab.pydをパッケージフォルダにコピーする.

[注]パッケージフォルダはPython2.6ならC:\Python26\Lib\site-packages

テストコード

#coding:utf-8
import MeCab

# ///////////////////////////
# ----- set sentence -----
# ///////////////////////////
test_sentence = 'すもももももももものうち'

# ////////////////////////////////////
# ----- Choose test_number -----
# ////////////////////////////////////
test_num = 1

# ///////////////////////////////
# ----- defined functions -----
# ///////////////////////////////
def test01(s):
    tagger = MeCab.Tagger('-Ochasen')
    result = tagger.parse(s)
    print result
    
def test02(s):
    tagger = MeCab.Tagger('mecabrc')
    result = tagger.parse(s)
    print result

def test03(s):
    tagger = MeCab.Tagger('-Owakati')
    result = tagger.parse(s)
    print result

def test04(s):
    tagger = MeCab.Tagger('-Oyomi')
    result = tagger.parse(s)
    print result
    
def test05(s):
    tagger = MeCab.Tagger('-Ochasen')
    node = tagger.parseToNode(s)
    while node:
        print "%s %s" % (node.surface, node.feature)
        node = node.next    

def main():
    if test_num == 1:
        test01(test_sentence)
    elif test_num == 2:
        test02(test_sentence)
    elif test_num == 3:
        test03(test_sentence)
    elif test_num == 4:
        test04(test_sentence)
    else:
        test05(test_sentence)

if __name__ == "__main__":
    main()

関数test01~04はMeCab.Tagger()の引数

'-Ochasen'(茶筌),'mecabrc'(?),'-Owakati'(分かち書き),'-Oyomi'(読み)

と異なり,それぞれの出力結果は以下のようになっています.

----------

>>test01[MeCab.Tagger()の引数が'-Ochasen'](ChaSen互換モード)

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

>>test02[MeCab.Tagger()の引数が'mecabrc'](後述のtagger.parseToNode()と同じ機能?)

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

>>test03[MeCab.Tagger()の引数が'-Owakati'](単語ごとに分割)

すもも も もも も もも の うち 

>>test04[MeCab.Tagger()の引数が'-Oyomi](漢字の読みでもOK)

スモモモモモモモモノウチ 

----------

また関数test05ではインスタンスtaggerメソッド:.parseToNode(引数)を用いて

MeCab.nodeというクラスを出力しています.この出力フォーマットは

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

であり,表層形はnode.surface,各性質はnode.featureでコンマ区切りのリストとして取得できます.

>>test05

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

文章から特定の品詞を抽出する

またまたココを参考にさせてもらいました.

#coding:utf-8
import MeCab

# /////////////////////
# ----- set text -----
# /////////////////////
test_txt = u'PythonからMeCabの形態素解析機能を使ってみました。'

#  ////////////////////////////////
# ----- category selection -----
#  ////////////////////////////////
class_num = 0
word_classes = [u'名詞',u'動詞',u'形容詞',u'副詞',u'助詞',u'助動詞']
word_class = word_classes[class_num]

# ////////////////////////////////
# ----- defined functions -----
#  ////////////////////////////////

def extractKeyword(text,word_class):
    """textを形態素解析して、名詞のみのリストを返す"""
    tagger = MeCab.Tagger('-Ochasen')
    node = tagger.parseToNode(text.encode('utf-8'))#textがu''形式⇒『.encode()』が必要
    keywords = []
    while node:
        if node.feature.split(",")[0] == word_class:
            keywords.append(node.surface)
        node = node.next
    return keywords

def main():
    keywords = extractKeyword(test_txt)
    for w in keywords:
        print w,

if __name__ == "__main__":
    main()

上記のコードでは'class_num = 0'としているので,名詞

PythonからMeCab形態素解析機能を使ってみました。」から取り出しています.

>>実行結果

Python MeCab 形態素 解析 機能