#はじめに
前回書いた記事
https://qiita.com/unias_day/items/f041b7c46543f38f78f7
の続きです。
使用環境については、前回の記事を参照してください。
#モジュール
mecab-pythonの出力をリスト化するモジュールを作ってみました。
以下のような感じ。
import MeCab
def mecab_list(text):
tagger = MeCab.Tagger("-Ochasen")
tagger.parse('')
node = tagger.parseToNode(text)
word_class = []
while node:
word = node.surface
wclass = node.feature.split(',')
if wclass[0] != u'BOS/EOS':
if wclass[6] == None:
word_class.append((word,wclass[0],wclass[1],wclass[2],""))
else:
word_class.append((word,wclass[0],wclass[1],wclass[2],wclass[6]))
node = node.next
return word_class
#使い方
>>> import MeCab
>>>
>>> def mecab_list(text):
... tagger = MeCab.Tagger("-Ochasen")
... tagger.parse('')
... node = tagger.parseToNode(text)
... word_class = []
... while node:
... word = node.surface
... wclass = node.feature.split(',')
... if wclass[0] != u'BOS/EOS':
... if wclass[6] == None:
... word_class.append((word,wclass[0],wclass[1],wclass[2],""))
... else:
... word_class.append((word,wclass[0],wclass[1],wclass[2],wclass[6]))
... node = node.next
... return word_class
...
>>> test = mecab_list("なんてこったパンナコッタ")
>>> print(test)
[('なんてこった', '感動詞', '*', '*', 'なんてこった'), ('パンナコッタ', '名詞', '一般', '*', '*')]
こんな感じで使える。
#おおまかな解説
tagger = MeCab.Tagger("-Ochasen")
パーサーの設定。ChaSenという形態素解析器と互換の出力をする設定にしている。
tagger.parse('')
パーサーにデータを渡す前にこれを挟むことで、
UnicodeDecodeErrorを避けることが出来る。
具体的な理由は分かっていないが、
おそらく一度tagger.parse('')を挟むことで、
プログラム内で使用されている標準の文字エンコードで
初期化されるのではないかと思う。
node = tagger.parseToNode(text)
nodeにsurface(単語)feature(品詞情報)を持つ解析結果を代入している。
node.surface/node.featureでそれぞれにアクセス出来る。
wclass = node.feature.split(',')
node.feature部分のデータは
品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用形,活用型,原形,読み,発音
の構造になっている。
”,”で区切られているテキストデータのため
","でsplitし、wclassに配列として代入している。
if wclass[0] != u'BOS/EOS':
品詞部分の結果が'BOS/EOS'の場合というのは
BOS は beginning of sentenceで文頭、もしくは
EOS は end of sentence で文末、ということ。
文単位の解析をする際には、データに入れる必要がある。
今回は文単位を考慮しない場合の処理を書いた。
if wclass[6] == None:
word_class.append((word,wclass[0],wclass[1],wclass[2],""))
else:
word_class.append((word,wclass[0],wclass[1],wclass[2],wclass[6]))
word_classは返り値。
内容は(表層形、品詞、品詞細分類1、品詞細分類2、原形)の形にした。
原形はデータが入っていない場合があるため、ifで分岐処理を書いた。
他に必要なデータがある場合などはwclass[]部を適宜変更してください。
また、データが入ってない問題に対してはsplitの時点で空のテキストデータを入れる処理を書いたほうがスマートな感じはします。(出来る人はそっちでやってみるのもいいかも)