Naive Bayesの実装

< ---- < | > Naive Bayesの罠 >

================================================

Naive Bayes(NB,ナイーブベイズ)の実装についてメモ。

NBというのはベイズ則に基づく単純な分類器で

lnP(Ci|D) = Σj{lnP(wj|Ci)} + lnP(Ci)

で文書DがクラスCiに属する確率が得られるよ、というもの。(以下、Σiで添字iのすべての場合についての足し合わせを表す)


これを実装する場合、まず手元にデータ集合を用意する。データ集合はクラスラベル(Ci)の付けられた単語(wj)、つまり(Ci,wj)のペアの集まり。例えば

(甘い,りんご) (甘い,りんご) (甘い,りんご)
(甘い,ハチミツ) (甘い,ハチミツ) (甘い,バナナ)
(甘い,砂糖) (甘い,カレー)
(辛い,カレー) (辛い,カレー) (辛い,麻婆豆腐)

これらのデータ集合を用いてNB分類器による確率を計算する。

はじめに。NBではデータ集合にないクラスと単語の組み合わせについても確率が計算できないといけない。これはゼロ頻度問題といって色々大変なのだが今回は問題を単純化したいので全データの頻度を+1ずつするという方法を採用する。つまり(甘い,りんご)の頻度は3ではなく4に、(辛い,りんご)の頻度は0ではなく1にする。

lnP(wj|Ci)はデータ集合から最尤推定によって求める。つまり単語wjのうちクラスCiに属する物の数をクラスCiに属する全単語数で割ったものの対数

ln{count(wj|Ci) / Σj count(wj|Ci)}
= ln{count(wj|Ci)} - ln{Σj count(wj|Ci)}

となる。

例えば

lnP(カレー|甘い) = ln(1+1) - ln(8+6)
lnP(カレー|辛い) = ln(2+1) - ln(3+6)

となる。(前述のゼロ頻度問題に対応して頻度を足した分は明示的に+XXと書いた)

lnP(Ci)もデータ集合からの最尤推定によって求める。つまり全データのうちCiに属するものの数を全データ数で割ったものの対数

ln {Σj count(wj|Ci) / ΣiΣj count(wj|Ci)}
= ln{Σj count(wj|Ci)} - ln{ΣiΣj count(wj|Ci)}

となる。ln{ΣiΣj count(wj|Ci)}はすべてのクラスCiで同じ値なのでクラス分類に寄与しない。よって無視できる。(ので以下Constと書いて定数項扱いする)

例えば

lnP(甘い) = ln(8+6) + Const
lnP(辛い) = ln(3+6) + Const

となる。

以上を用いると文書D={バナナ,カレー}について

lnP(甘い|{バナナ,カレー})
= lnP(カレー|甘い) + lnP(バナナ|甘い) + lnP(甘い)
= {ln(1+1) - ln(8+6)} + {ln(1+1) - ln(8+6)} + {ln(8+6) + Const}
= ln(1+1) + ln(1+1) - (2 - 1) * ln(8+6) + Const
= 0.69 + 0.69 - (2 - 1) * 2.64 + Const
= -1.26 + Const
lnP(辛い|{バナナ,カレー})
= lnP(カレー|辛い) + lnP(バナナ|辛い) + lnP(辛い)
= {ln(2+1) - ln(3+6)} + {ln(0+1) - ln(3+6)} + {ln(3+6) + Const}
= ln(2+1) + ln(0+1) - (2 - 1) * ln(3+6) + Const
= 1.1 + 0 - (2 - 1) * 2.2 + Const
= -1.1 + Const

というわけで

lnP(辛い|{バナナ,カレー}) > lnP(甘い|{バナナ,カレー})

なのでこの文書{バナナ,カレー}は「辛い」クラスであると判定できる。ここでちょっと気になっていることがある。
・・・のだが長くなったので次回に続く。

================================================< ---- < | > Naive Bayesの罠 >