Sinhala

Upload duplicate removal file.

#13
by Vihindi-K - opened
training/remove_exact_mmlu_question_duplicates.py ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Remove records whose question exactly matches a reference dataset question.
2
+ """
3
+
4
+ import argparse
5
+ import json
6
+ import os
7
+ import shutil
8
+ import tempfile
9
+ from pathlib import Path
10
+
11
+
12
+ DEFAULT_TARGET = Path(
13
+ r"D:\other\Research\ICTER\combined_extracted_answers_new.json"
14
+ )
15
+ DEFAULT_REFERENCE = Path(
16
+ r"D:\other\Research\ICTER\Sinhala-MMLU-Test-Dataset\Combined_All.json"
17
+ )
18
+
19
+
20
+ def load_json_array(path: Path) -> list:
21
+ with path.open("r", encoding="utf-8-sig") as file:
22
+ data = json.load(file)
23
+ if not isinstance(data, list):
24
+ raise TypeError(f"Expected a top-level JSON array in: {path}")
25
+ return data
26
+
27
+
28
+ def next_backup_path(target: Path) -> Path:
29
+ candidate = target.with_name(target.stem + ".before_exact_removal.json")
30
+ number = 2
31
+ while candidate.exists():
32
+ candidate = target.with_name(
33
+ f"{target.stem}.before_exact_removal_{number}.json"
34
+ )
35
+ number += 1
36
+ return candidate
37
+
38
+
39
+ def remove_exact_matches(target: Path, reference: Path) -> dict:
40
+ target_records = load_json_array(target)
41
+ reference_records = load_json_array(reference)
42
+
43
+ # No normalization is performed here. Membership uses exact string equality.
44
+ reference_questions = {
45
+ record["question"]
46
+ for record in reference_records
47
+ if isinstance(record, dict) and isinstance(record.get("question"), str)
48
+ }
49
+
50
+ kept_records = []
51
+ removed_records = []
52
+ for record in target_records:
53
+ question = record.get("question") if isinstance(record, dict) else None
54
+ if isinstance(question, str) and question in reference_questions:
55
+ removed_records.append(record)
56
+ else:
57
+ kept_records.append(record)
58
+
59
+ backup = next_backup_path(target)
60
+ shutil.copy2(target, backup)
61
+
62
+ temporary_file = tempfile.NamedTemporaryFile(
63
+ mode="w",
64
+ encoding="utf-8",
65
+ suffix=".json",
66
+ prefix="exact_match_filtered_",
67
+ dir=target.parent,
68
+ delete=False,
69
+ )
70
+ temporary_path = Path(temporary_file.name)
71
+
72
+ try:
73
+ with temporary_file:
74
+ json.dump(kept_records, temporary_file, ensure_ascii=False, indent=2)
75
+ temporary_file.write("\n")
76
+
77
+ # Reload and verify before replacing the original file.
78
+ verified_records = load_json_array(temporary_path)
79
+ matches_remaining = sum(
80
+ 1
81
+ for record in verified_records
82
+ if isinstance(record, dict)
83
+ and isinstance(record.get("question"), str)
84
+ and record["question"] in reference_questions
85
+ )
86
+
87
+ if len(verified_records) != len(kept_records):
88
+ raise ValueError("Output record count verification failed")
89
+ if matches_remaining != 0:
90
+ raise ValueError("Exact matching questions remain in the output")
91
+
92
+ os.replace(temporary_path, target)
93
+ except Exception:
94
+ temporary_path.unlink(missing_ok=True)
95
+ raise
96
+
97
+ return {
98
+ "records_before": len(target_records),
99
+ "reference_records": len(reference_records),
100
+ "unique_reference_questions": len(reference_questions),
101
+ "records_removed": len(removed_records),
102
+ "unique_questions_removed": len(
103
+ {record["question"] for record in removed_records}
104
+ ),
105
+ "records_after": len(kept_records),
106
+ "exact_matches_remaining": 0,
107
+ "updated_file": str(target),
108
+ "backup_file": str(backup),
109
+ }
110
+
111
+
112
+ def main() -> None:
113
+ parser = argparse.ArgumentParser(
114
+ description="Remove records with question strings exactly matching a reference JSON dataset."
115
+ )
116
+ parser.add_argument(
117
+ "--target",
118
+ type=Path,
119
+ default=DEFAULT_TARGET,
120
+ help=f"JSON file to update (default: {DEFAULT_TARGET})",
121
+ )
122
+ parser.add_argument(
123
+ "--reference",
124
+ type=Path,
125
+ default=DEFAULT_REFERENCE,
126
+ help=f"Reference JSON dataset (default: {DEFAULT_REFERENCE})",
127
+ )
128
+ args = parser.parse_args()
129
+
130
+ result = remove_exact_matches(args.target, args.reference)
131
+ print(json.dumps(result, ensure_ascii=False, indent=2))
132
+
133
+
134
+ if __name__ == "__main__":
135
+ main()