岩手からこんにちは ☆彡 perl とかウェブ系なブログ

はてなダイアリーからひっこしましたよ http://d.hatena.ne.jp/rosiro

Algorithm::NaiveBayesで2ch系まとめサイトをカテゴライズしてみた

2ch系まとめサイトのアンテナ?的な新着サイトは結構あるんですが、勉強もかねてAlgorithm::NaiveBayesでベイズ使ってカテゴライズしてみたメモ。

Algorithm::NaiveBayes
http://search.cpan.org/~kwilliams/Algorithm-NaiveBayes-0.04/lib/Algorithm/NaiveBayes.pm

目標 はてぶみたいに自動でカテゴリ分けしたい

参考に・・

新はてなブックマークでも使われてるComplement Naive Bayesを解説するよhttp://d.hatena.ne.jp/tkng/20081217/1229475900

上のサイトをみるとはてなではComplement Naive Bayesがつかわれてるっぽいです。

ここではAlgorithm::NaiveBayes 単純ベイズを使いました。
カテゴリ予測までの流れ

  1. カテゴリに属すると思われるページを選定
  2. 選ばれたページから特徴語を抽出 Lingua::JA::OkapiBM25を使いました。
  3. Algorithm::NaiveBayesにadd_instanceでカテゴリに属性データを追加
  4. Algorithm::NaiveBayesに学習させる
  5. ページがどのカテゴリーに属するかを予測する predict

カテゴリーを用意

今回は

政治・経済、スポーツ、科学・学問、グルメ・レシピ、映画・音楽、コンピュータ・IT、ゲーム、アニメ・漫画、アイドル・芸能人、アダルト

を用意しました。

そしてカテゴリーに属するサイトデータははてなブックマークのランキングや人気データを利用しました。

たとえば政治・経済の場合は http://b.hatena.ne.jp/ranking/monthly/201208/economics にのってるページを集めるといった感じで、各カテゴリにふさわしいと思われるサイトデータを集めます。

あとめたサイトの特徴語を抽出します。
抽出にはLingua::JA::OkapiBM25を利用しました。

my $page_text = ページタイトル . ページ概要などなど;
my $okapi =  Lingua::JA::OkapiBM25->new;
my @list  = $okapi->bm25(encode("utf8",$page_text))->list(50);

上記でLingua::JA::OkapiBM25が50個の特徴語を抽出してくれます。
Lingua::JA::OkapiBM25については
http://d.hatena.ne.jp/download_takeshi/20091206/1260130230
が詳しいです。(というか作者さん)

抽出したデータをAlgorithm::NaiveBayesにadd_instanceする

my $bayes;
my $bayes_file = 'algorithm_naivebayes.dat';
if( -f $bayes_file){
    $bayes = Algorithm::NaiveBayes->restore_state($bayes_file);
}
else{
    $bayes = Algorithm::NaiveBayes->new( purge => 0 );
}

for $さいと ( @さいと){
  my %pagedata{
    encode("utf8",$keyword->keyword)} => encode("utf8",$page_keyword->score);
  };
  $bayes->add_instance(
    attributes => {%pagedata},
    label => encode("utf8",'カテゴリ名'),
  );
}

bayes->train;
my $save = $bayes->save_state($bayse_file);

各カテゴリには約1500サイト程度にしています。 カテゴリに属するサイトの数はおなじぐらいになるようにしています。


最後にページがどのカテゴリに属するか予測してみます。

my $bayes_file = 'algorithm_naivebayes.dat';
if( -f $bayes_file){
    $bayes = Algorithm::NaiveBayes->restore_state($bayes_file);
}
else{
    $bayes = Algorithm::NaiveBayes->new( purge => 0 );
}

my %pagedata{
    'hogehoge' => 1.555,
    'mogemoge' => 1.444',
};
my $result = $bayes->predict( attributes => {%pagedata} );

以上でそのページがどのカテゴリに属するのかの予測ができました。

まとめサイトのデータは、最近2chで、まとめサイトを登録しろ的な事になったようですので、
ニコニコ大百科 http://dic.nicovideo.jp/a/2ch%E9%96%A2%E9%80%A3%E3%81%BE%E3%81%A8%E3%82%81%E3%82%B5%E3%82%A4%E3%83%88%E3%81%AE%E4%B8%80%E8%A6%A7
からサイトを調べています。
それぞれのサイトからrssフィードURLを探し出して、LWP::UserAgentで記事を抽出しています。

そんなこんなして、とりあえずつくってみたのがこちらになります。


めろりん http://merolin.com


カテゴライズはあってる部分と、それ違うだろ的な感じになっています。
まあなんとなくだけど、それっぽい感じにはなりました。
このままだといけてないので、カテゴリを修正する、ページつくって、手動で修正していく必要があるのかなとおもってます。 いまのところここまで

本当はBM25で抽出した単語の関連語なんかも出した方がいいのだろうとおもいます。
その辺のチューニング的な事もしないとだめだとおもいます。
あとComplement Naive Bayesでやれれば、やってみたいなと思います。

以上メモ。

とりあえず機械学習はたのしい!