File Coverage

blib/lib/Text/TFIDF.pm
Criterion Covered Total %
statement 68 68 100.0
branch 11 14 78.5
condition 1 2 50.0
subroutine 11 11 100.0
pod 5 5 100.0
total 96 100 96.0


line stmt bran cond sub pod time code
1             package Text::TFIDF;
2              
3 1     1   12707 use 5.012003;
  1         2  
4 1     1   3 use strict;
  1         1  
  1         20  
5 1     1   2 use warnings;
  1         4  
  1         21  
6 1     1   3 use Carp;
  1         1  
  1         810  
7             require Encode;
8              
9             our $VERSION = '0.03';
10              
11              
12             sub new {
13 2     2 1 7 my $class = shift;
14 2         2 my $self = {};
15              
16 2         3 bless $self, $class;
17              
18 2         3 my %args = @_;
19              
20 2 100       5 if ($args{file}) {
21 1         10 $self->process_files(@{$args{file}});
  1         3  
22             }
23              
24 2         4 return $self;
25             }
26              
27             sub TFIDF {
28 5     5 1 207 my $self = shift;
29 5         5 my $file = shift;
30 5         4 my $word = shift;
31              
32 5 100       12 if (!defined $file) {
33 1         112 carp("You must give a filename for the TFIDF measure.\n");
34 1         41 return undef;
35             }
36              
37 4 100       6 if (!defined $word) {
38 1         58 carp("You must give a word for the TFIDF measure.\n");
39 1         45 return undef;
40             }
41              
42             # $word =~ s/[?;:!,.'"]//g;
43 3         5 $word =~ s/[?;:!,."\(\)]//g;
44 3 50       8 return undef if (!defined $self->{file}->{$file});
45 3         5 return $self->TF($file,$word)*$self->IDF($word);
46             }
47              
48              
49             sub TF {
50 4     4 1 3 my $self = shift;
51 4         4 my $file = shift;
52 4         2 my $word = shift;
53              
54 4         9 return $self->{file}->{$file}->{$word};
55             }
56              
57              
58             #IDF = log(number of documents/(number of documents containing the word))
59             sub IDF {
60              
61 4     4 1 4 my $self = shift;
62 4         4 my $word = shift;
63              
64 4         3 my $count = 0;
65              
66 4         3 foreach my $el (keys %{$self->{file}}) {
  4         12  
67 8 50       16 $count++ if (defined $self->{file}->{$el}->{$word});
68             }
69              
70 4         4 return log(scalar(keys %{$self->{file}})/(1+$count))/log(10);
  4         25  
71             }
72              
73             sub process_files {
74              
75 2     2 1 248 my $self = shift;
76 2         3 my @documents = @_;
77              
78 2         2 foreach my $el (@documents) {
79 4         8 $self->_process_file($el);
80             }
81              
82 2         4 return 1;
83             }
84              
85             sub _process_file {
86 4     4   4 my $self = shift;
87 4         4 my $file = shift;
88              
89 4         1 my $hash;
90 4 50       62 return undef if (!-r $file);
91 1   50 1   4 open my $handle, '<:encoding(UTF-8)', $file || die $file," ",$!;
  1         1  
  1         5  
  4         83  
92 4         1115 while (<$handle>) {
93 138         246 chop;
94 138         178 my $line = lc($_);
95 138         488 my @words = split(/\s+/,$line);
96 138         173 foreach my $el (@words) {
97 1016         1035 $el =~ s/[?;:!,."\(\)]//g;
98 1016         1221 my $word = Encode::encode("utf8",$el);
99 1016 100       11012 if (defined $hash->{$word}) {
100 464         516 $hash->{$word}++;
101             }
102             else {
103 552         818 $hash->{$word} = 1;
104             }
105             }
106             }
107 4         90 close($handle);
108            
109 4         21 $self->{file}->{$file} = $hash;
110              
111             }
112              
113             1;
114             __END__