こんにちは、Perl 6アドベントカレンダーの10日目の投稿になります。
Advent Calender 6日目では"こんにちは世界!"しかできませんでした。
今日はもうちょっと実用的な例として、Inline::Perl5でAlgorithm::LibLinearを呼び出してSVMによる機械学習をやってみましょう!
インストール
-
Inline::Perl5 の入れ方は Advent Calender 6日目 を参照してください
-
Perl 5側については下記のモジュールを入れていきましょう。cpanm を使ってると仮定しています
$ cpanm Algorithm::LibLinear
$ cpanm Mouse::Util::TypeConstraints
$ cpanm PadWalker
データセットの準備
-
libsvmのサイトからnews20をもらってきましょう
-
https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass.html#news20
-
コマンド
$ wget https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass/news20.bz2
$ bzip2 -d news20.bz2 # これはtrain用データ
$ wget https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass/news20.t.bz2
$ bzip2 -d news20.t.bz2 # これはtest用データ
Let's try!
5分割交差検定をやってみましょう
- 下記のコードではtrainデータで5分割交差検定をやっています
use Algorithm::LibLinear:from<Perl5>;
use Algorithm::LibLinear::DataSet:from<Perl5>;
my $data-str = "news20".IO.slurp;
my $data-set = Algorithm::LibLinear::DataSet.load(string => $data-str);
my $learner = Algorithm::LibLinear.new;
my $accuracy = $learner.cross_validation(
data_set => $data-set,
num_folds => 5,
);
$accuracy.say; # accuracy が出力される
$ perl6 svm.p6
0.801004079071227
いけました!!!!
predictもやってみましょう
- 下記のような操作を行っています
- train用データで学習
- test用データから適当にひとつを取り出してラベルを予想させる。という操作を5回行う
use Algorithm::LibLinear:from<Perl5>;
use Algorithm::LibLinear::DataSet:from<Perl5>;
my $train-str = "news20".IO.slurp;
my @test-lines = "news20.t".IO.lines;
my $train-set = Algorithm::LibLinear::DataSet.load(string => $train-str);
my $learner = Algorithm::LibLinear.new;
my $classifier = $learner.train(data_set => $train-set);
for ^5 {
say '# ' ~ $_;
my $line = @test-lines.pick;
my ($label, *@feature) = $line.split(" ", :skip-empty);
say "label: " ~ $label; # 正解ラベルを出力
say "feature: " ~ @feature[^5]; # 入力した素性ベクトルを出力 (多いのでここの出力は5個にしぼってます)
my Map $feature := Map.new(@feature>>.split(":", :skip-empty).flat);
my $predict-label = $classifier.predict(feature => $feature);
say "predict label: " ~ $predict-label; # SVMの予測したラベルを出力
''.say;
}
# 0
label: 6
feature: 40:1 159:2 926:1 1460:1 2481:1
predict label: 6
# 1
label: 3
feature: 10:1 21:1 25:1 36:1 56:1
predict label: 3
# 2
label: 18
feature: 1:1 61:1 115:1 132:1 150:1
predict label: 18
# 3
label: 19
feature: 10:3 25:1 32:2 81:1 84:6
predict label: 18
# 4
label: 20
feature: 1:1 10:1 25:2 40:2 79:1
predict label: 20
いけました!!!!
以上、Perl 6アドベントカレンダーの10日目の投稿、"Perl 6 の Inline::Perl5 で Perl 5 の Algorithm::LibLinear を動かす" でした。
P.S
実ははじめ、今日の記事の内容をやろうとしたときにエラーが出てしまって困ったのですが、
作者の方に相談したら解決してくださいました。
https://github.com/niner/Inline-Perl5/issues/79