Algorithm-AdaBoost

 view release on metacpan or  search on metacpan

t/01_basic.t  view on Meta::CPAN

use 5.014;

use Algorithm::AdaBoost;
use Smart::Args;
use Test::More;

my @dataset = map {
  chomp;
  my ($label, $x, $y) = split /\s/;
  +{ feature => [$x, $y], label => $label };
} <DATA>;

my @training_set = @dataset[0 .. 99];
my @test_set = @dataset[100 .. 199];

my $learner = new_ok 'Algorithm::AdaBoost' => [
  training_set => \@training_set,
  weak_classifier_generator => \&generate_weak_classifier,
];
ok(
  +(not $learner->trained),
  '|trained| should be false before the learner |train|-ed.'
);

$learner->train(num_iterations => 1000);
ok($learner->trained, 'A classifier is constructed successfully.');

my $classifier = $learner->final_classifier;

my $correct = 0;
for my $test_data (@test_set) {
  my $answer = $classifier->classify($test_data->{feature}) < 0 ? -1 : 1;
  ++$correct if $answer == $test_data->{label};
}
my $accuracy = $correct / @test_set;
cmp_ok(
  $accuracy, '>', 0.65,
  'The constructed classifier should sagnificantly accurate rather than random guess'
);

done_testing;

# Generates simple linear classifier randomly.
sub generate_weak_classifier {
  args
    my $distribution => 'ArrayRef[Num]',
    my $training_set => 'ArrayRef[HashRef]';

  while (1) {
    my ($o_x, $o_y) = (rand(6) - 3, rand(6) - 3);
    my ($p_x, $p_y) = (rand(6) - 3, rand(6) - 3);
    my @normal_vector = ($p_x - $o_x, $p_y - $o_y);

    my $accuracy = 0;
    my $classifier_candidate = sub {
      args_pos my $point => 'ArrayRef[Num]';
      my ($x, $y) = @$point;
      my @position_vector = ($x - $o_x, $y - $o_y);
      my $inner_product = $normal_vector[0] * $position_vector[0]
        + $normal_vector[1] * $position_vector[1];
      return $inner_product < 0 ? -1 : 1;
    };

    for my $i (0 .. $#$distribution) {
      my $answer = $classifier_candidate->($training_set->[$i]{feature});
      $accuracy += $distribution->[$i] if $answer == $training_set->[$i]{label};
    }
    return $classifier_candidate if $accuracy > 1/2;
  }
}

# f(x, y) = 1 if x^2 + y^2 < 4, -1 otherwise.
# subject to -3 <= x < 3, -3 <= y < 3.
__DATA__
1 -0.248490100750111 -0.739693407357834
1 -0.566115592376427 -1.68714313853555
1 -0.399623250750217 1.33407775536753
-1 1.39932333014989 2.54595589010434
-1 -2.09890668052825 -2.26928674627152
-1 -1.35789686105749 -2.76051974907672
1 0.0495294874471526 -0.961790183534873
-1 -2.14562371189552 2.51764233416243
1 1.27731540363029 0.241831210669432
1 1.16150264946072 1.49304025338465
-1 -2.69274234964235 -1.46871200361485
-1 -2.89310561098872 -2.81413989571512
-1 2.54696623984031 1.41616350632637
-1 0.781246866667637 2.48176816466842
-1 2.38373366136403 1.01253303786686
-1 0.600980674475842 2.88221379594241
-1 0.939597995977032 -2.83339742205175
-1 2.28972352960461 -0.525712426444059
-1 -2.75988102026145 -2.24446732401097
-1 2.21730008163812 -2.33850116064853
1 -1.54575431091852 -1.09897828975295
1 1.01039465416262 -1.03916319224517
-1 -2.54494588098925 2.89106013439718
-1 -0.906021606727585 -2.36200605486606
1 1.18012920171409 -1.13335728166845
1 1.0976701154454 1.51814395249566
1 0.352755644705319 -0.576001314626382
-1 1.63010120924961 -1.78558630903204
-1 2.24641222885028 0.433679372218307
1 -0.730498875458231 -0.155846827770816
1 -0.0103682274561336 0.903988972969017
-1 -2.55871684579451 2.4820246671987
-1 1.03914071391184 -2.47013455036148
-1 2.57331225205082 -2.09971455910711
1 -1.01187493679573 0.675275173414235
-1 -2.82455058874117 -1.81433702562207
-1 1.88403020752772 -2.46291432114049
-1 0.639312525703879 2.55790116121567
1 1.23578758473143 0.824585442031179
-1 2.1731435466231 1.95012524070098
-1 0.391818457618136 -2.25156279176036
-1 -1.32985199557316 -2.20788347147068
1 -1.06560921130689 -0.173258529138565
1 -1.02965253504461 0.954639702309933
-1 -2.90155358560438 2.95865861423533
-1 -0.851719893813303 -2.69989013044439
-1 2.38816922117467 1.45605135623143
-1 -2.40702878971356 -0.0801417355682332
-1 -2.09462229112317 2.92297283457907
1 1.91239584196598 0.442538561637704
-1 -2.73790593529362 1.78739935047284
-1 1.48084220237551 -2.86295516367976
-1 -2.86408646150111 -2.73100021165305
-1 1.86157798320892 2.61567151288465
-1 -0.179630617782841 2.05430544701707
1 -1.29480462666631 1.32186960797021
-1 1.77140676843387 1.98350381963468
-1 -2.90911493491699 0.558326558697715
1 -0.127859190891634 -1.23791287691753
-1 2.90733754435966 -2.68454668842683



( run in 0.714 second using v1.01-cache-2.11-cpan-140bd7fdf52 )