Spaces:
Sleeping
Sleeping
RGB Evaluation commited on
Commit ·
5253a83
1
Parent(s): b1ccc5d
fix: Information Integration evaluation - handle multiple answer variants with pipe-separated format
Browse files- src/data_loader.py +19 -3
- src/evaluator.py +41 -2
src/data_loader.py
CHANGED
|
@@ -83,10 +83,26 @@ class RGBDataLoader:
|
|
| 83 |
return data
|
| 84 |
|
| 85 |
def _format_answer(self, answer: Any) -> str:
|
| 86 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
if isinstance(answer, list):
|
| 88 |
-
#
|
| 89 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
return str(answer)
|
| 91 |
|
| 92 |
def load_noise_robustness(
|
|
|
|
| 83 |
return data
|
| 84 |
|
| 85 |
def _format_answer(self, answer: Any) -> str:
|
| 86 |
+
"""
|
| 87 |
+
Format answer to string for comparison.
|
| 88 |
+
For nested lists (information integration), flatten to list of alternatives.
|
| 89 |
+
For simple lists (noise robustness), take first or join.
|
| 90 |
+
"""
|
| 91 |
if isinstance(answer, list):
|
| 92 |
+
# Check if it's a nested list (from en_int.json with answer variants)
|
| 93 |
+
if answer and isinstance(answer[0], list):
|
| 94 |
+
# Flatten nested list: [['variant1', 'variant2'], 'other_answer'] → all variants
|
| 95 |
+
variants = []
|
| 96 |
+
for item in answer:
|
| 97 |
+
if isinstance(item, list):
|
| 98 |
+
variants.extend(item)
|
| 99 |
+
else:
|
| 100 |
+
variants.append(str(item))
|
| 101 |
+
# Return as pipe-separated alternatives for matching
|
| 102 |
+
return "|".join(variants)
|
| 103 |
+
else:
|
| 104 |
+
# Simple list: join with pipe as alternatives
|
| 105 |
+
return "|".join(str(a) for a in answer)
|
| 106 |
return str(answer)
|
| 107 |
|
| 108 |
def load_noise_robustness(
|
src/evaluator.py
CHANGED
|
@@ -143,6 +143,7 @@ class RGBEvaluator:
|
|
| 143 |
"""
|
| 144 |
Normalize an answer for comparison.
|
| 145 |
Removes punctuation, extra whitespace, and converts to lowercase.
|
|
|
|
| 146 |
"""
|
| 147 |
if not answer:
|
| 148 |
return ""
|
|
@@ -153,6 +154,9 @@ class RGBEvaluator:
|
|
| 153 |
# Remove common punctuation at the end
|
| 154 |
answer = re.sub(r'[.!?,;:]+$', '', answer)
|
| 155 |
|
|
|
|
|
|
|
|
|
|
| 156 |
# Remove extra whitespace
|
| 157 |
answer = ' '.join(answer.split())
|
| 158 |
|
|
@@ -187,19 +191,54 @@ class RGBEvaluator:
|
|
| 187 |
def is_correct(self, response: str, ground_truth: str, strict: bool = False) -> bool:
|
| 188 |
"""
|
| 189 |
Check if the response matches the ground truth answer.
|
|
|
|
| 190 |
|
| 191 |
Args:
|
| 192 |
response: The model's response.
|
| 193 |
-
ground_truth: The correct answer.
|
| 194 |
strict: If True, requires exact match. If False, allows partial match.
|
| 195 |
|
| 196 |
Returns:
|
| 197 |
True if the answer is correct, False otherwise.
|
| 198 |
"""
|
| 199 |
norm_response = self.normalize_answer(response)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
norm_truth = self.normalize_answer(ground_truth)
|
| 201 |
|
| 202 |
-
if not
|
| 203 |
return False
|
| 204 |
|
| 205 |
if strict:
|
|
|
|
| 143 |
"""
|
| 144 |
Normalize an answer for comparison.
|
| 145 |
Removes punctuation, extra whitespace, and converts to lowercase.
|
| 146 |
+
Also removes commas from dates for consistent matching.
|
| 147 |
"""
|
| 148 |
if not answer:
|
| 149 |
return ""
|
|
|
|
| 154 |
# Remove common punctuation at the end
|
| 155 |
answer = re.sub(r'[.!?,;:]+$', '', answer)
|
| 156 |
|
| 157 |
+
# Remove all commas within the text (helps with date matching like "Jan, 2, 2022" -> "jan 2 2022")
|
| 158 |
+
answer = answer.replace(',', '')
|
| 159 |
+
|
| 160 |
# Remove extra whitespace
|
| 161 |
answer = ' '.join(answer.split())
|
| 162 |
|
|
|
|
| 191 |
def is_correct(self, response: str, ground_truth: str, strict: bool = False) -> bool:
|
| 192 |
"""
|
| 193 |
Check if the response matches the ground truth answer.
|
| 194 |
+
Supports pipe-separated alternatives (for information integration with variants).
|
| 195 |
|
| 196 |
Args:
|
| 197 |
response: The model's response.
|
| 198 |
+
ground_truth: The correct answer (can be pipe-separated alternatives).
|
| 199 |
strict: If True, requires exact match. If False, allows partial match.
|
| 200 |
|
| 201 |
Returns:
|
| 202 |
True if the answer is correct, False otherwise.
|
| 203 |
"""
|
| 204 |
norm_response = self.normalize_answer(response)
|
| 205 |
+
|
| 206 |
+
if not norm_response:
|
| 207 |
+
return False
|
| 208 |
+
|
| 209 |
+
# Handle pipe-separated alternatives (information integration with answer variants)
|
| 210 |
+
if "|" in ground_truth:
|
| 211 |
+
alternatives = [self.normalize_answer(alt.strip()) for alt in ground_truth.split("|")]
|
| 212 |
+
# Check if response matches ANY of the alternatives
|
| 213 |
+
for alternative in alternatives:
|
| 214 |
+
if not alternative:
|
| 215 |
+
continue
|
| 216 |
+
|
| 217 |
+
# Check each matching strategy for this alternative
|
| 218 |
+
if strict:
|
| 219 |
+
if norm_response == alternative:
|
| 220 |
+
return True
|
| 221 |
+
else:
|
| 222 |
+
# Substring match
|
| 223 |
+
if alternative in norm_response:
|
| 224 |
+
return True
|
| 225 |
+
# Short answer in long answer
|
| 226 |
+
if len(norm_response) < len(alternative) and norm_response in alternative:
|
| 227 |
+
return True
|
| 228 |
+
# Token overlap
|
| 229 |
+
truth_tokens = set(alternative.split())
|
| 230 |
+
response_tokens = set(norm_response.split())
|
| 231 |
+
if len(truth_tokens) > 0:
|
| 232 |
+
overlap = len(truth_tokens & response_tokens) / len(truth_tokens)
|
| 233 |
+
if overlap >= 0.8:
|
| 234 |
+
return True
|
| 235 |
+
|
| 236 |
+
return False
|
| 237 |
+
|
| 238 |
+
# Single answer (original logic)
|
| 239 |
norm_truth = self.normalize_answer(ground_truth)
|
| 240 |
|
| 241 |
+
if not norm_truth:
|
| 242 |
return False
|
| 243 |
|
| 244 |
if strict:
|