File Coverage

blib/lib/Lingua/EN/WSD/CorpusBased.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Lingua::EN::WSD::CorpusBased;
2              
3             our $VERSION = "0.11";
4              
5 1     1   21046 use warnings;
  1         1  
  1         31  
6 1     1   5 use strict;
  1         1  
  1         34  
7 1     1   763 use String::Util qw(crunch);
  1         5550  
  1         81  
8 1     1   405 use stem;
  0            
  0            
9             use Lingua::EN::WSD::CorpusBased::Corpus;
10              
11             sub new {
12             my $class = shift;
13              
14             my %args = ('debug' => 0,
15             'strict' => 0,
16             'stem' => 1,
17             'hypernyms' => 1,
18             'hyponyms' => 1,
19             @_);
20             return -1 if (ref($args{'wnref'}) ne 'WordNet::QueryData');
21             return -1 if (ref($args{'cref'}) ne 'Lingua::EN::WSD::CorpusBased::Corpus');
22            
23             my $this = { 'wn' => $args{'wnref'},
24             'corpus' => $args{'cref'},
25             'debug' => $args{'debug'},
26             'strict' => $args{'strict'},
27             'flexibility' => $args{'flexibility'},
28             'stem' => $args{'stem'},
29             'stemmer' => stem->new($args{'wnref'}),
30             'hype' => $args{'hypernyms'},
31             'hypo' => $args{'hyponyms'}};
32             return bless $this, $class;
33             }
34              
35             sub init {
36             my $self = shift;
37             my %args = @_;
38             my $term = $args{'term'};
39             my @t = split / +/, lc($term);
40             $self->{'term'} = \@t;
41             $self->{'size'} = scalar @t;
42             $self->{'inWN'} = $self->{'wn'}->queryWord($self->term,"syns");
43             $self->{'wnTerm'} = crunch($self->{'stemmer'}->stemString(($self->{'inWN'}?$self->term:$self->head)));
44             if ($self->{'debug'} > 0) {
45             print STDERR 'CorpusBased object initialized (term="'.join(' ',@{ $self->{'term'} }).'", ';
46             print STDERR 'size="'.$self->{'size'}.'", ';
47             print STDERR 'inWN="'.$self->{'inWN'}.'", ';
48             print STDERR 'wnTerm="'.$self->{'wnTerm'}.")\n";
49             }
50             }
51            
52             sub ready {
53             my $self = shift;
54             return 0 if (! exists($self->{'term'}));
55             return 0 if ($self->{'term'} eq '');
56             return 1;
57             }
58              
59             sub term {
60             my $self = shift;
61             return -1 if (! $self->ready);
62             return lc(join("_",@{$self->{'term'}}));
63             }
64              
65             sub head {
66             my $self = shift;
67             return -1 if (! $self->ready);
68             return lc($self->{'term'}->[$self->{'size'} - 1]);
69             }
70              
71             sub term_replace {
72             my $self = shift;
73             my $replacement = shift;
74             return -1 if (! $self->ready);
75             my @t = @{$self->{'term'}};
76             pop(@t);
77             push(@t,split(/_/,$replacement));
78             return \@t;
79             }
80              
81              
82             sub synsets {
83             my $self = shift;
84             my %returnlist = ();
85             return [] if (! $self->ready);
86             my $query = $self->{'wnTerm'};
87             my @senses = $self->{'wn'}->queryWord($query,"syns");
88             foreach my $word_pos (@senses) {
89             foreach my $word_pos_num ($self->{'wn'}->querySense($word_pos,"syns")) {
90             $returnlist{$word_pos_num} = 1;
91             };
92             };
93             my @t = keys %returnlist;
94            
95             return \@t;
96             }
97              
98             sub synonyms {
99             my ($self,$synset) = @_;
100             return () if ((! defined $synset) or $synset eq '');
101             return (map
102             { /([^\#]*)\#[nva]\#\d+/; $1 }
103             $self->{'wn'}->querySense($synset,"syns"));
104             }
105              
106             sub hypernyms {
107             my ($self,$synset) = @_;
108             return () if ((! defined $synset) or $synset eq '');
109             return $self->{'wn'}->querySense($synset,"hype");
110             }
111              
112             sub hyponyms {
113             my ($self,$synset) = @_;
114             return () if ((! defined $synset) or $synset eq '');
115             return $self->{'wn'}->querySense($synset,"hypo");
116             }
117              
118             sub count {
119             my $self = shift;
120             return -1 if ((! defined $self->{'corpus'}) or
121             (! exists $self->{'corpus'}));
122             return $self->{'corpus'}->count(@_);
123             }
124              
125             sub v {
126             my ($self,$synset) = @_;
127             return -1 if (! defined $synset or
128             $synset eq '');
129             my $sum = 0;
130             foreach my $synonym ($self->synonyms($synset)) {
131             if ($self->{'inWN'}) {
132             $sum += $self->count(split(/_/,$synonym));
133             } else {
134             $sum += $self->count(@{$self->term_replace($synonym)});
135             }
136             };
137              
138             # hypernyms
139             if ($self->{'hype'}) {
140             foreach my $hypernym ($self->hypernyms($synset)) {
141             foreach my $synonym ($self->synonyms($hypernym)) {
142             if ($self->{'inWN'}) {
143             $sum += $self->count(split(/_/,$synonym));
144             } else {
145             $sum += $self->count(@{$self->term_replace($synonym)});
146             }
147             };
148             };
149             };
150              
151             # hyponyms
152             if ($self->{'hypo'}) {
153             foreach my $hyponym ($self->hyponyms($synset)) {
154             foreach my $synonym ($self->synonyms($hyponym)) {
155             if ($self->{'inWN'}) {
156             $sum += $self->count(split(/_/,$synonym));
157             } else {
158             $sum += $self->count(@{$self->term_replace($synonym)});
159             }
160             };
161             };
162             };
163             return $sum;
164             }
165              
166             sub sense {
167             my $self = shift;
168             my $max = 0;
169             return [] if ($self->{'wnTerm'} eq '');
170             my @maxsynsets = ();
171             foreach my $synset (@{$self->synsets}) {
172             print STDERR ' '.$synset."\n" if ($self->{'debug'} > 0);
173             my $value = $self->v($synset)."\n";
174             if ($value > $max) {
175             @maxsynsets = ($synset);
176             $max = $value;
177             } elsif ($value == $max) {
178             push(@maxsynsets, $synset);
179             };
180             }
181             if (scalar @maxsynsets == scalar @{ $self->synsets } and
182             $self->{'strict'}) {
183             return [];
184             }
185             return \@maxsynsets;
186             }
187              
188             sub wsd {
189             my ($self,$term) = @_;
190             return -1 if ($term eq '');
191             print STDERR "Doing WSD for term '$term'\n" if ($self->{'debug'} > 0);
192             $self->init('term' => $term);
193             return $self->sense;
194             }
195              
196             sub debug {
197             my $self = shift;
198             return $self->{'debug'};
199             }
200              
201             1;
202              
203             __END__