MeCabとNLTKを使って最瀕語と共起関係を出力する
MecabとNLTKを使って最瀕語と共起関係を出力するコードを書きました。
Mecabのインストールについては、Windowsなら結構難なく行くようですが、Mac OSX Lionだととても躓きました。
その辺りの経緯は、mecab-pythonをMac OSX 10.7 Lion、Python2.7にインストールする - Men talking over coffee with smoking Ark Royal.を参考にしてください。
まず、このMeCabで形態素解析を行うコードですが、以前、『入門ソーシャルデータ』勉強会で、Kenji Koshikawa (Kshi_Kshi)さんに頂いた、mecab_library.pyを元にしています(元のリンクが見つけられませんでした、申し訳ございません)。
mecab_library.py
# -*- coding: utf-8 -*- import MeCab mecab = MeCab.Tagger('-Ochasen') class Tokens(object): """textの形態素情報を保持""" def __init__(self, text): self.text = text #print mecab.parse(text) node = mecab.parseToNode(text) self.tokens = [] while node: self.tokens.append(Token(node.surface, *node.feature.split(','))) node = node.next class Token(object): """形態素情報""" def __init__(self, surface, *args): # Mecab Format # 表層形\t品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用形,活用型,原形,読み,発音 self.surface = surface # 表層形 try: self.pos = args[0] # 品詞 self.pos_detail1 = args[1] # 品詞細分類^Z1 self.pos_detail2 = args[2] # 品詞細分類^Z2 self.pos_detail3 = args[3] # 品詞細分類^Z3 self.verb_form = args[4] # 活用形 self.verb_type = args[5] # 活用型 self.basic = args[6] # 原型 self.reading = args[7] # 読み self.pronunciation = args[8] # 発音 self.type = True # 全ての要素が格納できたとき except IndexError: self.type = False # 全ての要素が格納できなかったとき
このmecab_library.pyを用いて、tokenize(text, pos_list=["名詞","動詞"])という関数を作りました。ストップワーズは適宜編集してください。
mecab_tokenizer.py
# -*- coding: utf-8 -*- import mecab_library import pickle # tweets = pickle.load(open("cluster2_tweets.pickle","r")) def splitStr(str, num): l = [] for i in range(num): l.append(str[i::num]) l = ["".join(i) for i in zip(*l)] rem = len(str) % num # zip で捨てられた余り if rem: l.append(str[-rem:]) return l # pos: 名詞, 動詞, 形容詞, 副詞, 助詞, 接続詞, 助動詞, 連体詞, 感動詞, * def classifyPos(words, pos_list=["名詞", "動詞"]): stop_words = ["@","RT","bit","ly","goo","gl","こと","もの","好き"] texts = [] for token in words.tokens: if unicode(token.surface, 'utf-8') in stop_words: continue elif len(unicode(token.surface, 'utf-8')) == 1: continue # 1文字はスルー elif token.pos in pos_list: if token.basic == "*": texts.append(token.surface) else: texts.append(token.surface) return texts def tokenize(text, pos_list=["名詞","動詞"]): sent = text.encode('utf-8') if len(sent) > 2000000: sents = splitStr(sent, 2000000) words = mecab_library.Tokens(sents[0]) texts = classifyPos(words, pos_list) for i in range(1,len(sents)): w = mecab_library.Tokens(sents[i]) texts += classifyPos(w) print len(texts) return texts else: words = mecab_library.Tokens(sent) texts = classifyPos(words) return texts
そして、これらを元にNLTKを用いて、最瀕語と共起関係を出力する関数が以下のものです。引数には、unicode型のstrと、閾値頻度を取ります。(共起と最瀕語で閾値を変えたいときは適宜変更してください)
# -*- coding: utf-8 -*- import nltk import mecab_tokenizer # 共起と最頻語を出力する def collocations_and_freq_words(text, freq=25): tokens = mecab_tokenizer.tokenize(text) corpus = nltk.Text(tokens) print u"-----最頻語(頻度%d回以上)-----" % freq fdist1 = nltk.FreqDist(tokens) saihin1 = fdist1.keys() for voc in saihin1: if fdist1[voc] >= freq: print "%s\t%s" % (voc, fdist1[voc]) print u"" print u"-----共起関係(共起頻度%d回以上)-----" % freq bigrams = nltk.bigrams(corpus) cfd = nltk.ConditionalFreqDist(bigrams) kyouki = cfd.keys() for voc in kouki: for (key, value) in list(cfd[voc].viewitems()): if value >= freq: print "%s\t%s\t%s" % (voc, key, value)
NLTKすごい!ということで。
- 作者: Steven Bird,Ewan Klein,Edward Loper,萩原正人,中山敬広,水野貴明
- 出版社/メーカー: オライリージャパン
- 発売日: 2010/11/11
- メディア: 大型本
- 購入: 20人 クリック: 639回
- この商品を含むブログ (44件) を見る