File Coverage

blib/lib/Text/NSP/Measures/4D/MI.pm
Criterion Covered Total %
statement 56 170 32.9
branch 38 104 36.5
condition n/a
subroutine 6 6 100.0
pod 2 2 100.0
total 102 282 36.1


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Text::NSP::Measures::4D::MI - Perl module that provides error checks and
4             framework to implement Loglikelihood
5             for 4-grams.
6              
7             =head1 SYNOPSIS
8              
9             =head3 Basic Usage
10              
11             use Text::NSP::Measures::4D::MI::ll;
12              
13             $ll_value = calculateStatistic(
14             n1111=>8,
15             n1ppp=>306,
16             np1pp=>83,
17             npp1p=>83,
18             nppp1=>57,
19             n11pp=>8,
20             n1p1p=>8,
21             n1pp1=>8,
22             np11p=>83,
23             np1p1=>56,
24             npp11=>56,
25             n111p=>8,
26             n11p1=>8,
27             n1p11=>8,
28             np111=>56,
29             npppp=>15180);
30              
31             if( ($errorCode = getErrorCode()))
32             {
33             print STDERR $erroCode." - ".getErrorMessage()."\n";
34             }
35             else
36             {
37             print getStatisticName."value for 4-gram is ".$ll_value."\n";
38             }
39              
40             =head1 DESCRIPTION
41              
42             This module is the base class for the Loglikelihood and the True Mutual
43             Information measures. All these measure are similar. This module provides
44             error checks specific for these measures, it also implements the
45             computations that are common to these measures.
46              
47             =over
48              
49             =item Log-Likelihood measure is computed as
50             Log-Likelihood = 2 * [n1111 * log ( n1111 / m1111 ) + n1112 * log ( n1112 / m1112 ) +
51             n1121 * log ( n1121 / m1121 ) + n1122 * log ( n1122 / m1122 ) +
52             n1211 * log ( n1211 / m1211 ) + n1212 * log ( n1212 / m1212 ) +
53             n1221 * log ( n1221 / m1221 ) + n1222 * log ( n1222 / m1222 ) +
54             n2111 * log ( n2111 / m2111 ) + n2112 * log ( n2112 / m2112 ) +
55             n2121 * log ( n2121 / m2121 ) + n2122 * log ( n2122 / m2122 ) +
56             n2211 * log ( n2211 / m2211 ) + n2212 * log ( n2212 / m2212 ) +
57             n2221 * log ( n2221 / m2221 ) + n2222 * log ( n2222 / m2222 )];
58            
59              
60             =back
61              
62             All these methods use the ratio of the observed values to expected values,
63             for computations, and thus have common error checks, so they have been grouped
64             together.
65              
66             =head2 Methods
67              
68             =over
69              
70             =cut
71              
72              
73             package Text::NSP::Measures::4D::MI;
74              
75            
76 2     2   2511 use Text::NSP::Measures::4D;
  2         6  
  2         1077  
77 2     2   9 use strict;
  2         3  
  2         39  
78 2     2   9 use Carp;
  2         3  
  2         99  
79 2     2   8 use warnings;
  2         6  
  2         2097  
