File Coverage

blib/lib/AI/MaxEntropy/Model.pm
Criterion Covered Total %
statement 49 57 85.9
branch 10 16 62.5
condition n/a
subroutine 8 10 80.0
pod 7 7 100.0
total 74 90 82.2


line stmt bran cond sub pod time code
1 5     5   28 use strict;
  5         8  
  5         188  
2 5     5   29 use warnings;
  5         19  
  5         167  
3              
4             package AI::MaxEntropy::Model;
5              
6 5     5   4305 use YAML::Syck;
  5         11402  
  5         3723  
7              
8             our $VERSION = '0.20';
9              
10             sub new {
11 8     8 1 19 my ($class, $model) = @_;
12 8         104 my $self = bless {}, $class;
13 8 100       33 $self->load($model) if defined($model);
14 8         28 return $self;
15             }
16              
17             sub load {
18 1     1 1 2 my ($self, $file) = @_;
19 1         6 my $model = LoadFile($file);
20 1         280 ($self->{x_list}, $self->{y_list}, $self->{f_map}, $self->{lambda})
21             = @$model;
22 1         2 $self->{x_num} = scalar(@{$self->{x_list}});
  1         6  
23 1         2 $self->{y_num} = scalar(@{$self->{y_list}});
  1         4  
24 1         2 $self->{f_num} = scalar(@{$self->{lambda}});
  1         3  
25             $self->{x_bucket}->{$self->{x_list}->[$_]} = $_
26 1         15 for (0 .. $self->{x_num} - 1);
27             $self->{y_bucket}->{$self->{y_list}->[$_]} = $_
28 1         13 for (0 .. $self->{y_num} - 1);
29             }
30              
31             sub save {
32 1     1 1 2 my ($self, $file) = @_;
33 1         6 my $data = [
34             $self->{x_list},
35             $self->{y_list},
36             $self->{f_map},
37             $self->{lambda}
38             ];
39 1         7 DumpFile($file, $data);
40             }
41              
42 0     0 1 0 sub all_x { @{$_[0]->{x_list}} }
  0         0  
43 0     0 1 0 sub all_labels { @{$_[0]->{y_list}} }
  0         0  
44              
45             sub score {
46 42     42 1 47 my $self = shift;
47 42         93 my ($x, $y) = @_;
48             # preprocess if $x is hashref
49 0         0 $x = [
50             map {
51 42 50       101 my $attr = $_;
52 0         0 ref($x->{$attr}) eq 'ARRAY' ?
53 0 0       0 map { "$attr:$_" } @{$x->{$attr}} : "$_:$x->{$_}"
  0         0  
54             } keys %$x
55             ] if ref($x) eq 'HASH';
56             # calculate score
57 42         64 my @x1 = map { $self->{x_bucket}->{$_} } @$x;
  54         151  
58 42         57 my $lambda_f = 0;
59 42 50       197 if (defined(my $y1 = $self->{y_bucket}->{$y})) {
60 42         66 for my $x1 (@x1) {
61 54 50       104 if (defined($x1)) {
62 54         84 my $lambda_i = $self->{f_map}->[$y1]->[$x1];
63 54 50       197 $lambda_f += $self->{lambda}->[$lambda_i]
64             if $lambda_i != -1;
65             }
66             }
67             }
68 42         131 return $lambda_f;
69             }
70              
71             sub predict {
72 19     19 1 52 my $self = shift;
73 19         23 my $x = shift;
74 19         25 my @score = map { $self->score($x => $_) } @{$self->{y_list}};
  42         113  
  19         44  
75 19         33 my ($max_score, $max_y) = (undef, undef);
76 19         43 for my $y (0 .. $self->{y_num} - 1) {
77 42 100       104 ($max_score, $max_y) = ($score[$y], $y) if not defined($max_y);
78 42 100       122 ($max_score, $max_y) = ($score[$y], $y) if $score[$y] > $max_score;
79             }
80 19         134 return $self->{y_list}->[$max_y];
81             }
82              
83             1;
84              
85             __END__