メメメモモ

プログラミング、筋トレ、ゲーム、etc

ベイジアンフィルタの学習データをデータベースかStorableで管理

WEB+DB PRESS Vol.56

WEB+DB PRESS Vol.56


ベイジアンフィルタ開発に挑戦 未知のデータを学習して分類 - アルゴリズム実践教室」


上記のコーナーで作成しているサンプルコード「Classifier」モジュールを改造して、学習データをDBとStorableで扱えるようにしました。
学習データ部分は、Classifier.pmから分離して「Classifier::Filter::」下に別クラスとして持つようにしています。

http://github.com/memememomo/Classifier


データベースの場合


テーブル作成

$ mysql -uroot classifier < table.sql


スクリプト

use strict;
use warnings;
use DBI;
use Classifier;
use Classifier::Filter::DBI;

my $cl = Classifier->new;
my $filter = Classifier::Filter::DBI->new( dbh => DBI->connect('dbi:mysql:classifier','root',''));
$cl->set_filter($filter);

# 学習フェーズ                                                                                              
$cl->train('perlpythonスクリプト言語です', 'it');
$cl->train('perlベイジアンフィルタを作りました', 'it');
$cl->train('pythonはニシキヘビ科のヘビの総称', 'science');

# カテゴリ推定                                                                                              
print $cl->predict('perlは楽しい'),"\n";  # it
print $cl->predict('pythonperl'),"\n"; # it
print $cl->predict('pythonはヘビ'),"\n"; # science


DBには、下記のような感じで学習データが格納されます。

mysql> select * from category_count;
+----+----------+-------+
| id | category | count |
+----+----------+-------+
|  1 | it       |     7 |
|  2 | science  |     5 |
+----+----------+-------+

mysql> select * from term_count;
+----+-----------------------------+----------+-------+
| id | term                        | category | count |
+----+-----------------------------+----------+-------+
|  1 | perl                        | it       |     1 |
|  2 | python                      | it       |     1 |
|  3 | 言語                      | it       |     1 |
|  4 | スクリプト             | it       |     1 |
|  5 | 作り                      | it       |     1 |
|  6 | ベイジアンフィルタ | it       |     1 |
|  7 | 科                         | science  |     1 |
|  8 | ヘビ                      | science  |     1 |
|  9 | ニシキヘビ             | science  |     1 |
| 10 | python                      | science  |     1 |
| 11 | 総称                      | science  |     1 |
+----+-----------------------------+----------+-------+

Storableの場合

Storableの場合、「Classifier::Filter::Memory.pm」を使用します。

use strict;
use warnings;
use DBI;
use Classifier;
use Classifier::Filter::Memory;

my $dat = './filter.dat';

my $cl = Classifier->new;

# 学習フェーズ
if (-e $dat) {
    $cl->load_filter($dat);
} else {
    my $filter = Classifier::Filter::Memory->new();
    $cl->set_filter($filter);
    $cl->train('perlpythonスクリプト言語です', 'it');
    $cl->train('perlベイジアンフィルタを作りました', 'it');
    $cl->train('pythonはニシキヘビ科のヘビの総称', 'science');
}
$cl->save_filter($dat);


# カテゴリ推定
print $cl->predict('perlは楽しい'),"\n";
print $cl->predict('pythonperl'),"\n";
print $cl->predict('pythonはヘビ'),"\n";

$cl->save_filter($dat)で、Classifier::Filter::Memoryのインスタンスをまるごと保存するようにしています。

その他の保存方法

今回は、2種類の保存方法を実装しましたが、他にも方法がありそうです。
他の方法を追加する場合、「Classifier::Filter::」下にモジュールを作成するような形にしたいなと考えています。