forked from sheffieldnlp/stance-conditional
-
Notifications
You must be signed in to change notification settings - Fork 0
/
eval.pl
executable file
·160 lines (128 loc) · 4.51 KB
/
eval.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/usr/bin/perl
##########################################
#This script is originally created to evaluate Semeval-2016 Task 6:
#Detecting Stance in Tweets
#http://alt.qcri.org/semeval2016/task6/
#
#Author: Xiaodan Zhu (www.xiaodanzhu.com)
#
#Created date: Oct. 1, 2015
#
#This simple script is free but if you choose to modify it
#please include the description above.
##########################################
##########################################
#For usage, type perl eval.pl -u
##########################################
use strict;
if(@ARGV == 1 && $ARGV[0] eq "-u"){
printUsage();
die "\n";
}
if(@ARGV != 2){
print STDERR "\nError: Number of parameters are incorrect!\n";
printUsage();
die "\n";
}
my $fnGold = $ARGV[0];
open(IN, $fnGold) || die "Error: Cannot open the gold-standard file.\n";
my @goldLns = <IN>;
chomp @goldLns;
close(IN);
my $fnGuess = $ARGV[1];
open(IN, $fnGuess) || die "Error: Cannot open the file containing your prediction.\n";
my @guessLns = <IN>;
chomp @guessLns;
close(IN);
if(@guessLns != @goldLns){
print STDERR "\nError: make sure the number of lines in your prediction file is same as that in the gold-standard file!\n";
print STDERR sprintf("The gold-standard file contains %d lines, but the prediction file contains %d lines.\n", scalar(@goldLns), scalar(@guessLns));
die "\n";
}
my @cats = ("FAVOR", "AGAINST", "NONE", "UNKNOWN");
my %catsHash = map{$_ => 1}@cats;
my %numOfTruePosOfEachCat = ();
my %numOfGuessOfEachCat = ();
my %numOfGoldOfEachCat = ();
for (my $i = 0; $i < @guessLns; $i+=1) {
my $guessLn = $guessLns[$i];
$guessLn =~ s/\r//g;
my $goldLn = $goldLns[$i];
$goldLn =~ s/\r//g;
if($goldLn eq "ID Target Tweet Stance"){
next;
}
my @goldArr = split(/\t/, $goldLn);
if(@goldArr != 4){
print STDERR sprintf("\nError: the following line in the gold-standard file does not have a correct format:\n\n%s\n\n",$goldLn);
print STDERR "Correct format: ID<Tab>Target<Tab>Tweet<Tab>Stance\n";
die "\n";
}
my @guessArr = split(/\t/, $guessLn);
if(@guessArr != 4){
print STDERR sprintf("\nError: the following line in your prediction file does not have a correct format:\n\n%s\n\n",$guessLn);
print STDERR "Correct format: ID<Tab>Target<Tab>Tweet<Tab>Stance";
die "\n";
}
my $guessLbl = $guessArr[3];
my $goldLbl = $goldArr[3];
if(!defined($catsHash{$goldLbl})){
print STDERR sprintf("\nError: the stance label \"%s\" in the following line of the gold-standard file is invalid:\n\n%s\n\n",$goldLbl, $goldLn);
print STDERR "Correct labels in gold-standard file can be: FAVOR, AGAINST, NONE, or UNKNOWN (case sensitive). \n";
die "\n";
}
if(!defined($catsHash{$guessLbl})){
print STDERR sprintf("\nError: the stance label \"%s\" in the following line of the prediction file is invalid:\n\n%s\n\n",$guessLbl, $guessLn);
print STDERR "Correct labels in predication file can be: FAVOR, AGAINST, NONE, or UNKNOWN (case sensitive). \n";
die "\n";
}
$numOfGoldOfEachCat{$goldLbl} += 1;
$numOfGuessOfEachCat{$guessLbl} += 1;
if($guessLbl eq $goldLbl){
$numOfTruePosOfEachCat{$guessLbl} += 1;
}
}
#compute precision, recall, and f-score
my %precByCat = ();
my %recallByCat = ();
my %fByCat = ();
my $macroF = 0.0;
foreach my $cat (@cats) {
my $nTp = $numOfTruePosOfEachCat{$cat};
my $nGuess = $numOfGuessOfEachCat{$cat};
my $nGold = $numOfGoldOfEachCat{$cat};
my $p = 0;
my $r = 0;
my $f = 0;
$p = $nTp/$nGuess if($nGuess != 0);
$r = $nTp/$nGold if($nGold != 0);
$f = 2*$p*$r/($p+$r) if($p + $r != 0);
$precByCat{$cat} = $p;
$recallByCat{$cat} = $r;
$fByCat{$cat} = $f;
}
#print results
my $macroF = 0.0;
print STDOUT sprintf("\n\n============\n");
print STDOUT sprintf("Results \n");
print STDOUT sprintf("============\n");
my $nCat = 0;
foreach my $cat (@cats) {
if($cat eq "FAVOR" || $cat eq "AGAINST"){
$nCat += 1;
$macroF += $fByCat{$cat};
print STDOUT sprintf("%-9s precision: %.4f recall: %.4f f-score: %.4f\n", $cat, $precByCat{$cat}, $recallByCat{$cat}, $fByCat{$cat});
}
}
$macroF = $macroF/$nCat;
print STDOUT sprintf("------------\n");
print STDOUT sprintf("Macro F: %.4f\n\n", $macroF);
sub printUsage {
print STDERR "\n---------------------------\n";
print STDERR "Usage:\nperl eval.pl goldFile guessFile\n\n";
print STDERR "goldFile: file containing gold standards;\nguessFile: file containing your prediction.\n\n";
print STDERR "These two files have the same format:\n";
print STDERR "ID<Tab>Target<Tab>Tweet<Tab>Stance\n";
print STDERR "Only stance labels may be different between them!\n";
print STDERR "---------------------------\n";
}