#!/usr/bin/perl # # Usage: nphp-eval.pl # # Compute the mean reciprocal rank for runs for TREC 2005 Terabyte Track # named-page finding task. # The arguments to the script are: # run_list: the name of the file containing the tags of the runs to # be evaluated, one tag per line (can be created from # the runs table) # qrels: the name of the qrels file to use when evaluating # Use the simple, brute-force approach---read judgment file into memory # and sort submission file by topic-id, rank. Read in 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. # Compute score for each topic and mean over all topics. $#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; $judgments{$t}{$docno} = $judgment; } close QRELS || die "Close of homepages file failed: $!\n"; $oldt = -1; $sum = 0; $notfound = 0; $top10 = 0; $num_qs = 0; %retrieved = (); while ($line = ) { chomp $line; ($t, $q0, $docno, $given_rank, $sim, $xtag) = split " ", $line, 6; next unless exists $judgments{$t}; if ($t != $oldt) { # print oldt's score and add to running sum for average # re-initialize for current topic if ($oldt != -1) { # i.e., not very first topics $trank = score($oldt, \%retrieved); if ($trank != 0) { # had answer $recip = 1 / $trank; printf "Topic %3d: Named page found at rank %d\n", $oldt, $trank; $sum += $recip; if ($trank <= 10) { $top10++; } } else { #no answer printf "Topic %3d: No correct named page found.\n", $oldt; $notfound++; } } $trank = 0; %retrieved = (); $num_qs++; $oldt = $t; } if (exists $retrieved{$given_rank}) { die "Run $tag, topic $t: Two documents ($docno and $retrieved{$given_rank}) both have rank $given_rank\n"; } $retrieved{$given_rank} = $docno; } close(RUN); if ($t != 0) { # i.e., submission file not empty $trank = score($t, \%retrieved); if ($trank != 0) { # last q had answer $recip = 1 / $trank; printf "Topic %3d: Named page found at rank %d.\n", $oldt, $trank; $sum += $recip; if ($trank <= 10) { $top10++; } } else { #no answer printf "Topic %3d: No correct named page found.\n", $oldt; $notfound++; } } $ave = $sum / $num_qs; printf "\nAverage reciprocal rank over $num_qs topics: %.3f\n", $ave; printf "Number of topics for which named page found in top 10: %d (%.1f%%)\n", $top10, ($top10/$num_qs)*100; printf "Number of topics for which no named page 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; }