こんにちは、@Yoshimiです。
今回は、PythonでMeCabを利用する方法を紹介していきます。自然言語処理には欠かせないオープンソースの形態素解析エンジンです。利用するだけであれば難しくないのでチャレンジしてみてくださいね。
目次
形態素解析とは
MeCabを利用する前に「形態素解析」を知っておきましょう。形態素解析とは、簡単に行ってしまえば自然言語を単語(名詞、動詞、助詞、接続詞などなど・・・)に分割する作業です。
Pythonにおいて、形態素解析をする際のモジュール、ライブラリはJanome、Juman、kuromoji、そしてMeCabなど複数存在し特徴も異なります。
すもももももももものうち
MeCabといえば「すもももももももものうち」ですね。チュートリアル的に見かけます。右にならって確認してみます。
まずは、Python上でmecabを動かせるようにします。mecabをインストールします。jupyter notebooksを使っている場合は、以下の通りです。
!pip install mecab-python3
デフォルトでMeCabを使用するのは以下の通りで、非常に簡単です。
import MeCab mecab = MeCab.Tagger("-Ochasen") print(mecab.parse("すもももももももものうち"))
も モ も 助詞-係助詞
もも モモ もも 名詞-一般
も モ も 助詞-係助詞
もも モモ もも 名詞-一般
の ノ の 助詞-連体化
うち ウチ うち 名詞-非自立-副詞可能
EOS
EOSは文の終わりということです。
どうでしょうか?確認できましたか?サクッと終わりましたよね。
「すもももももももものうち」ではちょっとつまらなかったですね。
-Ochasen
はmecabのオプションで出力モードになります。
- mecabrc:デフォルト
- -Ochasen:ChaSen互換
- -Owakati:分かち書きのみ
- -Oyomi:読みのみ(振り仮名)
- -Odump:単語の全情報
では、もう少し文章を複雑にしてみて、オプションを使って検証してみます。
各種オプションで検証する
各オプションの検証も大切ですが、まずは土台となるテキストをデフォルト状態で確認してみます。
デフォルト
# デフォルト import MeCab text = '私はラーメンが大好物です。' mecab = MeCab.Tagger() me = mecab.parse(text) print(text) print('----------') print(me)
———-
私 名詞,代名詞,一般,*,*,*,私,ワタシ,ワタシ
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
ラーメン 名詞,一般,*,*,*,*,ラーメン,ラーメン,ラーメン
が 助詞,格助詞,一般,*,*,*,が,ガ,ガ
大 接頭詞,名詞接続,*,*,*,*,大,ダイ,ダイ
好物 名詞,一般,*,*,*,*,好物,コウブツ,コーブツ
です 助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
。 記号,句点,*,*,*,*,。,。,。
EOS
分かち書き
分かち書きとは、文章の単語を空白で区切ることです。英文であれば空白があり、わかりやすいのですが、日本語は句読点であったり、ひらがな感じカタカナなどもうごっちゃですから、区切ってくれるのは非常にありがたいです。
# 分かち書き import MeCab text = '私はラーメンが大好物です。' mecab = MeCab.Tagger('-Owakati') me = mecab.parse(text) print(text) print('----------') print(me)
———-
私 は ラーメン が 大 好物 です 。
振り仮名
文字に対しての読み仮名を返してくれます。(今のところ私は使ったことがありません。)
# 振り仮名 text = '私はラーメンが大好物です。' mecab = MeCab.Tagger('-Oyomi') me = mecab.parse(text) print(text) print('----------') print(me)
———-
ワタシハラーメンガダイコウブツデス。
ChaSen(茶筌)
入力文を単語単位に分割し品詞を付与するツールです。1番多く目にする機会があるかもしれません。
# ChaSen(茶筌)オプション text = '私はラーメンが大好物です。' mecab = MeCab.Tagger('-Ochasen') me = mecab.parse(text) print(text) print('----------') print(me)
———-
私 ワタシ 私 名詞-代名詞-一般
は ハ は 助詞-係助詞
ラーメン ラーメン ラーメン 名詞-一般
が ガ が 助詞-格助詞-一般
大 ダイ 大 接頭詞-名詞接続
好物 コウブツ 好物 名詞-一般
です デス です 助動詞 特殊・デス 基本形
。 。 。 記号-句点
EOS
単語の全情報
まさに全て出力されます。文章も短い場合はよいですが、文章が長い解析を行う場合は、表示させることは控えましょう。
# 単語の全情報を出力する text = '私はラーメンが大好物です。' mecab = MeCab.Tagger('-Odump') me = mecab.parse(text) print(text) print('----------') print(me)
2 私 名詞,代名詞,一般,*,*,*,私,ワタシ,ワタシ 0 3 1306 1306 59 2 0 1 0.000000 0.000000 0.000000 2737
4 は 助詞,係助詞,*,*,*,*,は,ハ,ワ 3 6 261 261 16 6 0 1 0.000000 0.000000 0.000000 3163
8 ラーメン 名詞,一般,*,*,*,*,ラーメン,ラーメン,ラーメン 6 18 1285 1285 38 7 0 1 0.000000 0.000000 0.000000 6918
65 が 助詞,格助詞,一般,*,*,*,が,ガ,ガ 18 21 148 148 13 6 0 1 0.000000 0.000000 0.000000 6063
75 大 接頭詞,名詞接続,*,*,*,*,大,ダイ,ダイ 21 24 560 560 30 2 0 1 0.000000 0.000000 0.000000 11098
83 好物 名詞,一般,*,*,*,*,好物,コウブツ,コーブツ 24 30 1285 1285 38 2 0 1 0.000000 0.000000 0.000000 13405
98 です 助動詞,*,*,*,特殊・デス,基本形,です,デス,デス 30 36 460 460 25 6 0 1 0.000000 0.000000 0.000000 14718
106 。 記号,句点,*,*,*,*,。,。,。 36 39 8 8 7 3 0 1 0.000000 0.000000 0.000000 11328
108 EOS BOS/EOS,*,*,*,*,*,*,*,* 39 39 0 0 0 0 3 1 0.000000 0.000000 0.000000 9792
追加辞書(mecab-ipadic-neologd)の導入
初期の辞書状態では登録後が少ないので、精度もよくないかもしれません。自然言語には「辞書」というものがあり、単語の登録などされていくため、新語が追加されていけば、思っていたような形態素解析ができる可能性もアップします。
MeCabで使える辞書でメジャーなものを簡単に紹介します。
- mecab-ipadic-neologd:固有表現や新語を取り込み続けている
- IPA辞書:Word2Vec などの学習済みモデルの分割単位であることが多い
- Juman辞書:代表表記は表記揺れ解消のための機能
- UniDic辞書:漢語・和語情報や語彙素など情報が豊富
PythonのMeCabといえば「mecab-ipadic-neologd」ですかね。
mecab = MeCab.Tagger('-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd')
形態素の解析
parseメソッド以上に柔軟い処理が行えるparseToNodeメソッドというのがあります。形態素解析した結果でデータ処理を行いたい場合には、parseToNodeメソッドを使います。(と私は思っています。)
parseToNodeメソッドは、例えば名詞だけを抽出したり、品詞ごとに出現数をカウントしたりする場合に便利です。
import MeCab text = '私はラーメンが大好物です。' mecab = MeCab.Tagger() par = mecab.parseToNode(text) print(text) print('----------') print(type(par)) while par: print(par.surface) # 形態素の出力 print(par.feature) #品詞などの出力 """ 次の単語へ """ par = par.next
———-
BOS/EOS,*,*,*,*,*,*,*,*
私
名詞,代名詞,一般,*,*,*,私,ワタシ,ワタシ
は
助詞,係助詞,*,*,*,*,は,ハ,ワ
ラーメン
名詞,一般,*,*,*,*,ラーメン,ラーメン,ラーメン
が
助詞,格助詞,一般,*,*,*,が,ガ,ガ
大
接頭詞,名詞接続,*,*,*,*,大,ダイ,ダイ
好物
名詞,一般,*,*,*,*,好物,コウブツ,コーブツ
です
助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
。
記号,句点,*,*,*,*,。,。,。
BOS/EOS,*,*,*,*,*,*,*,*
形態素の出力では「surface」とし、品詞などの出力には「feature」とすることで必要な情報を細かく取得することができます。
whileループの末尾に「next」というメソッドを変数に格納(par = par.next
)していますが、これは次の処理を実行させるために必要なメソッドです。
この応用で「名詞だけを抽出する」「形容詞だけを抽出する」なども可能になります。
品詞の数
今度は大量テキストを読み込んで確認してみましょう。
福澤諭吉の「学問のすゝめ」の一部(約20,000文字のテキスト)を形態素解析してみます。
import MeCab me = MeCab.Tagger ("-Ochasen") text = open('susume.txt', 'r') txt_data = text.read() print(me.parse (txt_data))
の ノ の 助詞-連体化
すすめ ススメ すすめ 名詞-一般
福沢 フクサワ 福沢 名詞-固有名詞-人名-姓
諭吉 ユキチ 諭吉 名詞-固有名詞-人名-名
+ + + 名詞-サ変接続
目次 モクジ 目次 名詞-一般
初 ハツ 初 名詞-接尾-一般
編 ヘン 編 名詞-接尾-一般
「 「 「 記号-括弧開
天 テン 天 名詞-一般
は ハ は 助詞-係助詞
人 ヒト 人 名詞-一般
の ノ の 助詞-連体化
上 ウエ 上 名詞-非自立-副詞可能
・
・
・
・
実際には、もっと多くの形態素に分かれています。
文章が多いと気になるのが品詞です。品詞とは単語を形態と職能によって分類した種別のことです。形態素解析は単語に分割すると冒頭で紹介しましたが、実は品詞のことなのです。
品詞をカウントしてみます。parseToNodeメソッドを使用します。
# coding: utf-8 import MeCab mecabTagger = MeCab.Tagger("-Ochasen") node = mecabTagger.parseToNode(txt_data) hcount = {} while node: hinshi = node.feature.split(",")[0] if hinshi in hcount.keys(): freq = hcount[hinshi] hcount[hinshi] = freq + 1 else: hcount[hinshi] = 1 node = node.next for key,value in hcount.items(): print(key+":"+str(value))
名詞:4283
助詞:3732
記号:1234
動詞:1809
助動詞:885
連体詞:294
副詞:331
接頭詞:103
形容詞:221
接続詞:200
フィラー:2
感動詞:1
多くの品詞があることがわかりましたね。
最後に
mecabで出力される結果はリストのように見えますが、単なる文字の塊です。なので、ここからリストに格納したり、グループ分けしたり、処理が必要になります。
自然言語処理では、形態素解析、構文解析、意味解析、文脈解析と段階があります。まずその土台作りがこのMeCabなどで処理されています。まずは分割するところからなのですが、変な分割のされ方もあるわけです。そこを変な分割にされないようにするのが非常に難しいのですが、エンジニアの力の見せ所です。
まだまだ精進です。
参考:
MeCabのコマンドライン引数一覧とその実行例
Mecabで形態素解析:品詞分解する方法【Python】
MeCab: Yet Another Part-of-Speech and Morphological Analyzer