形態素解析について
様々なユーザーの Tweet を収集して利用するパターンで最も多いのは、
Tweet 中に含まれる特定の単語を抽出して利用するパターンである。
今回は形態素解析器の MeCab を利用して、単語単位に分割して名詞、動詞、形容詞を抽出する。
- Python で Twitter からの情報収集 (環境構築編)
- 環境構築等はこちら
MeCabの出力形式
出力形式はオプションにより変わる。
- 'mecabrc': (デフォルト)
- '-Ochasen': (ChaSen 互換形式)
- '-Owakati': (分かち書きのみを出力)
- '-Oyomi': (読みのみを出力)
デフォルトだと
表層形\t品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用形,活用型,原形,読み,発音
という出力になる。
サンプルコード
ある文を単語単位(表層形そのまま)に分割して、
- 全単語
- 名詞のみ
- 動詞のみ
- 形容詞のみ
の4通りを取り出すプログラム。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import MeCab
### Constants
MECAB_MODE = 'mecabrc'
PARSE_TEXT_ENCODING = 'utf-8'
### Functions
def main():
sample_u = u"ライ麦畑のつかまえ役、そういったものに僕はなりたいんだよ。馬鹿げてることは知ってるよ。でも、ほんとうになりたいものといったらそれしかないね。"
words_dict = parse(sample_u)
print "All:", ",".join(words_dict['all'])
print "Nouns:", ",".join(words_dict['nouns'])
print "Verbs:", ",".join(words_dict['verbs'])
print "Adjs:", ",".join(words_dict['adjs'])
return
def parse(unicode_string):
tagger = MeCab.Tagger(MECAB_MODE)
# str 型じゃないと動作がおかしくなるので str 型に変換
text = unicode_string.encode(PARSE_TEXT_ENCODING)
node = tagger.parseToNode(text)
words = []
nouns = []
verbs = []
adjs = []
while node:
pos = node.feature.split(",")[0]
# unicode 型に戻す
word = node.surface.decode("utf-8")
if pos == "名詞":
nouns.append(word)
elif pos == "動詞":
verbs.append(word)
elif pos == "形容詞":
adjs.append(word)
words.append(word)
node = node.next
parsed_words_dict = {
"all": words[1:-1], # 最初と最後には空文字列が入るので除去
"nouns": nouns,
"verbs": verbs,
"adjs": adjs
}
return parsed_words_dict
### Execute
if __name__ == "__main__":
main()
出力結果
(twi-py)$ python tweet_parser.py
All: ライ麦,畑,の,つかまえ,役,、,そういった,もの,に,僕,は,なり,たい,ん,だ,よ,。,馬鹿げ,てる,こと,は,知っ,てる,よ,。,でも,、,ほんとう,に,なり,たい,もの,と,いっ,たら,それ,しか,ない,ね,。
Nouns: ライ麦,畑,役,もの,僕,ん,こと,ほんとう,もの,それ
Verbs: つかまえ,なり,馬鹿げ,てる,知っ,てる,なり,いっ
Adjs: ない
最後に
これで parse() に取得した Tweet を食わせれば、単語の抽出ができる。
今回のサンプルコードは node.surface に入っている表層形の方を使ったが、
動詞などの語尾が変化する語を正規化したいなら、
node.feature の方に入っている原形の方を使えばよい。