LoginSignup
2

More than 5 years have passed since last update.

Perl 6 の Inline::Perl5 で Perl 5 の Algorithm::LibLinear を動かす

Last updated at Posted at 2016-12-10

こんにちは、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

データセットの準備

$ 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分割交差検定をやっています
svm.p6
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 が出力される
output
$ perl6 svm.p6
0.801004079071227

いけました!!!!

predictもやってみましょう

  • 下記のような操作を行っています
    • train用データで学習
    • test用データから適当にひとつを取り出してラベルを予想させる。という操作を5回行う
svm-predict.p6
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;
}
output
# 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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2