Pythonでベイジアンフィルターを実装してみた
Web+DB Vol56でPerlでかかれていた、ベイジアンフィルターをPythonで実装してみました。
ほぼ、本に忠実に実装しています。
恒例によって、結果の保存とかはしてません。
#!/usr/bin/env python # -*- coding: utf-8 -*- import MeCab import math class Bayesian(object): term_count = {} cat_count = {} def __init__(self): pass def MecabSpliter(self, text): m = MeCab.Tagger("-Ochasen") n = m.parseToNode(text.encode('utf-8')) words = {} while n.next is not None: if n.posid == 1 or n.posid == 2 or n.posid == 3 or n.posid == 4 or n .posid == 5: words.setdefault(n.surface.lower(), 0) words[n.surface.lower()] += 1 n = n.next return words def text2vec(self, text, spliter=None): if spliter is None: return self.MecabSpliter(text) else: return spliter(text) def train(self, wv, cat): for term, cnt in wv.iteritems(): print term, cnt if not self.term_count.has_key(term): self.term_count[term] = {} if term in self.term_count[term]: self.term_count[term][cat] += cnt else: self.term_count[term][cat] = cnt if term in self.cat_count: self.cat_count[cat] += 1 else: self.cat_count[cat] = 1 def catProb(self, cat): total = 0 for k in self.cat_count: total += self.cat_count[k] return 1.0 * self.cat_count[cat] / total def termCnt(self, term, cat): if term in self.term_count: if cat in self.term_count[term]: return self.term_count[term][cat] else: return 0 else: return 0 def termProb(self, term, cat): return self.termCnt(term, cat) / self.cat_count[cat] def predict(self, vec): scores = {} for cat in self.cat_count: scores[cat] = self.score(vec, cat) return scores def score(self, vec, cat): print "tt", self.catProb(cat) cat_prob = math.log(self.catProb(cat) * 1.0) not_likely = 1.0 / (self.total_term_count() * 10) doc_prob = 0 for term, count in vec.items(): print term, count doc_prob += math.log(self.termProb(term, cat) or not_likely) * count return cat_prob + doc_prob def total_term_count(self): cnt = 0 for k in self.cat_count: cnt += self.cat_count[k] return cnt if __name__ == '__main__': filter = Bayesian() words = filter.text2vec(u'PerlやPythonはスクリプト言語です', filter.MecabSpl iter) filter.train(words, "it") words = filter.text2vec(u'Perlでベイジアンフィルタを作りました。') filter.train(words, "it") words = filter.text2vec(u'pythonはニシキヘビ科の総称です。') filter.train(words, "science") words = filter.text2vec(u'Perlは楽しい') porb = filter.predict(words) print porb words = filter.text2vec(u'PythonとPerl') porb = filter.predict(words) print porb words = filter.text2vec(u'pythonはヘビ') porb = filter.predict(words) print porb
あと、雑誌に書いてあるとおりに設定されたMeCabが必要です。
apt-getで入れたものを使う場合、多少変更が必要です。
- 作者: 赤松祐希,紀平拓男,牧大輔,西林孝,中島聡,中島拓,角田直行,はまちや2,舘野祐一,きしだなおき,和田裕介,伊藤直也,大沢和宏,塙与志夫,増井俊之,ミック,WEB+DB PRESS編集部
- 出版社/メーカー: 技術評論社
- 発売日: 2010/04/24
- メディア: 大型本
- 購入: 14人 クリック: 180回
- この商品を含むブログ (40件) を見る