#!/usr/bin/perl # # Usage: nphp-eval.pl # # (this script was called 'MRR-rank.pl' in TREC 11) # Compute the mean reciprocal rank for runs for TREC 2005 Enterprise # Track known-item finding task. # The arguments to the script are: # run_file: the name of the run file to be evaluated # qrels: the name of the qrels file to use when evaluating # Use the simple, brute-force approach---read judgment file into # memory and then read the run file. Locate targets for each # question, find first (if any) correct answer and compute score. # Finally report total number topics with no named page found and mean # reciprocal. $#ARGV == 1 || die "Usage: nphp-eval.pl run_file qrels\n"; $run_file = $ARGV[0]; $qrels = $ARGV[1]; if ( (! -e $run_file) || (! open RUN, "<$run_file") ) { die "Can't find/open run file `$run_file': $!\n"; } # read in judgment file if ( (! -e $qrels) || (! open QRELS, "<$qrels") ) { die "Can't find/open homepages file `$qrels': $!\n"; } while ($line = ) { chomp $line; ($t,$z,$docno,$judgment) = split " ",$line, 4; $t =~ s/^KI//; $judgments{$t}{$docno} = $judgment; } close QRELS || die "Close of homepages file failed: $!\n"; $num_qs = scalar(keys %judgments); %retrieved = (); while ($line = ) { chomp $line; ($t, $q0, $docno, $given_rank, $sim, $xtag) = split " ", $line, 6; $t =~ s/^KI//; next unless exists $judgments{$t}; if (exists $retrieved{$t}{$given_rank}) { die "Run $tag, topic $t: Two documents ($docno and $retrieved{$given_rank}) both have rank $given_rank\n"; } $retrieved{$t}{$given_rank} = $docno; } close RUN; $notfound = 0; $sum = 0; $top10 = 0; %tranks = (); for my $topic (sort { $a <=> $b } keys %judgments) { $tranks{$topic} = score($topic, $retrieved{$topic}); if ($tranks{$topic} == 0) { $notfound++; printf "Topic %3d: No target page found.\n", $topic; } else { my $recip = 1.0 / $tranks{$topic}; $sum += $recip; if ($tranks{$topic} <= 10) { $top10++; } printf "Topic %3d: Target page found at rank %d\n", $topic, $tranks{$topic}; } } $ave = $sum / $num_qs; printf "\nAverage reciprocal rank over $num_qs topics: %.3f\n", $ave; printf "Number of topics for which target page found in top 10: %d (%.1f%%)\n", $top10, ($top10/$num_qs)*100; printf "Number of topics for which no target was found: %d (%.1f%%)\n", $notfound, ($notfound/$num_qs)*100; sub numerically { $a <=> $b } sub score { my ($topic, $retr) = @_; my $rank = 1; my $trank = 0; for my $scr (sort numerically keys %$retr) { if ($judgments{$topic}{$retr->{$scr}} == 1) { $trank = $rank; last; } $rank++; } return $trank; }