やぐブロ

yag + programming + hateblo

Clojureでナイーブベイズ分類器(多項モデル)

前回(Clojureでナイーブベイズ分類器(多変数ベルヌーイモデル) - やぐブロ)に続いて,多項モデルを用いたナイーブベイズ分類器を実装してみた.今回は言語処理のための機械学習入門 (自然言語処理シリーズ)のP.114 例題4.6を解いている.といっても.多変数ベルヌーイモデルと同様に\arg \max_c p(c) p(d|c)を最大にするp(c)およびp(d|c)は閉形式で求まるので,実際には訓練データ内の文字数を数えて掛け合わせるだけなのだが.



スクリプトは前回の多変数ベルヌーイモデルのものを使い回している.主な変更点としては,

  • count-wordsetで文章数ではなく単語数を数えるようにしてある
  • mm-MLestimateを少し変更(文章の単語ぶんだけq_{w,c}を掛け合わせる)
(def text_classified_p '(["good" "bad" "good" "good"]
                            ["exciting" "exciting"]
                            ["good" "good" "exciting" "boring"]))
(def text_classified_n '(["bad" "boring" "boring" "boring"]
                           ["bad" "good" "bad"]
                           ["bad" "bad" "boring" "exciting"]))

(defn train [features]
    (reduce (fn [model f] (assoc model f (inc (get model f 0)))) {} features))
(defn count-wordset [training-data]
  (apply merge-with + (map train training-data)))
(defn mm-MLestimate [documents datasets]
  (* (/ (count datasets) (count (concat text_classified_p text_classified_n)))
     (apply * (map #(/ % (count (reduce concat datasets)))
                   (map #(get (count-wordset datasets) %) documents)))))

(defn classify [d]
  (sorted-map-by >
                 (mm-MLestimate d text_classified_p) :positive
                 (mm-MLestimate d text_classified_n) :negative))

実際に分類器を動かしてみると,

> (classify ["good" "good" "bad" "boring"]) 
{1/800 :positive, 10/14641 :negative}

といったカタチで求まる.


前回と今回で多変数ベルヌーイモデル・多項モデルを用いたナイーブベイズ分類器を作成したが,実装に用いた閉形式のパラメータは最尤推定で求められたものである.他にもMAP推定を用いて加算スムージングすることにより生起回数を調節することができるが,実装レベルでは生起回数の部分に+n(nはディリクレ分布のαに依存する)するだけなので,今回は取り上げないことにする.

言語処理のための機械学習入門 (自然言語処理シリーズ)

言語処理のための機械学習入門 (自然言語処理シリーズ)