Node.js と MongoDB でナイーブベイズによる文書分類をやってみた

タイトルは若干釣りです>< MongoDB は使ってみたかっただけ。

先月から「言語処理のための機械学習入門」を読んでいるので、ナイーブベイズ分類器を書いてみました。

「言語処理のための機械学習入門」はホントに説明が分かりやすい良本だった(数式全然分からなくてそっちの勉強からのスタートになったけど・・)。
あと、Wikipediaも詳しいです。

ナイーブベイズは実装が簡単な割によく働くテキスト分類手法です。
メールを自動でフィルタリングとかよく見かけるブログのこの記事と似ている記事はこちら、みたいなことをやりたいときに使えそうなやつです。
ナイーブベイズの説明はググればいくらでも出てくるのでカット。
事後確率P(cat|doc)を求める方法として、多項ナイーブベイズモデルとベルヌーイモデルの二つがあるようなのですが、ベルヌーイモデルの方はまだ理解できてない><ので、多項ナイーブベイズモデルで分類しました。


ソースは GitHub にアップしてあります。
node-naivebayes-simple at master from waka/node-naivebayes-simple - GitHub


形態素解析には node-mecab-bindingを使わせてもらいました。
ただ、surfaceが上手く取れてなかったのでparseしたものを分解して使っています。
TinySegmenter を使わせてもらおうかとも思ったのですが、品詞の種別でフィルタしたかったので今回は MeCab で。

MongoDBのアダプタはコールバック地獄を味わってみたかったので、Mongo DB Native NodeJS Driveを使いました。
コールバック深くなりすぎてうんざりしたので富豪的形態素たちを保存しています。

非同期で呼ばれるコールバック内で決定した結果カテゴリを呼び出し側で受け取るために、分類器クラスはEventEmitterを継承したものにしています。


こんな感じで使う。

var Train = require('naivebayes-simple').Train;
Train.train(doc, category); // 学習させて保存
var Classifier = require('naivebayes-simple').Classifier;
Classifier.on('classified', function(arg) {// 分類終わったら[分類カテゴリ, 元文書]が返却される
    var bestCategory = arg[0];
    var originalDoc = arg[1];
    console.log(originalDoc + ' => category: ' + bestCategory);
});
Classifier.classify(doc);

試しにこのブログの過去エントリとカテゴリを学習させて、このエントリを推定したら"javascript"って出てちょっと感動した。

全然関係ないところで、mongodbモジュールが読み込めなくて困ったのだけど、npm install -g したモジュールは、プロジェクトのルートディレクトリで「npm ln "module_name"」して読み込みパスに追加しないとダメみたい。


条件付き確率とか高校以来勉強したので正直ヒーヒーなりましたが、何回も読んでいるうちに数学記号に少しずつ慣れてきた気がします。そういうものだっけか。
仕事で分類器をイチから自分で作ることは無さそうだけど、中でどういうことやってるのかが分かると楽しいですね。