File Coverage

blib/lib/AI/Categorizer/FeatureVector.pm
Criterion Covered Total %
statement 50 63 79.3
branch 13 20 65.0
condition 2 2 100.0
subroutine 14 17 82.3
pod 0 17 0.0
total 79 119 66.3


line stmt bran cond sub pod time code
1             package AI::Categorizer::FeatureVector;
2              
3             sub new {
4 122     122 0 5104 my ($package, %args) = @_;
5 122   100     521 $args{features} ||= {};
6 122         908 return bless {features => $args{features}}, $package;
7             }
8              
9             sub names {
10 3     3 0 6 my $self = shift;
11 3         6 return keys %{$self->{features}};
  3         582  
12             }
13              
14             sub set {
15 1     1 0 158 my $self = shift;
16 1 50       7 $self->{features} = (ref $_[0] ? $_[0] : {@_});
17             }
18              
19             sub as_hash {
20 154     154 0 222 my $self = shift;
21 154         353 return $self->{features};
22             }
23              
24             sub euclidean_length {
25 49     49 0 65 my $self = shift;
26 49         71 my $f = $self->{features};
27              
28 49         66 my $total = 0;
29 49         135 foreach (values %$f) {
30 296         503 $total += $_**2;
31             }
32 49         149 return sqrt($total);
33             }
34              
35             sub normalize {
36 48     48 0 227 my $self = shift;
37              
38 48         96 my $length = $self->euclidean_length;
39 48 100       165 return $length ? $self->scale(1/$length) : $self;
40             }
41              
42             sub scale {
43 50     50 0 75 my ($self, $scalar) = @_;
44 50         62 $_ *= $scalar foreach values %{$self->{features}};
  50         320  
45 50         187 return $self;
46             }
47              
48             sub as_boolean_hash {
49 16     16 0 18 my $self = shift;
50 16         18 return { map {($_ => 1)} keys %{$self->{features}} };
  112         199  
  16         50  
51             }
52              
53             sub length {
54 0     0 0 0 my $self = shift;
55 0         0 return scalar keys %{$self->{features}};
  0         0  
56             }
57              
58             sub clone {
59 4     4 0 5 my $self = shift;
60 4         7 return ref($self)->new( features => { %{$self->{features}} } );
  4         43  
61             }
62              
63             sub intersection {
64 16     16 0 24 my ($self, $other) = @_;
65 16 50       62 $other = $other->as_hash if UNIVERSAL::isa($other, __PACKAGE__);
66              
67 16         17 my $common;
68 16 50       69 if (UNIVERSAL::isa($other, 'ARRAY')) {
    50          
69 0 0       0 $common = {map {exists $self->{features}{$_} ? ($_ => $self->{features}{$_}) : ()} @$other};
  0         0  
70             } elsif (UNIVERSAL::isa($other, 'HASH')) {
71 16 100       65 $common = {map {exists $self->{features}{$_} ? ($_ => $self->{features}{$_}) : ()} keys %$other};
  288         568  
72             }
73 16         68 return ref($self)->new( features => $common );
74             }
75              
76             sub add {
77 114     114 0 155 my ($self, $other) = @_;
78              
79 114 100       372 $other = $other->as_hash if UNIVERSAL::isa($other, __PACKAGE__);
80 114         413 while (my ($k,$v) = each %$other) {
81 741         2959 $self->{features}{$k} += $v;
82             }
83             }
84              
85             sub dot {
86 82     82 0 344 my ($self, $other) = @_;
87 82 50       315 $other = $other->as_hash if UNIVERSAL::isa($other, __PACKAGE__);
88              
89 82         125 my $sum = 0;
90 82         111 my $f = $self->{features};
91 82         247 while (my ($k, $v) = each %$f) {
92 456 100       1840 $sum += $other->{$k} * $v if exists $other->{$k};
93             }
94 82         247 return $sum;
95             }
96              
97             sub sum {
98 0     0 0 0 my ($self) = @_;
99              
100             # Return total of values in this vector
101 0         0 my $total = 0;
102 0         0 $total += $_ foreach values %{ $self->{features} };
  0         0  
103 0         0 return $total;
104             }
105              
106             sub includes {
107 17     17 0 269 return exists $_[0]->{features}{$_[1]};
108             }
109              
110             sub value {
111 5     5 0 31 return $_[0]->{features}{$_[1]};
112             }
113              
114             sub values {
115 0     0 0   my $self = shift;
116 0           return @{ $self->{features} }{ @_ };
  0            
117             }
118              
119             1;
120             __END__