File Coverage

blib/lib/Word2vec/Spearmans.pm
Criterion Covered Total %
statement 9 360 2.5
branch 0 220 0.0
condition 0 147 0.0
subroutine 5 29 17.2
pod 17 18 94.4
total 31 774 4.0


line stmt bran cond sub pod time code
1             #!usr/bin/perl
2            
3             ######################################################################################
4             # #
5             # Author: Clint Cuffy #
6             # Date: 05/09/2016 #
7             # Revised: 09/09/2017 #
8             # UMLS Similarity Word2Phrase Executable Interface Module #
9             # #
10             ######################################################################################
11             # #
12             # Description: #
13             # ============ #
14             # Spearman's Rank Correlation Module for UMLS Similarity #
15             # Features: #
16             # ========= #
17             # Calculates Spearman's Rank Correlation Scores #
18             # #
19             ######################################################################################
20            
21            
22             package Word2vec::Spearmans;
23            
24 3     3   18 use strict;
  3         7  
  3         81  
25 3     3   16 use warnings;
  3         4  
  3         96  
26            
27            
28 3     3   16 use vars qw($VERSION);
  3         6  
  3         152  
29            
30             $VERSION = '0.02';
31            
32            
33             ######################################################################################
34             # Constructor
35             ######################################################################################
36            
37             BEGIN
38       3     {
39             # CONSTRUCTOR : DO SOMETHING HERE
40             }
41            
42            
43             ######################################################################################
44             # Deconstructor
45             ######################################################################################
46            
47             END
48       3     {
49             # DECONSTRUCTOR : DO SOMETHING HERE
50             }
51            
52            
53             ######################################################################################
54             # new Class Operator
55             ######################################################################################
56            
57             sub new
58             {
59 0     0 1   my $class = shift;
60 0           my $self = {
61             # Private Member Variables
62             _debugLog => shift, # Boolean (Binary): 0 = False, 1 = True
63             _writeLog => shift, # Boolean (Binary): 0 = False, 1 = True
64             _precision => shift, # Integer
65             _isFileOfWords => shift, # undef = Auto-Detect, 0 = CUI Terms, 1 = Word Terms
66             _printN => shift, # undef = Do Not Print N / defined = Print N
67             _aCount => shift, # Integer
68             _bCount => shift, # Integer
69             _NValue => shift, # Integer
70             };
71            
72             # Set debug log variable to false if not defined
73 0 0         $self->{ _debugLog } = 0 if !defined( $self->{ _debugLog } );
74 0 0         $self->{ _writeLog } = 0 if !defined( $self->{ _writeLog } );
75 0 0         $self->{ _precision } = 4 if !defined( $self->{ _precision } );
76 0 0         $self->{ _aCount } = -1 if !defined( $self->{ _aCount } );
77 0 0         $self->{ _bCount } = -1 if !defined( $self->{ _bCount } );
78 0 0         $self->{ _NValue } = -1 if !defined( $self->{ _NValue } );
79            
80            
81             # Open File Handler if checked variable is true
82 0 0         if( $self->{ _writeLog } )
83             {
84 0           open( $self->{ _fileHandle }, '>:encoding(UTF-8)', 'SpearmansLog.txt' );
85 0           $self->{ _fileHandle }->autoflush( 1 ); # Auto-flushes writes to log file
86             }
87            
88 0           bless $self, $class;
89 0           return $self;
90             }
91            
92            
93             ######################################################################################
94             # DESTROY
95             ######################################################################################
96            
97             sub DESTROY
98             {
99 0     0     my ( $self ) = @_;
100            
101             # Close FileHandle
102 0 0         close( $self->{ _fileHandle } ) if( $self->{ _fileHandle } );
103             }
104            
105            
106             ######################################################################################
107             # Module Functions
108             ######################################################################################
109            
110             sub CalculateSpearmans
111             {
112 0     0 1   my ( $self, $fileA, $fileB, $includeCountsInResults ) = @_;
113            
114             # Check(s)
115 0 0 0       print( "Error: This Function Requires Two Arguments\n" ) if $self->GetDebugLog() == 0 && ( !defined( $fileA ) || !defined( $fileB ) );
      0        
116 0 0         $self->WriteLog( "CalculateSpearmans - Error: \"FileA\" Not Defined" ) if !defined( $fileA );
117 0 0         $self->WriteLog( "CalculateSpearmans - Error: \"FileB\" Not Defined" ) if !defined( $fileB );
118 0 0 0       if( !defined( $fileA ) || !defined( $fileB ) )
119             {
120 0           $self->_ResetVariables();
121 0           return undef;
122             }
123            
124 0 0 0       print( "Error: Unable To Locate One Or More Files\n" ) if $self->GetDebugLog() == 0 && ( !( -e $fileA ) || !( -e $fileB ) );
      0        
125 0 0         $self->WriteLog( "CalculateSpearmans - Error: File \"$fileA\" Does Not Exist" ) if !( -e $fileA );
126 0 0         $self->WriteLog( "CalculateSpearmans - Error: File \"$fileB\" Does Not Exist" ) if !( -e $fileB );
127 0 0 0       if( !( -e $fileA ) || !( -e $fileB ) )
128             {
129 0           $self->_ResetVariables();
130 0           return undef;
131             }
132            
133 0 0 0       print( "Error: One Or More Files Are Empty / 0-Byte Files\n" ) if $self->GetDebugLog() == 0 && ( -z $fileA || -z $fileB );
      0        
134 0 0         $self->WriteLog( "CalculateSpearmans - Error: File \"$fileA\" Exists But Has No Data / File Size = 0 bytes" ) if ( -z $fileA );
135 0 0         $self->WriteLog( "CalculateSpearmans - Error: File \"$fileB\" Exists But Has No Data / File Size = 0 bytes" ) if ( -z $fileB );
136 0 0 0       if( -z $fileA || -z $fileB )
137             {
138 0           $self->_ResetVariables();
139 0           return undef;
140             }
141            
142 0           my $rank = 0;
143 0           my $aCUICheck = 0; my $bCUICheck = 0;
  0            
144 0           my $aMean = 0 ; my $bMean = 0;
  0            
145 0           my $aCount = 0 ; my $bCount = 0;
  0            
146 0           my %aHash = (); my %bHash = ();
  0            
147 0           my %aList = (); my %bList = ();
  0            
148 0           my %aRank = (); my %bRank = ();
  0            
149 0           my $aNegative = 0 ; my $bNegative = 0;
  0            
150 0           my $aTotal = 0 ; my $bTotal = 0;
  0            
151 0           my $oldIsFileOfWords = $self->GetIsFileOfWords();
152 0           my $fileAIsCUIFile = undef;
153 0           my $fileBIsCUIFile = undef;
154            
155 0           my $errorOpeningFile = 0;
156            
157             # Open $fileA Data
158 0           $self->WriteLog( "CalculateSpearmans - Opening File: \"$fileA\"" );
159 0 0         open( A, "<:",$fileA ) or $errorOpeningFile = 1;
160            
161             # Check
162 0 0         $self->WriteLog( "CalculateSpearmans - Error Opening \"$fileA\"" ) if ( $errorOpeningFile == 1 );
163 0 0         if( $errorOpeningFile == 1 )
164             {
165 0           $self->_ResetVariables();
166 0           return undef;
167             }
168            
169             # Read $fileA Data Into Memory Using $_ variable
170 0           while( )
171             {
172 0           chomp;
173 0           $_ = lc;
174            
175             # Removes Spaces At Both Ends Of String And More Than Once Space In-Between Ends
176 0           $_ =~ s/^\s+|\s(?=\s)|\s+$//g;
177            
178 0           my( $score, $term1, $term2 ) = split( /<>/ );
179            
180             # Auto-Detect If Terms Are CUIs or Words
181 0 0 0       if( $aCUICheck == 0 && !defined( $self->GetIsFileOfWords() ) )
182             {
183 0           my $isCUI1 = $self->_IsCUI( $term1 );
184 0           my $isCUI2 = $self->_IsCUI( $term2 );
185            
186 0 0 0       $self->WriteLog( "CalculateSpearmans - File: \"$fileA\" Detected As Word File" ) if ( $isCUI1 == 0 && $isCUI2 == 0 );
187 0 0 0       $self->WriteLog( "CalculateSpearmans - File: \"$fileA\" Detected As CUI File" ) if ( $isCUI1 == 1 && $isCUI2 == 1 );
188 0 0 0       $self->SetIsFileOfWords( 1 ) if( $isCUI1 == 0 && $isCUI2 == 0 );
189 0 0 0       $self->SetIsFileOfWords( 0 ) if( $isCUI1 == 1 && $isCUI2 == 1 );
190            
191 0 0 0       $fileAIsCUIFile = 0 if ( $isCUI1 == 0 && $isCUI2 == 0 );
192 0 0 0       $fileAIsCUIFile = 1 if ( $isCUI1 == 1 && $isCUI2 == 1 );
193 0           $aCUICheck = 1;
194            
195             # Check(s)
196 0 0 0       $self->WriteLog( "CalculateSpearmans - Error: \"$fileA\" - Term1 Is CUI and Term2 Is Word" ) if ( $isCUI1 == 1 && $isCUI2 == 0 );
197 0 0 0       $self->WriteLog( "CalculateSpearmans - Error: \"$fileA\" - Term1 Is Word and Term2 Is CUI" ) if ( $isCUI1 == 0 && $isCUI2 == 1 );
198 0 0         if ( $isCUI1 != $isCUI2 )
199             {
200 0           close( A );
201 0           $self->SetIsFileOfWords( undef );
202 0           $self->_ResetVariables();
203 0           return undef;
204             }
205             }
206            
207 0           my $cui1 = ""; my $cui2 = "";
  0            
208            
209 0 0 0       if( defined( $self->GetIsFileOfWords() ) && $self->GetIsFileOfWords() == 1 )
210             {
211 0           $cui1 = $term1;
212 0           $cui2 = $term2;
213             }
214             else
215             {
216 0           $term1 =~ /(C[0-9]+)/;
217 0 0         $cui1 = $1 if defined( $1 );
218            
219 0           $term2 =~ /(C[0-9]+)/;
220 0 0         $cui2 = $1 if defined( $1 );
221             }
222            
223 0 0         if( $score == -1.0 )
224             {
225 0           $aNegative++;
226 0           next;
227             }
228            
229 0           $aTotal++;
230 0           push( @{ $aHash{ $score } }, "$cui1 $cui2" );
  0            
231 0           $aList{ "$cui1 $cui2" }++;
232             }
233            
234             # Clean Up
235 0           $self->WriteLog( "CalculateSpearmans - Closing File: \"$fileA\"" );
236 0           $self->SetIsFileOfWords( $oldIsFileOfWords );
237 0           $errorOpeningFile = 0;
238 0           close( A );
239            
240            
241             # Open $fileB Data
242 0           $self->WriteLog( "CalculateSpearmans - Opening File: \"$fileB\"" );
243 0 0         open( B, "<:",$fileB ) or $errorOpeningFile = 1;
244            
245             # Check
246 0 0         $self->WriteLog( "CalculateSpearmans - Error Opening \"$fileB\"" ) if ( $errorOpeningFile == 1 );
247 0 0         if( $errorOpeningFile == 1 )
248             {
249 0           $self->_ResetVariables();
250 0           return undef;
251             }
252            
253             # Read $fileB Data Into Memory Using $_ variable
254 0           while( )
255             {
256 0           chomp;
257 0           $_ = lc;
258            
259             # Removes Spaces At Both Ends Of String And More Than Once Space In-Between Ends
260 0           $_ =~ s/^\s+|\s(?=\s)|\s+$//g;
261            
262 0           my( $score, $term1, $term2 ) = split( /<>/ );
263            
264             # Auto-Detect If Terms Are CUIs Or Words
265 0 0 0       if( $bCUICheck == 0 && !defined( $self->GetIsFileOfWords() ) )
266             {
267 0           my $isCUI1 = $self->_IsCUI( $term1 );
268 0           my $isCUI2 = $self->_IsCUI( $term2 );
269            
270 0 0 0       $self->WriteLog( "CalculateSpearmans - File: \"$fileA\" Detected As Word File" ) if ( $isCUI1 == 0 && $isCUI2 == 0 );
271 0 0 0       $self->WriteLog( "CalculateSpearmans - File: \"$fileA\" Detected As CUI File" ) if ( $isCUI1 == 1 && $isCUI2 == 1 );
272 0 0 0       $self->SetIsFileOfWords( 1 ) if( $isCUI1 == 0 && $isCUI2 == 0 );
273 0 0 0       $self->SetIsFileOfWords( 0 ) if( $isCUI1 == 1 && $isCUI2 == 1 );
274            
275 0 0 0       $fileAIsCUIFile = 0 if ( $isCUI1 == 0 && $isCUI2 == 0 );
276 0 0 0       $fileAIsCUIFile = 1 if ( $isCUI1 == 1 && $isCUI2 == 1 );
277 0           $bCUICheck = 1;
278            
279             # Check(s)
280 0 0 0       $self->WriteLog( "CalculateSpearmans - Error: \"$fileB\" - Term1 Is CUI and Term2 Is Word" ) if ( $isCUI1 == 1 && $isCUI2 == 0 );
281 0 0 0       $self->WriteLog( "CalculateSpearmans - Error: \"$fileB\" - Term1 Is Word and Term2 Is CUI" ) if ( $isCUI1 == 0 && $isCUI2 == 1 );
282 0 0         if ( $isCUI1 != $isCUI2 )
283             {
284 0           close( B );
285 0           $self->SetIsFileOfWords( undef );
286 0           $self->_ResetVariables();
287 0           return undef;
288             }
289             }
290            
291 0           my $cui1 = ""; my $cui2 = "";
  0            
292            
293 0 0 0       if( defined( $self->GetIsFileOfWords() ) && $self->GetIsFileOfWords() == 1 )
294             {
295 0           $cui1 = $term1;
296 0           $cui2 = $term2;
297             }
298             else
299             {
300 0           $term1 =~ /(C[0-9]+)/;
301 0 0         $cui1 = $1 if defined( $1 );
302            
303 0           $term2 =~ /(C[0-9]+)/;
304 0 0         $cui2 = $1 if defined( $1 );
305             }
306            
307 0 0         if( $score == -1.0 )
308             {
309 0           $bNegative++;
310 0           next;
311             }
312            
313 0           $bTotal++;
314 0           push( @{ $bHash{ $score } }, "$cui1 $cui2" );
  0            
315 0           $bList{ "$cui1 $cui2" }++;
316             }
317            
318             # Clean Up
319 0           $self->WriteLog( "CalculateSpearmans - Closing File: \"$fileB\"" );
320 0           $self->SetIsFileOfWords( $oldIsFileOfWords );
321 0           $errorOpeningFile = 0;
322 0           close( B );
323            
324             # Post Read File Check
325 0 0 0       $self->WriteLog( "CalculateSpearmans - Error: \"$fileA\" Detected As Word File And \"$fileB\" Detected As CUI File" ) if ( defined( $fileAIsCUIFile ) && defined( $fileBIsCUIFile ) && $fileAIsCUIFile == 0 && $fileBIsCUIFile == 1 );
      0        
      0        
326 0 0 0       $self->WriteLog( "CalculateSpearmans - Error: \"$fileA\" Detected As CUI File And \"$fileB\" Detected As Word File" ) if ( defined( $fileAIsCUIFile ) && defined( $fileBIsCUIFile ) && $fileAIsCUIFile == 1 && $fileBIsCUIFile == 0 );
      0        
      0        
327 0 0 0       if( defined( $fileAIsCUIFile ) && defined( $fileBIsCUIFile ) )
328             {
329 0 0 0       if( $fileAIsCUIFile == 0 && $fileBIsCUIFile == 1 )
    0 0        
330             {
331 0           $self->_ResetVariables();
332 0           return undef;
333             }
334             elsif( $fileAIsCUIFile == 1 && $fileBIsCUIFile == 0 )
335             {
336 0           $self->_ResetVariables();
337 0           return undef;
338             }
339             }
340            
341 0           $self->WriteLog( "CalculateSpearmans - Calculating Spearman's Rank Correlation" );
342            
343             # Calculate Spearman's Rank Correlation Score
344 0           $rank = 1;
345 0           for my $score ( sort( { $b<=>$a } keys %aHash ) )
  0            
346             {
347 0           my $count = 0;
348 0           my $computedRank = 0;
349 0           my $cRank = $rank + 1;
350            
351 0           for my $term ( @{ $aHash{ $score } } )
  0            
352             {
353 0 0         if( exists( $bList{ $term } ) )
354             {
355 0           $computedRank += $cRank;
356 0           $count++;
357 0           $cRank++;
358             }
359             }
360            
361 0 0         next if ( $count == 0 );
362            
363 0           $computedRank = $computedRank / $count;
364            
365 0           for my $term ( @{ $aHash{ $score } } )
  0            
366             {
367 0 0         next if( !exists( $bList{ $term } ) );
368            
369 0           $aRank{ $term } = $computedRank;
370 0           $aMean += $computedRank;
371 0           $aCount++;
372 0           $rank++;
373             }
374             }
375            
376 0           $self->_SetACount( $aCount );
377            
378             # Reset $rank
379 0           $rank = 0;
380            
381 0           for my $score ( sort( { $b<=>$a } keys %bHash ) )
  0            
382             {
383 0           my $count = 0;
384 0           my $computedRank = 0;
385 0           my $cRank = $rank + 1;
386            
387 0           for my $term ( @{ $bHash{ $score } } )
  0            
388             {
389 0 0         if( exists( $aList{ $term } ) )
390             {
391 0           $computedRank += $cRank;
392 0           $count++;
393 0           $cRank++;
394             }
395             }
396            
397 0 0         next if ( $count == 0 );
398            
399 0           $computedRank = $computedRank / $count;
400            
401 0           for my $term ( @{ $bHash{ $score } } )
  0            
402             {
403 0 0         next if( !exists( $aList{ $term } ) );
404            
405 0           $bRank{ $term } = $computedRank;
406 0           $bMean += $computedRank;
407 0           $bCount++;
408 0           $rank++;
409             }
410             }
411            
412 0           $self->_SetBCount( $bCount );
413            
414 0           $self->WriteLog( "CalculateSpearmans - ACount -> $aCount : BCount -> $bCount" );
415            
416             # Check
417 0 0         $self->WriteLog( "Error: aCount <= 0 / Cannot Continue" ) if ( $aCount <= 0 );
418 0 0         $self->WriteLog( "Error: bCount <= 0 / Cannot Continue" ) if ( $bCount <= 0 );
419 0 0 0       return undef if ( $aCount <= 0 || $bCount <= 0 );
420            
421 0           $aMean = $aMean / $aCount;
422 0           $bMean = $bMean / $bCount;
423            
424 0           my $numerator = 0;
425 0           my $aDenominator = 0;
426 0           my $bDenominator = 0;
427            
428 0           for my $term ( sort( keys %aRank ) )
429             {
430 0           my $ai = $aRank{ $term };
431 0           my $bi = $bRank{ $term };
432            
433 0           $numerator += ( ( $ai - $aMean ) * ( $bi - $bMean ) );
434            
435 0           $aDenominator += ( ( $ai - $aMean ) ** 2 );
436 0           $bDenominator += ( ( $bi - $bMean ) ** 2 );
437             }
438            
439 0           my $denominator = sqrt( $aDenominator * $bDenominator );
440            
441 0 0         if( $denominator <= 0 )
442             {
443 0           $self->WriteLog( "CalculateSpearmans - Correlation Cannot Be Calculated" );
444 0           $self->WriteLog( "File Does Not Contain Similar N-Grams" );
445 0           $self->_ResetVariables();
446 0           return undef;
447             }
448            
449 0           my $pearsons = $numerator / $denominator;
450 0           my $floatFormat = join( '', '%', '.', $self->GetPrecision(), 'f' );
451 0           my $score = sprintf( $floatFormat, $pearsons );
452            
453 0           my $aN = $aTotal - $aNegative;
454 0           my $bN = $bTotal - $bNegative;
455 0           my $N = $bN;
456            
457 0 0         $N = $aN if( $aN < $bN );
458            
459 0           $self->_SetNValue( $N );
460            
461 0           $self->WriteLog( "CalculateSpearmans - Spearman's Rank Correlation: $score" );
462 0 0         $self->WriteLog( "CalculateSpearmans - N: $N" ) if( defined( $self->GetPrintN() ) );
463            
464 0 0         $score = "$score $aCount : $bCount" if defined( $includeCountsInResults );
465            
466 0           $self->WriteLog( "CalculateSpearmans - Finished" );
467 0           return $score;
468             }
469            
470             sub IsFileWordOrCUIFile
471             {
472 0     0 1   my ( $self, $filePath ) = @_;
473            
474             # Check(s)
475 0 0         $self->WriteLog( "IsFileWordOrCUIFile - Error: File Path Not Defined" ) if !defined( $filePath );
476 0 0         return undef if !defined( $filePath );
477            
478 0 0         $self->WriteLog( "IsFileWordOrCUIFile - Error: File Path Eq Empty String" ) if ( $filePath eq "" );
479 0 0         return undef if ( $filePath eq "" );
480            
481 0 0         $self->WriteLog( "IsFileWordOrCUIFile - Error: File Does Not Exist" ) if !( -e $filePath );
482 0 0         return undef if !( -e $filePath );
483            
484 0           my $errorOpeningFile = 0;
485 0 0         open( FILE, "<:", "$filePath" ) or $errorOpeningFile = 1;
486            
487             # Check
488 0 0         if ( $errorOpeningFile == 1 )
489             {
490 0           $self->WriteLog( "IsFileWordOrCUIFile - Error Opening File: \"$filePath\"" );
491 0           close( FILE );
492 0           return undef;
493             }
494            
495             # Read First Line Of File
496 0           $_ = ;
497 0           chomp( $_ );
498 0           my ( $score, $term1, $term2 ) = split( '<>', $_ );
499            
500             # Format Check
501             # If Checking A Similarity File Without Spearman's Rank Correlation Scores, Adjust For This
502 0 0 0       if( defined( $score ) && defined( $term1 ) && !defined( $term2 ) )
      0        
503             {
504 0           $term2 = $term1;
505 0           $term1 = $score;
506 0           $score = 0.0;
507             }
508            
509             # Check(s)
510 0 0 0       $self->WriteLog( "IsFileWordOrCUIFile - Error: Input File Format" ) if !defined( $score ) || !defined( $term1 ) || !defined( $term2 );
      0        
511 0 0 0       return undef if !defined( $score ) || !defined( $term1 ) || !defined( $term2 );
      0        
512            
513 0           $score =~ s/[0-9].//g;
514 0 0         $self->WriteLog( "IsFileWordOrCUIFile - Warning: Score Contains Erroneous Data" ) if ( $score ne "" );
515            
516 0           my $isTerm1CUI = $self->_IsCUI( $term1 );
517 0           my $isTerm2CUI = $self->_IsCUI( $term2 );
518            
519 0 0 0       $self->WriteLog( "IsFileWordOrCUIFile - File Contains CUI Terms" ) if ( $isTerm1CUI == 1 && $isTerm2CUI == 1 );
520 0 0 0       $self->WriteLog( "IsFileWordOrCUIFile - File Contains Word Terms" ) if ( $isTerm1CUI == 0 && $isTerm2CUI == 0 );
521            
522 0           close( FILE );
523            
524 0 0 0       return "cui" if ( $isTerm1CUI == 1 && $isTerm2CUI == 1 );
525 0 0 0       return "word" if ( $isTerm1CUI == 0 && $isTerm2CUI == 0 );
526 0           return undef;
527             }
528            
529             sub _IsCUI
530             {
531 0     0     my ( $self, $term ) = @_;
532            
533             # Check
534 0 0         $self->WriteLog( "_IsCUI - No Term Defined" ) if !defined( $term );
535            
536 0           $term = lc( $term );
537 0           my @terms = split( 'c', $term );
538            
539             # Return False If There Are Not Two Elements After Splitting
540 0 0         return 0 if( @terms != 2 );
541            
542             # If $term Is CUI, Then First Element Should Be Empty String
543 0 0         return 0 if ( $terms[0] ne "" );
544            
545             # Remove Numbers From Second Element
546 0           $terms[1] =~ s/[0-9]//g;
547            
548             # If $term Is CUI, Then After Removing All Number From Second Element An Empty String Is All That Is Left
549 0 0         return 0 if ( $terms[1] ne "" );
550            
551 0           return 1;
552             }
553            
554             sub _ResetVariables
555             {
556 0     0     my ( $self ) = @_;
557 0           $self->_SetACount( -1 );
558 0           $self->_SetBCount( -1 );
559 0           $self->_SetNValue( -1 );
560             }
561            
562            
563             ######################################################################################
564             # Accessors
565             ######################################################################################
566            
567             sub GetDebugLog
568             {
569 0     0 1   my ( $self ) = @_;
570 0 0         $self->{ _debugLog } = 0 if !defined ( $self->{ _debugLog } );
571 0           return $self->{ _debugLog };
572             }
573            
574             sub GetWriteLog
575             {
576 0     0 1   my ( $self ) = @_;
577 0 0         $self->{ _writeLog } = 0 if !defined ( $self->{ _writeLog } );
578 0           return $self->{ _writeLog };
579             }
580            
581             sub GetFileHandle
582             {
583 0     0 1   my ( $self ) = @_;
584 0 0         $self->{ _fileHandle } = undef if !defined ( $self->{ _fileHandle } );
585 0           return $self->{ _fileHandle };
586             }
587            
588             sub GetPrecision
589             {
590 0     0 1   my ( $self ) = @_;
591 0 0         $self->{ _precision } = 4 if !defined ( $self->{ _precision } );
592 0           return $self->{ _precision };
593             }
594            
595             sub GetIsFileOfWords
596             {
597 0     0 1   my ( $self ) = @_;
598 0           return $self->{ _isFileOfWords };
599             }
600            
601             sub GetPrintN
602             {
603 0     0 1   my ( $self ) = @_;
604 0           return $self->{ _printN };
605             }
606            
607             sub GetACount
608             {
609 0     0 1   my ( $self ) = @_;
610 0           return $self->{ _aCount };
611             }
612            
613             sub GetBCount
614             {
615 0     0 1   my ( $self ) = @_;
616 0           return $self->{ _bCount };
617             }
618            
619             sub GetNValue
620             {
621 0     0 0   my ( $self ) = @_;
622 0           return $self->{ _NValue };
623             }
624            
625            
626             ######################################################################################
627             # Mutators
628             ######################################################################################
629            
630             sub SetPrecision
631             {
632 0     0 1   my ( $self, $temp ) = @_;
633 0 0         return $self->{ _precision } = $temp if defined ( $temp );
634             }
635            
636             sub SetIsFileOfWords
637             {
638 0     0 1   my ( $self, $temp ) = @_;
639 0           return $self->{ _isFileOfWords } = $temp;
640             }
641            
642             sub SetPrintN
643             {
644 0     0 1   my ( $self, $temp ) = @_;
645 0           return $self->{ _printN } = $temp;
646             }
647            
648             sub _SetACount
649             {
650 0     0     my ( $self, $temp ) = @_;
651 0           return $self->{ _aCount } = $temp;
652             }
653            
654             sub _SetBCount
655             {
656 0     0     my ( $self, $temp ) = @_;
657 0           return $self->{ _bCount } = $temp;
658             }
659            
660             sub _SetNValue
661             {
662 0     0     my ( $self, $temp ) = @_;
663 0           return $self->{ _NValue } = $temp;
664             }
665            
666            
667             ######################################################################################
668             # Debug Functions
669             ######################################################################################
670            
671             sub GetTime
672             {
673 0     0 1   my ( $self ) = @_;
674 0           my( $sec, $min, $hour ) = localtime();
675            
676 0 0         if( $hour < 10 )
677             {
678 0           $hour = "0$hour";
679             }
680            
681 0 0         if( $min < 10 )
682             {
683 0           $min = "0$min";
684             }
685            
686 0 0         if( $sec < 10 )
687             {
688 0           $sec = "0$sec";
689             }
690            
691 0           return "$hour:$min:$sec";
692             }
693            
694             sub GetDate
695             {
696 0     0 1   my ( $self ) = @_;
697 0           my ( $sec, $min, $hour, $mday, $mon, $year ) = localtime();
698            
699 0           $mon += 1;
700 0           $year += 1900;
701            
702 0           return "$mon/$mday/$year";
703             }
704            
705             sub WriteLog
706             {
707 0     0 1   my ( $self ) = shift;
708 0           my $string = shift;
709 0           my $printNewLine = shift;
710            
711 0 0         return if !defined ( $string );
712 0 0         $printNewLine = 1 if !defined ( $printNewLine );
713            
714            
715 0 0         if( $self->GetDebugLog() )
716             {
717 0 0         if( ref ( $self ) ne "Word2vec::Spearmans" )
718             {
719 0           print( GetDate() . " " . GetTime() . " - word2phrase: Cannot Call WriteLog() From Outside Module!\n" );
720 0           return;
721             }
722            
723 0 0         $string = "" if !defined ( $string );
724 0           print GetDate() . " " . GetTime() . " - word2phrase::$string";
725 0 0         print "\n" if( $printNewLine != 0 );
726             }
727            
728 0 0         if( $self->GetWriteLog() )
729             {
730 0 0         if( ref ( $self ) ne "Word2vec::Spearmans" )
731             {
732 0           print( GetDate() . " " . GetTime() . " - word2phrase: Cannot Call WriteLog() From Outside Module!\n" );
733 0           return;
734             }
735            
736 0           my $fileHandle = $self->GetFileHandle();
737            
738 0 0         if( defined( $fileHandle ) )
739             {
740 0           print( $fileHandle GetDate() . " " . GetTime() . " - word2phrase::$string" );
741 0 0         print( $fileHandle "\n" ) if( $printNewLine != 0 );
742             }
743             }
744             }
745            
746             #################### All Modules Are To Output "1"(True) at EOF ######################
747             1;
748            
749            
750             =head1 NAME
751            
752             Word2vec::Spearmans - Spearman's Rank Correlation Score Module
753            
754             =head1 SYNOPSIS
755            
756             use Word2vec::Spearmans;
757            
758             my $spearmans = Word2vec::Spearmans->new();
759             $spearmans->SetPrecision( 8 );
760             my $score = $spearmans->CalculateSpearmans( "MiniMayoSRS.comp_results", "MiniMayoSRS.coders", undef );
761             print( "Spearman's Rank Correlation Score: $score\n" );
762             undef( $spearmans );
763            
764             # Or
765            
766             use Word2vec::Spearmans;
767            
768             my $spearmans = Word2vec::Spearmans->new();
769             $spearmans->SetIsFileOfWords( 1 );
770             my $score = $spearmans->CalculateSpearmans( "MiniMayoSRS.terms.comp_results", "MiniMayoSRS.terms.coders", undef );
771             print( "Spearman's Rank Correlation Score: $score\n" );
772             undef( $spearmans );
773            
774             =head1 DESCRIPTION
775            
776             Word2vec::Spearmans is a Spearman's Rank Correlation Score Module for the Word2vec::Inteface package.
777            
778             =head2 Main Functions
779            
780             =head3 new
781            
782             Description:
783            
784             Returns a new 'Word2vec::Spearmans' module object.
785            
786             Note: Specifying no parameters implies default options.
787            
788             Default Parameters:
789             debugLog = 0
790             writeLog = 0
791             precision = 4
792             isFileOfWords = undef
793             N = undef
794             aCount = -1
795             bCount = -1
796             NValue = -1
797            
798             Input:
799            
800             $debugLog -> Instructs module to print debug statements to the console. (1 = True / 0 = False)
801             $writeLog -> Instructs module to print debug statements to a log file. (1 = True / 0 = False)
802             $isFileOfWords -> Specifies the word option, default is Auto-Detect. (undef = Auto-Detect, 0 = CUI Terms, 1 = Word Terms)
803             $N -> Specifies the N option, default is undef. (defined = Print N / undef = Do Not Print N)
804             $aCount -> Term count for $aFile post Spearman's Rank Correlation calculation.
805             $bCount -> Term count for $bFile post Spearman's Rank Correlation calculation.
806             $NValue -> N Value post Spearmans's Rank Correlation calculation.
807            
808             Warning: Only debugLog, writeLog, precision, word and N variables should be specified.
809            
810             Output:
811            
812             Word2vec::Spearmans object.
813            
814             Example:
815            
816             use Word2vec::Spearmans;
817            
818             my $spearmans = Word2vec::Spearmans->new();
819            
820             undef( $spearmans );
821            
822             =head3 DESTROY
823            
824             Description:
825            
826             Removes member variables and file handle from memory.
827            
828             Input:
829            
830             None
831            
832             Output:
833            
834             None
835            
836             Example:
837            
838             use Word2vec::Spearmans;
839            
840             my $spearmans = Word2vec::Spearmans->new();
841            
842             $spearmans->DESTROY();
843             undef( $spearmans );
844            
845             =head3 CalculateSpearmans
846            
847             Description:
848            
849             Calculates Spearman's Rank Correlation Score between two data-sets (files) using _precision, _isWordOfFile and _printN Variables.
850            
851             Note: _precision, _isFileOfWords and _printN variables must be set prior to calling this function or default values will be used.
852            
853             Input:
854            
855             $fileA -> File To Process
856             $fileB -> File To Process
857             $includeCountsInResults -> Specifies whether to return file counts in score. (undef = False / defined = True)
858            
859             Output:
860            
861             $value -> Spearman's Rank Correlation Score or "undef"
862            
863             Example:
864            
865             use Word2vec::Spearmans;
866            
867             my $spearmans = Word2vec::Spearmans->new();
868             $spearmans->SetPrecision( 8 );
869             my $score = $spearmans->CalculateSpearmans( "MiniMayoSRS.comp_results", "MiniMayoSRS.coders", undef );
870             print( "Spearman's Rank Correlation Score: $score\n" ) if defined( $score );
871             print( "Spearman's Rank Correlation Score: undef\n" ) if !defined( $score );
872             undef( $spearmans );
873            
874             # Or
875            
876             use Word2vec::Spearmans;
877            
878             my $spearmans = Word2vec::Spearmans->new();
879             $spearmans->SetIsFileOfWords( 1 );
880             my $score = $spearmans->CalculateSpearmans( "MiniMayoSRS.terms.comp_results", "MiniMayoSRS.terms.coders", 1 );
881             print( "Spearman's Rank Correlation Score: $score\n" ) if defined( $score );
882             print( "Spearman's Rank Correlation Score: undef\n" ) if !defined( $score );
883             undef( $spearmans );
884            
885             =head3 IsFileWordOrCUIFile
886            
887             Description:
888            
889             Determines if a file is composed of CUI or word terms by checking the first line.
890            
891             Input:
892            
893             $string -> File Path
894            
895             Output:
896            
897             $string -> "undef" = Unable to determine, "cui" = CUI Term File, "word" = Word Term File
898            
899             Example:
900            
901             use Word2vec::Spearmans;
902            
903             my $spearmans = Word2vec::Spearmans->new();
904             my $isWordOrCuiFile = $spearmans->IsFileWordOrCUIFile( "samples/MiniMayoSRS.terms" );
905            
906             print( "MiniMayoSRS.terms File Is A \"$isWordOrCuiFile\" File\n" ) if defined( $isWordOrCuiFile );
907             print( "Unable To Determine Type Of File\n" ) if !defined( $isWordOrCuiFile
908            
909             undef( $spearmans );
910            
911             =head3 _IsCUI
912            
913             Description:
914            
915             Checks to see whether passed string argument is a word or CUI term.
916            
917             Note: This is an internal function and should not be called.
918            
919             Input:
920            
921             $value -> String
922            
923             Output:
924            
925             $value -> 0 = Word Term, 1 = CUI Term
926            
927             Example:
928            
929             This is a private function and should not be utilized.
930            
931             =head3 _ResetVariables
932            
933             Description:
934            
935             Resets _aCount, _bCount and _NValue variables.
936            
937             Note: This is an internal function and should not be called.
938            
939             Input:
940            
941             None
942            
943             Output:
944            
945             None
946            
947             Example:
948            
949             This is a private function and should not be utilized.
950            
951             =head2 Accessor Functions
952            
953             =head3 GetDebugLog
954            
955             Description:
956            
957             Returns the _debugLog member variable set during Word2vec::Spearmans object initialization of new function.
958            
959             Input:
960            
961             None
962            
963             Output:
964            
965             $value -> 0 = False, 1 = True
966            
967             Example:
968            
969             use Word2vec::Spearmans;
970            
971             my $spearmans = Word2vec::Spearmans->new();
972             my $debugLog = $spearmans->GetDebugLog();
973            
974             print( "Debug Logging Enabled\n" ) if $debugLog == 1;
975             print( "Debug Logging Disabled\n" ) if $debugLog == 0;
976            
977             undef( $spearmans );
978            
979             =head3 GetWriteLog
980            
981             Description:
982            
983             Returns the _writeLog member variable set during Word2vec::Spearmans object initialization of new function.
984            
985             Input:
986            
987             None
988            
989             Output:
990            
991             $value -> 0 = False, 1 = True
992            
993             Example:
994            
995             use Word2vec::Spearmans;
996            
997             my $spearmans = Word2vec::Spearmans->new();
998             my $writeLog = $spearmans->GetWriteLog();
999            
1000             print( "Write Logging Enabled\n" ) if $writeLog == 1;
1001             print( "Write Logging Disabled\n" ) if $writeLog == 0;
1002            
1003             undef( $spearmans );
1004            
1005             =head3 GetFileHandle
1006            
1007             Description:
1008            
1009             Returns file handle used by WriteLog() method.
1010            
1011             Input:
1012            
1013             None
1014            
1015             Output:
1016            
1017             $fileHandle -> Returns file handle blob used by 'WriteLog()' function or undefined.
1018            
1019             Example:
1020            
1021            
1022            
1023             =head3 GetPrecision
1024            
1025             Description:
1026            
1027             Returns floating point precision value.
1028            
1029             Input:
1030            
1031             None
1032            
1033             Output:
1034            
1035             $value -> Spearmans Float Precision Value
1036            
1037             Example:
1038            
1039             use Word2vec::Spearmans;
1040            
1041             my $spearmans = Word2vec::Spearmans->new();
1042             my $value = $spearmans->GetPrecision();
1043            
1044             print( "Float Precision Value: $value\n" ) if defined( $value );
1045             undef( $spearmans );
1046            
1047             =head3 GetIsFileOfWords
1048            
1049             Description:
1050            
1051             Returns the variable indicating whether the files to be parsed are files consisting of words or CUI terms.
1052            
1053             Input:
1054            
1055             None
1056            
1057             Output:
1058            
1059             $value -> "undef = Auto-Detect, 0 = CUI Terms, 1 = Word Terms"
1060            
1061             Example:
1062            
1063             use Word2vec::Spearmans;
1064            
1065             my $spearmans = Word2vec::Spearmans->new();
1066             my $isFileOfWords = $spearmans->GetIsFileOfWords();
1067            
1068             print( "IsFileOfWords Is Undefined\n" ) if !defined( $isFileOfWords );
1069             print( "IsFileOfWords Value: $isFileOfWords\n" ) if defined( $isFileOfWords );
1070             undef( $spearmans );
1071            
1072             =head3 GetPrintN
1073            
1074             Description:
1075            
1076             Returns the variable indicating whether to print NValue.
1077            
1078             Input:
1079            
1080             None
1081            
1082             Output:
1083            
1084             $value -> "undef" = Do not print NValue, "defined" = Print NValue
1085            
1086             Example:
1087            
1088             use Word2vec::Spearmans;
1089            
1090             my $spearmans = Word2vec::Spearmans->new();
1091             my $printN = $spearmans->GetPrintN();
1092             print "Print N\n" if defined( $printN );
1093             print "Do Not Print N\n" if !defined( $printN );
1094            
1095             undef( $spearmans );
1096            
1097             =head3 GetACount
1098            
1099             Returns the non-negative count for file A.
1100            
1101             Input:
1102            
1103             None
1104            
1105             Output:
1106            
1107             $value -> Integer
1108            
1109             Example:
1110            
1111             use Word2vec::Spearmans;
1112            
1113             my $spearmans = Word2vec::Spearmans->new();
1114             print "A Count: " . $spearmans->GetACount() . "\n";
1115            
1116             undef( $spearmans );
1117            
1118             =head3 GetBCount
1119            
1120             Returns the non-negative count for file B.
1121            
1122             Input:
1123            
1124             None
1125            
1126             Output:
1127            
1128             $value -> Integer
1129            
1130             Example:
1131            
1132             use Word2vec::Spearmans;
1133            
1134             my $spearmans = Word2vec::Spearmans->new();
1135             print "B Count: " . $spearmans->GetBCount() . "\n";
1136            
1137             undef( $spearmans );
1138            
1139             =head3 SpGetNValue
1140            
1141             Returns the N value.
1142            
1143             Input:
1144            
1145             None
1146            
1147             Output:
1148            
1149             $value -> Integer
1150            
1151             Example:
1152            
1153             use Word2vec::Spearmans;
1154            
1155             my $spearmans = Word2vec::Spearmans->new();
1156             print "N Value: " . $spearmans->GetNValue() . "\n";
1157            
1158             undef( $spearmans );
1159            
1160             =head2 Mutator Functions
1161            
1162             =head3 SetPrecision
1163            
1164             Description:
1165            
1166             Sets number of decimal places after the decimal point of the Spearman's Rank Correlation Score to represent.
1167            
1168             Input:
1169            
1170             $value -> Integer
1171            
1172             Output:
1173            
1174             None
1175            
1176             Example:
1177            
1178             use Word2vec::Spearmans;
1179            
1180             my $spearmans = Word2vec::Spearmans->new();
1181             $spearmans->SetPrecision( 8 );
1182             my $score = $spearmans->CalculateSpearmans( "samples/MiniMayoSRS.term.comp_results", "Similarity/MiniMayoSRS.terms.coders", undef );
1183             print "Spearman's Rank Correlation Score: $score\n" if defined( $score );
1184             print "Spearman's Rank Correlation Score: undef\n" if !defined( $score );
1185            
1186             undef( $spearmans );
1187            
1188             =head3 SetIsFileOfWords
1189            
1190             Specifies the main method to auto-detect if file consists of CUI or Word terms, or manual override with user setting.
1191            
1192             Input:
1193            
1194             $value -> "undef" = Auto-Detect, 0 = CUI Terms, 1 = Word Terms
1195            
1196             Output:
1197            
1198             None
1199            
1200             Example:
1201            
1202             use Word2vec::Spearmans;
1203            
1204             my $spearmans = Word2vec::Spearmans->new();
1205             $spearmans->SetIsFileOfWords( undef );
1206             my $score = $spearmans->CalculateSpearmans( "samples/MiniMayoSRS.term.comp_results", "Similarity/MiniMayoSRS.terms.coders", undef );
1207             print "Spearman's Rank Correlation Score: $score\n" if defined( $score );
1208             print "Spearman's Rank Correlation Score: undef\n" if !defined( $score );
1209            
1210             undef( $spearmans );
1211            
1212             =head3 SetPrintN
1213            
1214             Specifies the main method print _NValue post Spearmans::CalculateSpearmans() function completion.
1215            
1216             Input:
1217            
1218             $value -> "undef" = Do Not Print _NValue, "defined" = Print _NValue
1219            
1220             Output:
1221            
1222             None
1223            
1224             Example:
1225            
1226             use Word2vec::Spearmans;
1227            
1228             my $spearmans = Word2vec::Spearmans->new();
1229             $spearmans->SetPrintN( 1 );
1230             my $score = $spearmans->CalculateSpearmans( "samples/MiniMayoSRS.term.comp_results", "Similarity/MiniMayoSRS.terms.coders", undef );
1231             print "Spearman's Rank Correlation Score: $score\n" if defined( $score );
1232             print "Spearman's Rank Correlation Score: undef\n" if !defined( $score );
1233            
1234             undef( $spearmans );
1235            
1236             =head3 _SetACount
1237            
1238             Description:
1239            
1240             Sets _aCount variable.
1241            
1242             Note: This is an internal function and should not be called.
1243            
1244             Input:
1245            
1246             $value -> Integer
1247            
1248             Output:
1249            
1250             None
1251            
1252             Example:
1253            
1254             This is a private function and should not be utilized.
1255            
1256             =head3 _SetBCount
1257            
1258             Description:
1259            
1260             Sets _bCount variable.
1261            
1262             Note: This is an internal function and should not be called.
1263            
1264             Input:
1265            
1266             $value -> Integer
1267            
1268             Output:
1269            
1270             None
1271            
1272             Example:
1273            
1274             This is a private function and should not be utilized.
1275            
1276             =head3 _SetNValue
1277            
1278             Description:
1279            
1280             Sets _NValue variable.
1281            
1282             Note: This is an internal function and should not be called.
1283            
1284             Input:
1285            
1286             $value -> Integer
1287            
1288             Output:
1289            
1290             None
1291            
1292             Example:
1293            
1294             This is a private function and should not be utilized.
1295            
1296             =head2 Debug Functions
1297            
1298             =head3 GetTime
1299            
1300             Description:
1301            
1302             Returns current time string in "Hour:Minute:Second" format.
1303            
1304             Input:
1305            
1306             None
1307            
1308             Output:
1309            
1310             $string -> XX:XX:XX ("Hour:Minute:Second")
1311            
1312             Example:
1313            
1314             use Word2vec::Spearmans:
1315            
1316             my $spearmans = Word2vec::Spearmans->new();
1317             my $time = $spearmans->GetTime();
1318            
1319             print( "Current Time: $time\n" ) if defined( $time );
1320            
1321             undef( $spearmans );
1322            
1323             =head3 GetDate
1324            
1325             Description:
1326            
1327             Returns current month, day and year string in "Month/Day/Year" format.
1328            
1329             Input:
1330            
1331             None
1332            
1333             Output:
1334            
1335             $string -> XX/XX/XXXX ("Month/Day/Year")
1336            
1337             Example:
1338            
1339             use Word2vec::Spearmans:
1340            
1341             my $spearmans = Word2vec::Spearmans->new();
1342             my $date = $spearmans->GetDate();
1343            
1344             print( "Current Date: $date\n" ) if defined( $date );
1345            
1346             undef( $spearmans );
1347            
1348             =head3 WriteLog
1349            
1350             Description:
1351            
1352             Prints passed string parameter to the console, log file or both depending on user options.
1353            
1354             Note: printNewLine parameter prints a new line character following the string if the parameter
1355             is undefined and does not if parameter is 0.
1356            
1357             Input:
1358            
1359             $string -> String to print to the console/log file.
1360             $value -> 0 = Do not print newline character after string, all else prints new line character including 'undef'.
1361            
1362             Output:
1363            
1364             None
1365            
1366             Example:
1367            
1368             use Word2vec::Spearmans:
1369            
1370             my $spearmans = Word2vec::Spearmans->new();
1371             $spearmans->WriteLog( "Hello World" );
1372            
1373             undef( $spearmans );
1374            
1375             =head1 Author
1376            
1377             Bridget T McInnes, Virginia Commonwealth University
1378             Clint Cuffy, Virginia Commonwealth University
1379            
1380             =head1 COPYRIGHT
1381            
1382             Copyright (c) 2016
1383            
1384             Bridget T McInnes, Virginia Commonwealth University
1385             btmcinnes at vcu dot edu
1386            
1387             Clint Cuffy, Virginia Commonwealth University
1388             cuffyca at vcu dot edu
1389            
1390             This program is free software; you can redistribute it and/or modify it
1391             under the terms of the GNU General Public License as published by the Free
1392             Software Foundation; either version 2 of the License, or (at your option)
1393             any later version.
1394            
1395             This program is distributed in the hope that it will be useful, but WITHOUT
1396             ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1397             FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1398            
1399             You should have received a copy of the GNU General Public License along with
1400             this program; if not, write to:
1401            
1402             The Free Software Foundation, Inc.,
1403             59 Temple Place - Suite 330,
1404             Boston, MA 02111-1307, USA.
1405            
1406             =cut