-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmmr_evaluate_rules.py
More file actions
154 lines (127 loc) · 5.06 KB
/
Copy pathmmr_evaluate_rules.py
File metadata and controls
154 lines (127 loc) · 5.06 KB
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
# -*- coding: utf-8 -*-
"""MMR_Evaluate_Rules.ipynb
Automatically generated by Colab.
Original file is located at
https://colab.research.google.com/drive/1QzpS4Haovj5VyDERDKNsc_RwsujyALU7
"""
from google.colab import drive
drive.mount('/content/drive')
import json
import re
# Process the file
file_path = '/content/drive/My Drive/World Models/responses.json'
def text_to_number(text):
"""
Convert textual representation of numbers to numerical format.
E.g., "Zero" -> 0, "One" -> 1
"""
text = text.strip().lower()
number_map = {
"zero": 0,
"one": 1,
"two": 2,
"three": 3,
"four": 4,
"five": 5,
"six": 6,
"seven": 7,
"eight": 8,
"nine": 9,
"ten": 10
}
return number_map.get(text, None)
def evaluate_response_fixed(problem):
"""
Enhanced evaluation for multi-choice and other types of responses.
Properly handles cases where response contains option letters (e.g., "A") or option content.
"""
response = problem.get('response', '').strip()
answer = problem.get('answer', '').strip()
answer_type = problem.get('answer_type', '')
choices = problem.get('choices', None)
# Handle missing fields
if not response or not answer or not answer_type:
return False
try:
# Handle multiple-choice questions
if problem.get('question_type') == 'multi_choice':
# Extract the selected option from response
match = re.search(r'Answer:?[ \(]?([A-Z])[\)]? ?.*', response, re.IGNORECASE)
selected_option = match.group(1).upper() if match else response.upper()
if choices:
# Check if response is a valid option letter
if selected_option in [chr(65 + i) for i in range(len(choices))]:
selected_answer = choices[ord(selected_option) - 65]
# Normalize and compare with the expected answer
if selected_answer.strip().lower() == answer.lower():
return True
# Directly compare response to answer (if response is option content)
if response.strip().lower() == answer.lower():
return True
# Check if both response and answer contain "yes" but not "no", or contain "no" but not "yes"
response_lower = response.lower()
answer_lower = answer.lower()
if ("yes" in response_lower and "yes" in answer_lower and "no" not in response_lower and "no" not in answer_lower) or \
("no" in response_lower and "no" in answer_lower and "yes" not in response_lower and "yes" not in answer_lower):
return True
# Handle free-form integer answers
if answer_type == 'integer':
try:
response_num = text_to_number(response) if not response.isdigit() else int(response)
answer_num = text_to_number(answer) if not answer.isdigit() else int(answer)
return response_num == answer_num
except ValueError:
return False
# Handle free-form float answers
if answer_type == 'float':
try:
precision = problem.get('precision', 1e-3)
return abs(float(response) - float(answer)) < precision
except ValueError:
return False
# Handle text answers
if answer_type == 'text':
# Normalize and compare text answers
return response.lower().strip() == answer.lower().strip()
except Exception as e:
# Return False if any parsing error occurs
return False
return False
def process_responses_fixed(file_path):
"""
Process the responses in the given JSON file with enhanced evaluation logic.
"""
with open(file_path, 'r') as f:
data = json.load(f)
total = len(data)
correct = 0
detailed_results = []
for pid, problem in data.items():
is_correct = evaluate_response_fixed(problem)
if is_correct:
correct += 1
detailed_results.append({
'pid': pid,
'query': problem.get('query', ''),
'response': problem.get('response', ''),
'answer': problem.get('answer', ''),
'is_correct': is_correct
})
accuracy = correct / total if total > 0 else 0
return {
'total': total,
'correct': correct,
'accuracy': accuracy,
'detailed_results': detailed_results
}
# Re-run evaluation with fixed logic
fixed_results = process_responses_fixed(file_path)
# Output fixed results
import pprint
# pprint.pprint(fixed_results['accuracy']) # Print accuracy
# Save detailed results to a file for further analysis
with open('/content/drive/My Drive/World Models/detailed_results.json', 'w') as f:
json.dump(fixed_results['detailed_results'], f, indent=2)
print(f"Total questions: {fixed_results['total']}")
print(f"Correct answers: {fixed_results['correct']}")
print(f"Accuracy: {fixed_results['accuracy']:.2%}")