人工知能に関する断創録

このブログでは人工知能のさまざまな分野について調査したことをまとめています(更新停止: 2019年12月31日)

WindowsでMeCab Pythonを使う

日本語の文章を単語に分割するには形態素解析を使います。日本語の形態素解析には、ChaSenMeCabYahoo!形態素解析などがあります。ナイーブベイズを用いたブログ記事の自動分類(2010/7/3)でMeCabPythonから使う方法を簡単にまとめましたが、MeCabはよく使うので再度まとめ直して独立したエントリにしました。Yahoo!形態素解析の使い方は、Yahoo!形態素解析API(2009/4/15)で書きました。

Windowsへの導入方法

MeCabは高性能な形態素解析モジュールでPythonRubyPerlJavaなどさまざまな言語から使えます。Mac OS XLinuxでは簡単にコンパイルしてインストールができるのですが、WindowsではMinGWVisual Studioのインストール、コードの修正が必要でかなり面倒くさい。そこで、Pythonモジュールはid:fgshunさんがコンパイルしたバイナリを使わせてもらいました。以下、導入方法です。

  1. MeCabの本サイトでダウンロードしたWindows版のmecab-0.98.exeをインストール(辞書はUTF-8形式が無難です)
  2. 形態素解析エンジン MeCab 0.98pre3 野良ビルドからダウンロードしたlibmecab-1.dll、MeCab.py、_MeCab.pydをパッケージフォルダ(Python2.6ならC:\Python26\Lib\site-packages)にコピー。IPA辞書はmecab-0.98.exeでインストールしたので不要。id:fgshunさんはTaggerにmecabrcファイルを指定してますが、指定しないとデフォルトでC:\Program Files\MeCab\etc\mecabrcを読みにいくようなのでmecab-0.98.exeでIPA辞書をインストールしたほうが簡単だと思います。下のサンプルプログラムが動くか確かめてみます。

形態素解析

#coding:utf-8
import MeCab
tagger = MeCab.Tagger("-Ochasen")
result = tagger.parse("PythonからMeCabの形態素解析機能を使ってみました。")
print result

parse()の引数に解析したい文字列を入力すると解析結果がテキストで返ってきます。文字列はu""のユニコード文字列でなくていいみたいです。逆にユニコード文字列はstr()で変換しないとダメみたい。上の例の実行結果は下のようになります。ただ、テキストで結果を返されても必要な情報の抽出などその後の処理が面倒です。その場合は、後で紹介するparseToNode()というメソッドが用意されています。

Python	Python	Python	名詞-固有名詞-組織		
から	カラ	から	助詞-格助詞-一般		
MeCab	MeCab	MeCab	名詞-固有名詞-組織		
の	ノ	の	助詞-連体化		
形態素	ケイタイソ	形態素	名詞-一般		
解析	カイセキ	解析	名詞-サ変接続		
機能	キノウ	機能	名詞-サ変接続		
を	ヲ	を	助詞-格助詞-一般		
使っ	ツカッ	使う	動詞-自立	五段・ワ行促音便	連用タ接続
て	テ	て	助詞-接続助詞		
み	ミ	みる	動詞-非自立	一段	連用形
まし	マシ	ます	助動詞	特殊・マス	連用形
た	タ	た	助動詞	特殊・タ	基本形
。	。	。	記号-句点		
EOS

分かち書き

-Ochasenのところを-Owakatiにすると分かち書きの結果が返ってきます

#coding:utf-8
import MeCab
tagger = MeCab.Tagger("-Owakati")
result = tagger.parse("PythonからMeCabの形態素解析機能を使ってみました。")
print result
Python から MeCab の 形態素 解析 機能 を 使っ て み まし た 。 

読み

-Ochasenのところを-Oyomiにすると読みが返ってきます。何に使うのかいまいちピンとこないのですが、音声認識とか音声合成とかかな?

#coding:utf-8
import MeCab
tagger = MeCab.Tagger("-Oyomi")
result = tagger.parse("PythonからMeCabの形態素解析機能を使ってみました。")
print result
PythonカラMeCabノケイタイソカイセキキノウヲツカッテミマシタ。

詳細情報の取得

parse()の代わりにparseToNode()を使うと形態素の詳細情報が得られます。parseToNode()は先頭のノード(形態素情報)を返し、surfaceで表層形、featureで形態素情報を取得できます。両方とも文字列です。featureは , で区切られているのでsplit()などで分割して必要な情報を抽出します。

#coding:utf-8
import MeCab
tagger = MeCab.Tagger("-Ochasen")
node = tagger.parseToNode("PythonからMeCabの形態素解析機能を使ってみました。")
while node:
    print "%s %s" % (node.surface, node.feature)
    node = node.next

実行結果は、

 BOS/EOS,*,*,*,*,*,*,*,*
Python 名詞,固有名詞,組織,*,*,*,*
から 助詞,格助詞,一般,*,*,*,から,カラ,カラ
MeCab 名詞,固有名詞,組織,*,*,*,*
の 助詞,連体化,*,*,*,*,の,ノ,ノ
形態素 名詞,一般,*,*,*,*,形態素,ケイタイソ,ケイタイソ
解析 名詞,サ変接続,*,*,*,*,解析,カイセキ,カイセキ
機能 名詞,サ変接続,*,*,*,*,機能,キノウ,キノー
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
使っ 動詞,自立,*,*,五段・ワ行促音便,連用タ接続,使う,ツカッ,ツカッ
て 助詞,接続助詞,*,*,*,*,て,テ,テ
み 動詞,非自立,*,*,一段,連用形,みる,ミ,ミ
まし 助動詞,*,*,*,特殊・マス,連用形,ます,マシ,マシ
た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
。 記号,句点,*,*,*,*,。,。,。
 BOS/EOS,*,*,*,*,*,*,*,*

最初と最後のBOS/EOSも出力されるみたいです。まあ、無視すればいいですね。featureのフォーマットは、

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

とのこと。発音とか付いてるけど音声合成にも使えるのかな?

文章から名詞のみ抽出

文書分類などでは文書を単語の集合で表すことがよくあります(bag-of-wordsモデル)。このときに使う単語は主に名詞です。助詞、助動詞なんかは文章の内容を表さないので普通除去します。また、動詞、形容詞、形容動詞は目的によっては使いますが普通はあまり使わないと思います。そこで、文章を与えると名詞のリストを返すような関数を作成してみます。

#coding:utf-8
import MeCab

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

if __name__ == "__main__":
    keywords = extractKeyword(u"PythonからMeCabの形態素解析機能を使ってみました。")
    for w in keywords:
        print w,
    print
    keywords = extractKeyword(u"菅直人首相は野党の出方や世論を見極めつつ判断する考えだ。")
    for w in keywords:
        print w,

実行結果は、

Python MeCab 形態素 解析 機能
菅 直人 首相 野党 出方 世論 判断 考え

形態素解析は抽出されるキーワードの粒度がかなり細かいです。もっと大きな粒度で複合語として抽出したいことがよくあります。たとえば、上の例では、「形態素解析」や「菅直人」で1つのキーワードにしてほしいなぁ。この問題に対して、あとで、Wikipediaコーパスを使ったアプローチを試してみます。