今回は、
ベイジアンフィルタとは
ベイジアンフィルタとは、
このベイジアンフィルタは、
例えばベイジアンフィルタによるスパム判定では、
ベイジアンフィルタがメールのスパム判定として利用される契機となったのは
先述のようにベイジアンフィルタは、
「教師あり学習」
環境構築
本連載では基本的にプログラミング言語にPythonを使って実装していきます。バージョンは2.
Pythonでは大規模な多次元配列や行列をサポートしている拡張モジュール
また、
bag-of-wordsを利用したテキスト分類
それでは早速、
ナイーブベイズは簡単な計算でよい結果のでる
今回は、
一般的に文章を分類するためには何が必要になるでしょうか。それは文章に含まれている特徴になります。 今回は文章の中に出現する単語を出現する順番を意識せずに特徴として扱います。このように文脈に依存しない、
例えば、
これらは「機械学習」という技術を使って実現されているのです。
この文章ををbag-of-wordsで表現すると、
「これら」、「機械」、「学習」、「技術」、「実現」
文章を形態素に分割する
今回は日本語を含む文章から単語の集合を作るにあたって
英文の場合は単語がスペースによって分割されているため、
形態素解析ライブラリとしてはMeCabやChaSenなどが有名ですが、
また、
# -*- coding: utf-8 -*-
import urllib
import urllib2
from BeautifulSoup import BeautifulSoup
appid = 'Yahoo!デベロッパーズネットワークのアプリケーションIDを入力して下さい'
pageurl = "http://jlp.yahooapis.jp/MAService/V1/parse";
# Yahoo!形態素解析の結果をリストで返します。
def split(sentence, appid=appid, results="ma", filter="1|2|3|4|5|9|10"):
sentence = sentence.encode("utf-8")
params = urllib.urlencode({'appid':appid, 'results':results, 'filter':filter,'sentence':sentence})
results = urllib2.urlopen(pageurl, params)
soup = BeautifulSoup(results.read())
return [w.surface.string for w in soup.ma_result.word_list]
リスト1のコードをmorphological.
引数のfilterで解析する品詞の種類を指定することができます。filterに指定可能な品詞番号は以下のようになっています
1 | 形容詞 |
---|---|
2 | 形容動詞 |
3 | 感動詞 |
4 | 副詞 |
5 | 連体詞 |
6 | 接続詞 |
7 | 接頭辞 |
8 | 接尾辞 |
9 | 名詞 |
10 | 動詞 |
11 | 助詞 |
12 | 助動詞 |
13 | 特殊 |
さらに詳細な利用方法が知りたい方は、
ベイジアンフィルタの実装
ここから本格的にベイジアンフィルタの実装に入っていきます。
その前に、
# -*- coding: utf-8 -*-
import math
import sys
#yahoo!形態素解析
import morphological
def getwords(doc):
words = [s.lower() for s in morphological.split(doc)]
return tuple(w for w in words)
それでは、
具体的には確率値を計算することになるため、
そして、
ナイーブベイズのアルゴリズム
ここで、
ナイーブベイズにおいてのカテゴリの推定とは、
今回は文章
前回と同じように確率の乗法定理を使って展開してみましょう。
P(cat, doc)
= P(cat|doc)P(doc)
= P(doc|cat)P(cat)
第2式と第3式を使うことで、
P(cat|doc) = P(doc|cat)P(cat) / P(doc)
カテゴリの推定では、
では、
次に P(doc|cat) ですが、 文章は分割した単語 P(wordn|cat) の確率は分割した単語があるカテゴリに属する確率 したがって、 アルゴリズム全体の概要を把握したところで、 まずはコンストラクタと訓練フェーズの実装について見てみましょう 続けて、 まずは、 次に、 しかし、 普通に考えて、 今回のように一様な値を加えるスムージングを加算スムージングと呼びます。加算スムージングでは単語の出現回数に一定数の値を加え、 リスト5 単語の条件付き確率を求める しかし、 それに対応するために対数をとり、 あとは、 それでは、 今回、 以下の結果のように、 「オブジェクト指向言語」 今回は訓練データとして各カテゴリに対して1件ずつしか用意していませんが、 今回実装したベイジアンフィルタはとても簡単なものです。ベイジアンフィルタは色々な言語のオープンソースプロジェクトでも開発されているので見比べてみるのも面白いかもしれません。 次回の理論編では正規分布を説明します。P(doc|cat) = P(word1|cat) P(word2|cat) ... P(wordn|cat)
訓練フェーズの実装
class NaiveBayes:
def __init__(self):
self.vocabularies = set() # 単語の集合
self.wordcount = {} # {category : { words : n, ...}}
self.catcount = {} # {category : n}
def wordcountup(self, word, cat):
self.wordcount.setdefault(cat, {})
self.wordcount[cat].setdefault(word, 0)
self.wordcount[cat][word] += 1
self.vocabularies.add(word)
def catcountup(self, cat):
self.catcount.setdefault(cat, 0)
self.catcount[cat] += 1
def train(self, doc, cat):
word = getwords(doc)
for w in word:
self.wordcountup(w, cat)
self.catcountup(cat)
推定フェーズの実装
def priorprob(self, cat):
return float(self.catcount[cat]) / sum(self.catcount.values())
def incategory(self, word, cat):
#あるカテゴリの中に単語が登場した回数を返す
if word in self.
def score(self, word, cat):
score = math.log(self.priorprob(cat))
for w in word:
score += math.log(self.wordprob(w, cat))
return score
カテゴリの推定
def classifier(self, doc):
best = None # 最適なカテゴリ
max = -sys.maxint
word = getwords(doc)
# カテゴリ毎に確率の対数を求める
for cat in self.catcount.keys():
prob = self.score(word, cat)
if prob < max:
max = prob
best = cat
return best
実行してみよう
if __name__ == "__main__":
nb = NaiveBayes()
nb.train(u'''Python(パイソン)は、オランダ人のグイド・ヴァンロッサムが作ったオープンソースのプログラミング言語。
オブジェクト指向スクリプト言語の一種であり、Perlとともに欧米で広く普及している。イギリスのテレビ局 BBC が製作したコメディ番組『空飛ぶモンティパイソン』にちなんで名付けられた。
Python は英語で爬虫類のニシキヘビの意味で、Python言語のマスコットやアイコンとして使われることがある。Pythonは汎用の高水準言語である。プログラマの生産性とコードの信頼性を重視して設計されており、核となるシンタックスおよびセマンティクスは必要最小限に抑えられている反面、利便性の高い大規模な標準ライブラリを備えている。
Unicode による文字列操作をサポートしており、日本語処理も標準で可能である。多くのプラットフォームをサポートしており(動作するプラットフォーム)、また、豊富なドキュメント、豊富なライブラリがあることから、産業界でも利用が増えつつある。''', 'Python')
nb.train(u'''Ruby(ルビー)は、まつもとゆきひろ(通称Matz)により開発されたオブジェクト指向スクリプト言語であり、従来 Perlなどのスクリプト言語が用いられてきた領域でのオブジェクト指向プログラミングを実現する。Rubyは当初1993年2月24日に生まれ、 1995年12月にfj上で発表された。名称のRubyは、プログラミング言語Perlが6月の誕生石であるPearl(真珠)と同じ発音をすることから、まつもとの同僚の誕生石(7月)のルビーを取って名付けられた。''', 'Ruby')
nb.train(u'''豊富な機械学習(きかいがくしゅう、Machine learning)とは、人工知能における研究課題の一つで、人間が自然に行っている学習能力と同様の機能をコンピュータで実現させるための技術・手法のことである。ある程度の数のサンプルデータ集合を対象に解析を行い、そのデータから有用な規則、ルール、知識表現、判断基準などを抽出する。データ集合を解析するため、統計学との関連も非常に深い。
機械学習は検索エンジン、医療診断、スパムメールの検出、金融市場の予測、DNA配列の分類、音声認識や文字認識などのパターン認識、ゲーム戦略、ロボット、など幅広い分野で用いられている。応用分野の特性に応じて学習手法も適切に選択する必要があり、様々な手法が提案されている。それらの手法は、 Machine Learning や IEEE Transactions on Pattern Analysis and Machine Intelligence などの学術雑誌などで発表されることが多い。''', u'機械学習')
#Python
words = u'ヴァンロッサム氏によって開発されました.'
print u'%s => 推定カテゴリ: %s' % (words ,nb.classifier(words))
words = u'豊富なドキュメントや豊富なライブラリがあります.'
print u'%s => 推定カテゴリ: %s' % (words ,nb.classifier(words))
#Ruby
words = u'純粋なオブジェクト指向言語です.'
print u'%s => 推定カテゴリ: %s' % (words ,nb.classifier(words))
words = u'Rubyはまつもとゆきひろ氏(通称Matz)により開発されました.'
print u'%s => 推定カテゴリ: %s' % (words ,nb.classifier(words))
#機械学習
words = u'「機械学習 はじめよう」が始まりました.'
print u'%s => 推定カテゴリ: %s' % (words ,nb.classifier(words))
words = u'検索エンジンや画像認識に利用されています.'
print u'%s => 推定カテゴリ: %s' % (words , nb.classifier(words))
% python naivebayes.py
ヴァンロッサム氏によって開発されました. => 推定カテゴリ: Python
豊富なドキュメントや豊富なライブラリがあります. => 推定カテゴリ: Python
純粋なオブジェクト指向言語です. => 推定カテゴリ: Ruby
Rubyはまつもとゆきひろ氏(通称Matz)により開発されました. => 推定カテゴリ: Ruby
「機械学習 はじめよう」が始まりました. => 推定カテゴリ: 機械学習
検索エンジンや画像認識に利用されています. => 推定カテゴリ: 機械学習
次回のお知らせ