///|
fn contains_gold(pair : AlignmentPair, gold_pairs : Array[GoldPair]) -> Bool {
for gold in gold_pairs {
if pair.source_start == gold.source_start &&
pair.source_end == gold.source_end &&
pair.target_start == gold.target_start &&
pair.target_end == gold.target_end {
return true
}
}
false
}
///|
pub fn evaluate(
report : AlignmentReport,
gold_pairs : Array[GoldPair],
) -> AlignmentMetrics {
let mut exact_pairs = 0
let mut merged_pairs = 0
let mut source_covered = 0
let mut target_covered = 0
let mut score_total = 0.0
for pair in report.pairs {
if contains_gold(pair, gold_pairs) {
exact_pairs += 1
}
if pair.source_end - pair.source_start > 1 ||
pair.target_end - pair.target_start > 1 {
merged_pairs += 1
}
source_covered += pair.source_end - pair.source_start
target_covered += pair.target_end - pair.target_start
score_total += pair.score
}
let predicted_count = report.pairs.length()
let gold_count = gold_pairs.length()
let precision = if predicted_count == 0 {
0.0
} else {
exact_pairs.to_double() / predicted_count.to_double()
}
let recall = if gold_count == 0 {
0.0
} else {
exact_pairs.to_double() / gold_count.to_double()
}
let f1 = if precision + recall < 0.000001 {
0.0
} else {
2.0 * precision * recall / (precision + recall)
}
let source_coverage = if report.source_count == 0 {
1.0
} else {
source_covered.to_double() / report.source_count.to_double()
}
let target_coverage = if report.target_count == 0 {
1.0
} else {
target_covered.to_double() / report.target_count.to_double()
}
let average_score = if predicted_count == 0 {
0.0
} else {
score_total / predicted_count.to_double()
}
{
predicted_pairs: predicted_count,
gold_pairs: gold_count,
exact_pairs,
precision,
recall,
f1,
source_coverage,
target_coverage,
merged_pairs,
average_score,
}
}
///|
pub fn benchmark_case(case : BenchmarkCase) -> BenchmarkResult {
let report = align(case.source, case.target)
{
name: case.name,
metrics: evaluate(report, case.gold_pairs),
warnings: report.warnings,
}
}
///|
pub fn benchmark_suite() -> Array[BenchmarkResult] {
let results = []
for case in benchmark_cases() {
results.push(benchmark_case(case))
}
results
}
///|
pub fn benchmark_to_json_string(indent? : Int = 2) -> String {
benchmark_suite().to_json().stringify(indent~)
}