line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Algorithm::LibLinear::Model; |
2
|
|
|
|
|
|
|
|
3
|
3
|
|
|
3
|
|
65
|
use 5.014; |
|
3
|
|
|
|
|
12
|
|
|
3
|
|
|
|
|
133
|
|
4
|
3
|
|
|
3
|
|
18
|
use Algorithm::LibLinear; # For Algorithm::LibLinear::Model::Raw |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
70
|
|
5
|
3
|
|
|
3
|
|
17
|
use Algorithm::LibLinear::Types; |
|
3
|
|
|
|
|
7
|
|
|
3
|
|
|
|
|
60
|
|
6
|
3
|
|
|
3
|
|
16
|
use Carp qw//; |
|
3
|
|
|
|
|
3
|
|
|
3
|
|
|
|
|
44
|
|
7
|
3
|
|
|
3
|
|
13
|
use Smart::Args; |
|
3
|
|
|
|
|
4
|
|
|
3
|
|
|
|
|
1103
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
sub new { |
10
|
6
|
|
|
6
|
0
|
3765
|
args |
11
|
|
|
|
|
|
|
my $class => 'ClassName', |
12
|
|
|
|
|
|
|
my $raw_model => 'Algorithm::LibLinear::Model::Raw'; |
13
|
|
|
|
|
|
|
|
14
|
6
|
|
|
|
|
308550
|
bless +{ raw_model => $raw_model, } => $class; |
15
|
|
|
|
|
|
|
} |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
sub load { |
18
|
2
|
|
|
2
|
1
|
26
|
args |
19
|
|
|
|
|
|
|
my $class => 'ClassName', |
20
|
|
|
|
|
|
|
my $filename => 'Str'; |
21
|
|
|
|
|
|
|
|
22
|
2
|
|
|
|
|
429
|
my $raw_model = Algorithm::LibLinear::Model::Raw->load($filename); |
23
|
1
|
|
|
|
|
7
|
$class->new(raw_model => $raw_model); |
24
|
|
|
|
|
|
|
} |
25
|
|
|
|
|
|
|
|
26
|
1
|
|
|
1
|
1
|
12
|
sub class_labels { $_[0]->raw_model->class_labels } |
27
|
|
|
|
|
|
|
|
28
|
1
|
|
|
1
|
1
|
8
|
sub is_probability_model { $_[0]->raw_model->is_probability_model } |
29
|
|
|
|
|
|
|
|
30
|
1
|
|
|
1
|
1
|
5
|
sub num_classes { $_[0]->raw_model->num_classes } |
31
|
|
|
|
|
|
|
|
32
|
1
|
|
|
1
|
1
|
4
|
sub num_features { $_[0]->raw_model->num_features } |
33
|
|
|
|
|
|
|
|
34
|
6
|
|
|
6
|
0
|
280
|
sub raw_model { $_[0]->{raw_model} } |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
sub predict { |
37
|
1
|
|
|
1
|
1
|
4
|
args |
38
|
|
|
|
|
|
|
my $self, |
39
|
|
|
|
|
|
|
my $feature => 'Algorithm::LibLinear::Feature'; |
40
|
|
|
|
|
|
|
|
41
|
1
|
|
|
|
|
13
|
$self->raw_model->predict($feature); |
42
|
|
|
|
|
|
|
} |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
sub predict_probability { |
45
|
0
|
|
|
0
|
0
|
0
|
args |
46
|
|
|
|
|
|
|
my $self, |
47
|
|
|
|
|
|
|
my $feature => 'Algorithm::LibLinear::Feature'; |
48
|
|
|
|
|
|
|
|
49
|
0
|
0
|
|
|
|
0
|
unless ($self->is_probability_model) { |
50
|
0
|
|
|
|
|
0
|
Carp::carp( |
51
|
|
|
|
|
|
|
'This method only makes sense when the model is configured for' |
52
|
|
|
|
|
|
|
. ' classification based on logistic regression.' |
53
|
|
|
|
|
|
|
); |
54
|
|
|
|
|
|
|
} |
55
|
0
|
|
|
|
|
0
|
$self->raw_model->predict_probability($feature); |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
sub predict_values { |
59
|
0
|
|
|
0
|
1
|
0
|
args |
60
|
|
|
|
|
|
|
my $self, |
61
|
|
|
|
|
|
|
my $feature => 'Algorithm::LibLinear::Feature'; |
62
|
|
|
|
|
|
|
|
63
|
0
|
|
|
|
|
0
|
$self->raw_model->predict_values($feature); |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
sub save { |
67
|
1
|
|
|
1
|
1
|
1426
|
args |
68
|
|
|
|
|
|
|
my $self, |
69
|
|
|
|
|
|
|
my $filename => 'Str'; |
70
|
|
|
|
|
|
|
|
71
|
1
|
|
|
|
|
100
|
$_[0]->raw_model->save($filename); |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
1; |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
__DATA__ |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=head1 NAME |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
Algorithm::LibLinear::Model |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=head1 SYNOPSIS |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
use Algorithm::LibLinear; |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
my $data_set = Algorithm::LibLinear::DataSet->load(fh => \*DATA); |
87
|
|
|
|
|
|
|
my $classifier = Algorithm::LibLinear->new->train(data_set => $data_set); |
88
|
|
|
|
|
|
|
my $classifier = Algorithm::LibLinear::Model->load(filename => 'trained.model'); |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
my @labels = $classifier->class_labels; |
91
|
|
|
|
|
|
|
$classifier->is_probability_model; |
92
|
|
|
|
|
|
|
say $classifier->num_classes; # == @labels |
93
|
|
|
|
|
|
|
say $classifier->num_features; # == $data_set->size |
94
|
|
|
|
|
|
|
my $class_label = $classifier->predict(feature => +{ 1 => 1, 2 => 1, ... }); |
95
|
|
|
|
|
|
|
my @probabilities = $classifier->predict_probability(feature => +{ 1 => 1, 2 => 1, ... }); |
96
|
|
|
|
|
|
|
my @values = $classifier->predict_values(feature => +{ 1 => 1, 2 => 1, ... }); |
97
|
|
|
|
|
|
|
$classifier->save(filenmae => 'trained.model'); |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
__DATA__ |
100
|
|
|
|
|
|
|
+1 1:0.708333 2:1 3:1 4:-0.320755 5:-0.105023 6:-1 7:1 8:-0.419847 9:-1 10:-0.225806 12:1 13:-1 |
101
|
|
|
|
|
|
|
-1 1:0.583333 2:-1 3:0.333333 4:-0.603774 5:1 6:-1 7:1 8:0.358779 9:-1 10:-0.483871 12:-1 13:1 |
102
|
|
|
|
|
|
|
+1 1:0.166667 2:1 3:-0.333333 4:-0.433962 5:-0.383562 6:-1 7:-1 8:0.0687023 9:-1 10:-0.903226 11:-1 12:-1 13:1 |
103
|
|
|
|
|
|
|
... |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
=head1 DESCRIPTION |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
This class represents a classifier or an estimated function generated as a return value of L<Algorithm::LibLinear>'s C<train> method. |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
If you have model files generated by LIBLINEAR's C<train> command or this class's C<save> method, you can C<load> them. |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
=head1 METHOD |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
Note that the constructor of this class is B<not> a part of public API. You can get a instance via C<< Algorithm::LibLinaear->train >>. i.e., C<Algorithm::LibLinear> is a factory class. |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
=head2 load(filename => $path) |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
Class method. Load a LIBLINEAR's model file and returns an instance of this class. |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
=head2 class_labels |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
Returns an ArrayRef of class labels, each of them could be returned by C<predict> and C<predict_values>. |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
=head2 is_probability_model |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
Returns true if the model is trained as a classifier based on logistic regression, false otherwise. |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
=head2 num_classes |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
The number of class labels. |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
=head2 num_features |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
The number of features contained in training set. |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
=head2 predict(feature => $hashref) |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
In case of classification, returns predicted class label. |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
In case of regression, returns value of estimated function given feature. |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=head2 predict_probabilities(feature => $hashref) |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
Returns an ArrayRef of probabilities of the feature belonging to corresponding class. |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
This method will raise an error if the model is not a classifier based on logistic regression (i.e., C<< not $classifier->is_probability_model >>.) |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=head2 predict_values(feature => $hashref) |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
Returns an ArrayRef of decision values of each class (higher is better). |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
=head2 save(filename => $path) |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
Writes the model out as a LIBLINEAR model file. |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
=cut |