いかにたいしとことをやってないかって話
「ベイズフィルタって難しいんじゃね?」と思ってる人へ。
環境を作るのは、JARがなかったりビルドエラーが出たり結構面倒です(難しいっていよりだるい)。しかし、APIをつかうだけならとても簡単です。
参考にした元ネタのサイトはこちら
Java版ベイズ実装 ci-bayes を試す
http://diary.voq.jp/archives/8
//ベイズのエンジンを作ります。
FisherClassifier fc=new FisherClassifierImpl();
//文章を与えてトレーニングします。
//Popfileの「このメールはXXXバケツへ」と同じノリです。
fc.train("The quick brown fox jumps over the lazy dog's tail","good");
fc.train("Make money fast!", "bad");
//こちらが判定用のメソッドです。
String classification=fc.getClassification("money", null);
System.out.println(classification);
ぶっちゃけ、コアとなる部分はこれだけ。本当にこれだけです。
後、作りこまなければならない重要な点としては、
- FisherClassifierImplに与えるWordLister (パーサです)の実装
となります。日本語の場合は、Java版ベイズ実装 ci-bayes を試すを見てください。
今回、私は、はてブをパースするのが目的となりますので、はてブを現すBEANを定義し、それをパースする形にしました。
/** * 1ブックマークURLに対応するBEAN */ public class BookMarkInfo implements Serializable { /** * ブックマーク対象のURL */ public String link; /** * ブックマーク対象のHTMLのタイトル */ public String title; /** * はてぶの詳細ページ * 例:http://b.hatena.ne.jp/entry/http://techtalk.jp/ */ public String ditailLink; /** * はてぶの詳細ページ(ユーザ数が多い場合のみ出現) */ public String moreLink; /** * 一人、一人のブックマークを現すデータのセット */ public SortedSet<BookMarkDitailOneUserInfo> set = new TreeSet<BookMarkDitailOneUserInfo>( new BookMarkDitailOneUserInfo.DateComparator()); } /** * 1ユーザがブックマークしたことを示すBean。 * 「誰が =user」「いつ =date」ブックマークしたかを保持。 * 将来的には、あるユーザの「これはすごい」タグは参考になる * とか解析したいのでBean化してる。 */ public class BookMarkDitailOneUserInfo implements Serializable { public String user; public String dateStr; public Date date; } /** * ハテナ用の分析用のパーサー * FisherClassifier fc = new FisherClassifierImpl(new HatenaWordLister()); * 上記みたいな使い方をする。 */ public class HatenaWordLister implements WordLister, Serializable { /** * データをSet<String>にする責務を持つ。 */ public Set<String> getUniqueWords(Object document) { Set<String> set = new HashSet<String>(); if (document instanceof BookMarkInfo) { //ブックマークから、ユーザ情報のみを抜き取って、 //設定って感じ。 BookMarkInfo d = (BookMarkInfo) document; for (BookMarkDitailOneUserInfo info : d.set) { set.add(info.user); } //あと、URLのある層までは役に立つと思ってるので、 //それも登録。 // d.link が 「http://blog.livedoor.jp/dankogai/archives/51088368.html」 // の時、http://blog.livedoor.jp/dankogaiを登録する感じ。 // 好きなブログ、サイト抽出に近いロジック。 set.add(getURLLayer1(d.link)); } return set; } }
ベイジアンフィルタにかかわるコアの部分はこれだけです。
実装が難しいというよりも、どの情報に着目してWordListerを作るかって話かと思います。
ってことで、興味がある人はぜひ試してください。
Gmailとかを読み込ませて、フィルタリングアプリを作っているだけで、結構の間遊べますよ。
まあ、周辺系をつくるのが相当だるかったりしますけど(Imapのコードとか、クローラ、HTMLパーサのコードとか)。