初心者がナイーブベイズ分類器を作成する為の備忘録
やりたい事
ナイーブベイズ分類器を用いてツイートの内容が修造BOTとイチローBOTのどちらに分類されるかを識別する。
自分用の備忘録として纏めていますので、若干分かりづらい所があると思いますので悪しからず。
間違いがあれば指摘頂けると嬉しいです。
教師データ作成
Bag of Wordsを作成する
Bag of Wordsとは文書から抽出した単語の集合。
訓練用データを読み込んで、mecabで分かち書きし、
[ツイート][単語]の2次元配列を作成する。
こんな感じなる
[ [自分,絶対,駄目,人,全て], [自分,ない,人,目,バット] ]
訓練用データのBag of Wordsから教師データ(モデル)を作成する
教師データ作成では以下の情報を取得する。
P(Ci)=事前確率
教師データ作成の為に利用した全データのうちクラスCiの発生する確率。
各クラスの生起確率とも言う。
今回の識別器で扱うクラスは
それぞれ150件、合計300件を利用しているので事前確率は等しい事となる。
P(C1) = 150 / 300 = 1/2
P(C2) = 150 / 300 = 1/2
識別対象データのクラス識別する
識別対象データの特徴ベクトルを取得
今回の例だと識別対象のツイートから頻出単語上位5件を取得する。
取得した特徴ベクトルを特徴ベクトルxと呼ぶ事とする。
例)
[自分,明日,人,耳,バット]
観測データをベイズの定理に当てはめてそれぞれのクラスの事後確率を求める
P(Ci|x)=p(x|Ci)/p(x) * P(Ci)
以下の様に変形できる
P(x|Ci) * P(Ci)
p(x)とは特徴ベクトルxの生起確率、全てのクラスで共通なので無視できる。
例えば、特徴ベクトルxのC1クラスとC2クラスそれぞれの事後確率を比較する場合、
p(x|C1)/p(x) * P(C1)
と
p(x|C2)/p(x) * P(C2)
を比較する事となるが、p(x)はどちらでも共通の値(全文書で特徴ベクトルxの生起確率)なので無視できる。
なので
P(x|Ci) * P(Ci)
の式に当てはめて事後確率を求める。
P(Ci)=事前確率
訓練時に取得済み。
p(x|Ci)=尤度
特徴ベクトルが連続的なデータ(単語の出現回数)なので、多項分布モデルで分類する。
※単語が出たか出なかったか(0 or 1)のような離散的データならベルヌーイ分布モデル
観測データをx、分類クラスをCi(i=1,...,N)とし、書き直すと
=P(x|Ci)
=クラスCiに分類されたデータxの確率分布
=Ci の中でxが発生する確率(xがCiであることが尤もらしい度合い)。
イチローBOTの例で考えると、
イチローBOTのツイート全ての中で、特徴ベクトル[自分,ない,人,目,バット]が発生する確率。
P(x|Ci) = P( word1, word2, word3, ... | Ci)
と考えられる。
P(word_i | Ci)=単語の条件付き確率
各単語がイチローBOTのツイート全ての中で発生する確率「単語の条件付き確率」を求める。
P( word1, word2, word3, ... | Ci)
=P(word1 | Ci) * P(word2 | Ci) * P(word3 | Ci) ...
=特徴ベクトルxの単語の条件付き確率の積が尤度となる。
※注意
上記の式の変形では単語の出現確率の間に独立性を仮定して同時確率をそれぞれの確率の積で表しているが、
本来、単語の出現に独立性は成り立りたたない。
たとえば、「人工」と「知能」は共起しやすいし、「機械」と「学習」は共起しやすい。
これを無視して単語の出現は独立と無理矢理仮定して文書の確率を単語の確率の積で表して
単純化するのがナイーブベイズのナイーブたる所以。
P(word_i | Ci)=単語の条件付き確率
クラスCiでword_iが出現する確率。
例として、
イチローBOTでword_iが出現した単語数 / (イチローBOTで出現した全ての単語数 + 全文書のユニーク単語数)
クラスの識別
各クラスの事後確率を比較して、最も事後確率が大きいクラスが該当する。
(Map推定)