80             require Exporter;
81              
82             our ($VERSION, @EXPORT, @ISA);
83              
84             @ISA = qw(Exporter);
85              
86             @EXPORT = qw(initializeStatistic calculateStatistic
87             getErrorCode getErrorMessage getStatisticName
88             $n1111 $n1112 $n1121 $n1122 $n1211 $n1212 $n1221 $n1222
89             $n2111 $n2112 $n2121 $n2122 $n2211 $n2212 $n2221 $n2222
90             $m1111 $m1112 $m1121 $m1122 $m1211 $m1212 $m1221 $m1222
91             $m2111 $m2112 $m2121 $m2122 $m2211 $m2212 $m2221 $m2222
92             $nppp1 $npp1p $npp11 $np1pp $np1p1 $np11p $np111 $n1ppp
93             $n1pp1 $n1p1p $n1p11 $n11pp $n11p1 $n111p $npppp
94             $nppp2 $npp2p $npp22 $np2pp $np2p2 $np22p $np222 $n2ppp
95             $n2pp2 $n2p2p $n2p22 $n22pp $n22p2 $n222p
96             $np112 $np121 $np122 $np211 $np212 $np221
97             $errorCodeNumber $errorMessage
98             getValues computePMI);
99              
100             $VERSION = '1.03';
101              
102              
103             =item getValues($count_values) - This method calls
104             computeMarginalTotals the computeObservedValues() and
105             the computeExpectedValues() methods to compute the
106             observed and expected values. It checks these values
107             for any errors that might cause the Loglikelihood,
108             TMI and PMI measures to fail.
109              
110             INPUT PARAMS : $count_values .. Reference of an hash containing
111             the count values computed by the
112             count.pl program.
113              
114             RETURN VALUES : 1/undef ..returns '1' to indicate success
115             and an undefined(NULL) value to indicate
116             failure.
117              
118             =cut
119              
120             sub getValues
121             {
122 16     16 1 22 my ($values)=@_;
123              
124 16 100       42 if( !(Text::NSP::Measures::4D::computeObservedValues($values)) ) {
125 15         44 return;
126             }
127            
128 1 50       4 if( !(Text::NSP::Measures::4D::computeMarginalTotals($values)) ) {
129 0         0 return;
130             }
131            
132 1 50       8 if( !(Text::NSP::Measures::4D::computeExpectedValues($values)) ) {
133 0         0 return;
134             }
135              
136             # dont want ($n1111 / $m1111) to be 0 or less! flag error if so!
137 1 50       4 if ( $n1111 )
138             {
139 1 50       4 if ($m1111 == 0) {
140 0         0 $errorMessage = "Expected value in cell (1,1,1,1) must not be zero";
141 0         0 $errorCodeNumber = 231; return;
  0         0  
142             }
143              
144 1 50       4 if (($n1111 / $m1111) <= 0) {
145 0         0 $errorMessage = "About to take log of negative value for cell (1,1,1,1)";
146 0         0 $errorCodeNumber = 232; return;
  0         0  
147             }
148             }
149              
150             # dont want ($n1112 / $m1112) to be 0 or less! flag error if so!
151 1 50       4 if ( $n1112 )
152             {
153 0 0       0 if ($m1112 == 0) {
154 0         0 $errorMessage = "Expected value in cell (1,1,1,2) must not be zero";
155 0         0 $errorCodeNumber = 233; return;
  0         0  
156             }
157              
158 0 0       0 if (($n1112 / $m1112) <= 0) {
159 0         0 $errorMessage = "About to take log of negative value for cell (1,1,1,2)";
160 0         0 $errorCodeNumber = 234; return;
  0         0  
161             }
162             }
163              
164             # dont want ($n1121 / $m1121) to be 0 or less! flag error if so!
165 1 50       3 if ( $n1121 )
166             {
167 0 0       0 if ($m1121 == 0) {
168 0         0 $errorMessage = "Expected value in cell (1,1,2,1) must not be zero";
169 0         0 $errorCodeNumber = 235; return;
  0         0  
170             }
171              
172 0 0       0 if (($n1121 / $m1121) <= 0) {
173 0         0 $errorMessage = "About to take log of negative value for cell (1,1,2,1)";
174 0         0 $errorCodeNumber = 236; return;
  0         0  
175             }
176             }
177              
178              
179             # dont want ($n1122 / $m1122) to be 0 or less! flag error if so!
180 1 50       3 if ( $n1122 )
181             {
182 0 0       0 if ($m1122 == 0) {
183 0         0 $errorMessage = "Expected value in cell (1,1,2,2) must not be zero";
184 0         0 $errorCodeNumber = 237; return;
  0         0  
185             }
186              
187 0 0       0 if (($n1122 / $m1122) <= 0) {
188 0         0 $errorMessage = "About to take log of negative value for cell (1,1,2,2)";
189 0         0 $errorCodeNumber = 238; return;
  0         0  
190             }
191             }
192              
193             # dont want ($n1211 / $m1211) to be 0 or less! flag error if so!
194 1 50       3 if ( $n1211 )
195             {
196 0 0       0 if ($m1211 == 0) {
197 0         0 $errorMessage = "Expected value in cell (1,2,1,1) must not be zero";
198 0         0 $errorCodeNumber = 239; return;
  0         0  
199             }
200              
201 0 0       0 if (($n1211 / $m1211) <= 0) {
202 0         0 $errorMessage = "About to take log of negative value for cell (1,2,1,1)";
203 0         0 $errorCodeNumber = 240; return;
  0         0  
204             }
205             }
206              
207             # dont want ($n1212 / $m1212) to be 0 or less! flag error if so!
208 1 50       4 if ( $n1212 )
209             {
210 0 0       0 if ($m1212 == 0) {
211 0         0 $errorMessage = "Expected value in cell (1,2,1,2) must not be zero";
212 0         0 $errorCodeNumber = 241; return;
  0         0  
213             }
214              
215 0 0       0 if (($n1212 / $m1212) <= 0) {
216 0         0 $errorMessage = "About to take log of negative value for cell (1,2,1,2)";
217 0         0 $errorCodeNumber = 242; return;
  0         0  
218             }
219             }
220              
221             # dont want ($n1221 / $m1221) to be 0 or less! flag error if so!
222 1 50       3 if ( $n1221 )
223             {
224 0 0       0 if ($m1221 == 0) {
225 0         0 $errorMessage = "Expected value in cell (1,2,2,1) must not be zero";
226 0         0 $errorCodeNumber = 243; return;
  0         0  
227             }
228              
229 0 0       0 if (($n1221 / $m1221) <= 0) {
230 0         0 $errorMessage = "About to take log of negative value for cell (1,2,2,1)";
231 0         0 $errorCodeNumber = 244; return;
  0         0  
232             }
233             }
234              
235             # dont want ($n1222 / $m1222) to be 0 or less! flag error if so!
236 1 50       3 if ( $n1222 )
237             {
238 1 50       3 if ($m1222 == 0) {
239 0         0 $errorMessage = "Expected value in cell (1,2,2,2) must not be zero";
240 0         0 $errorCodeNumber = 245; return;
  0         0  
241             }
242              
243 1 50       7 if (($n1222 / $m1222) <= 0) {
244 0         0 $errorMessage = "About to take log of negative value for cell (1,2,2,2)";
245 0         0 $errorCodeNumber = 246; return;
  0         0  
246             }
247             }
248              
249             # dont want ($n2111 / $m2111) to be 0 or less! flag error if so!
250 1 50       4 if ( $n2111 )
251             {
252 1 50       3 if ($m2111 == 0) {
253 0         0 $errorMessage = "Expected value in cell (2,1,1,1) must not be zero";
254 0         0 $errorCodeNumber = 247; return;
  0         0  
255             }
256              
257 1 50       3 if (($n2111 / $m2111) <= 0) {
258 0         0 $errorMessage = "About to take log of negative value for cell (2,1,1,1)";
259 0         0 $errorCodeNumber = 248; return;
  0         0  
260             }
261             }
262              
263             # dont want ($n2112 / $m2112) to be 0 or less! flag error if so!
264 1 50       3 if ( $n2112 )
265             {
266 1 50       8 if ($m2112 == 0) {
267 0         0 $errorMessage = "Expected value in cell (2,1,1,2) must not be zero";
268 0         0 $errorCodeNumber = 249; return;
  0         0  
269             }
270              
271 1 50       4 if (($n2112 / $m2112) <= 0) {
272 0         0 $errorMessage = "About to take log of negative value for cell (2,1,1,2)";
273 0         0 $errorCodeNumber = 250; return;
  0         0  
274             }
275             }
276              
277             # dont want ($n2121 / $m2121) to be 0 or less! flag error if so!
278 1 50       3 if ( $n2121 )
279             {
280 0 0       0 if ($m2121 == 0) {
281 0         0 $errorMessage = "Expected value in cell (2,1,2,1) must not be zero";
282 0         0 $errorCodeNumber = 251; return;
  0         0  
283             }
284              
285 0 0       0 if (($n2121 / $m2121) <= 0) {
286 0         0 $errorMessage = "About to take log of negative value for cell (2,1,2,1)";
287 0         0 $errorCodeNumber = 252; return;
  0         0  
288             }
289             }
290              
291             # dont want ($n2122 / $m2122) to be 0 or less! flag error if so!
292 1 50       4 if ( $n2122 )
293             {
294 1 50       3 if ($m2122 == 0) {
295 0         0 $errorMessage = "Expected value in cell (2,1,2,2) must not be zero";
296 0         0 $errorCodeNumber = 253; return;
  0         0  
297             }
298              
299 1 50       4 if (($n2122 / $m2122) <= 0) {
300 0         0 $errorMessage = "About to take log of negative value for cell (2,1,2,2)";
301 0         0 $errorCodeNumber = 254; return;
  0         0  
302             }
303             }
304              
305             # dont want ($n2211 / $m2211) to be 0 or less! flag error if so!
306 1 50       3 if ( $n2211 )
307             {
308 0 0       0 if ($m2211 == 0) {
309 0         0 $errorMessage = "Expected value in cell (2,2,1,1) must not be zero";
310 0         0 $errorCodeNumber = 255; return;
  0         0  
311             }
312              
313 0 0       0 if (($n2211 / $m2211) <= 0) {
314 0         0 $errorMessage = "About to take log of negative value for cell (2,2,1,1)";
315 0         0 $errorCodeNumber = 256; return;
  0         0  
316             }
317             }
318              
319             # dont want ($n1111 / $m1111) to be 0 or less! flag error if so!
320 1 50       3 if ( $n2212 )
321             {
322 1 50       13 if ($m2212 == 0) {
323 0         0 $errorMessage = "Expected value in cell (2,2,1,2) must not be zero";
324 0         0 $errorCodeNumber = 257; return;
  0         0  
325             }
326              
327 1 50       3 if (($n2212 / $m2212) <= 0) {
328 0         0 $errorMessage = "About to take log of negative value for cell (2,2,1,2)";
329 0         0 $errorCodeNumber = 258; return;
  0         0  
330             }
331             }
332              
333             # dont want ($n2221 / $m2221) to be 0 or less! flag error if so!
334 1 50       3 if ( $n2221 )
335             {
336 1 50       3 if ($m2221 == 0) {
337 0         0 $errorMessage = "Expected value in cell (2,2,2,1) must not be zero";
338 0         0 $errorCodeNumber = 259; return;
  0         0  
339             }
340              
341 1 50       5 if (($n2221 / $m2221) <= 0) {
342 0         0 $errorMessage = "About to take log of negative value for cell (2,2,2,1)";
343 0         0 $errorCodeNumber = 260; return;
  0         0  
344             }
345             }
346              
347             # dont want ($n2222 / $m2222) to be 0 or less! flag error if so!
348 1 50       3 if ( $n2222 )
349             {
350 1 50       3 if ($m2222 == 0) {
351 0         0 $errorMessage = "Expected value in cell (2,2,2,2) must not be zero";
352 0         0 $errorCodeNumber = 261; return;
  0         0  
353             }
354              
355 1 50       3 if (($n2222 / $m2222) <= 0) {
356 0         0 $errorMessage = "About to take log of negative value for cell (2,2,2,2)";
357 0         0 $errorCodeNumber = 262; return;
  0         0  
358             }
359             }
360              
361             # Everything looks good so we can return 1
362 1         4 return 1;
363             }
364              
365              
366              
367             =item computePMI($n, $m) - Computes the pmi of a given
368             observed and expected value pair.
369              
370             INPUT PARAMS : $n ..Observed value
371             $m ..Expected value
372              
373             RETURN VALUES : lognm .. the log of the ratio of
374             observed value to expected
375             value.
376              
377             =cut
378              
379             sub computePMI
380             {
381 16     16 1 19 my $n = shift;
382 16         17 my $m = shift;
383 16 100       27 if($n)
384             {
385 8         9 my $val = $n/$m;
386              
387 8         35 return log($val);
388             }
389             else
390             {
391 8         17 return 0;
392             }
393             }
394              
395              
396              
397             1;
398             __END__