forked from rasbt/reasoning-from-scratch
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrandom_guessing_baseline.py
More file actions
96 lines (79 loc) · 2.86 KB
/
Copy pathrandom_guessing_baseline.py
File metadata and controls
96 lines (79 loc) · 2.86 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
# Copyright (c) Sebastian Raschka under Apache License 2.0 (see LICENSE.txt)
# Source for "Build a Reasoning Model (From Scratch)": https://mng.bz/lZ5B
# Code repository: https://github.com/rasbt/reasoning-from-scratch
import argparse
import random
import statistics as stats
from collections import Counter
from datasets import load_dataset
# Gold letter is MMLU jargon for correct answer letter
def gold_letter(ans):
if isinstance(ans, int):
return "ABCD"[ans]
s = str(ans).strip().upper()
return s if s in {"A", "B", "C", "D"} else s[:1]
def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
description="Show gold answer distribution for an MMLU subset and a random-guess baseline."
)
parser.add_argument(
"--subset",
type=str,
default="high_school_mathematics",
help="MMLU subset name.",
)
parser.add_argument(
"--seed",
type=int,
default=42,
help="Random seed for the random-guess baseline.",
)
parser.add_argument(
"--trials",
type=int,
default=10_000,
help="Number of random-guess trials.",
)
args = parser.parse_args()
ds = load_dataset("cais/mmlu", args.subset, split="test")
labels = [gold_letter(ex["answer"]) for ex in ds]
n = len(labels)
counts = Counter(labels)
print(f"Subset: {args.subset} | split: test | n={n}")
print("Gold distribution provided in the dataset:")
for letter in "ABCD":
c = counts.get(letter, 0)
pct = (c / n) if n else 0.0
print(f" {letter}: {c} ({pct:.2%})")
if n == 0:
print("\nNo items. Baseline undefined.")
return
# Repeat random guessing
rng = random.Random(args.seed)
accs = []
for _ in range(args.trials):
guesses = [rng.choice("ABCD") for _ in range(n)]
correct = sum(1 for g, y in zip(guesses, labels) if g == y)
accs.append(correct / n)
mean_acc = stats.mean(accs)
sd_acc = stats.stdev(accs) if len(accs) > 1 else 0.0
print(f"\nRandom guessing over {args.trials:,} trials (uniform A/B/C/D, seed={args.seed}):")
print(f" Mean accuracy: {mean_acc:.2%}")
print(f" Std dev across trials: {sd_acc:.2%}")
# Quantiles
qs = [0.01, 0.05, 0.25, 0.5, 0.75, 0.95, 0.99]
accs_sorted = sorted(accs)
print("\nSelected quantiles of accuracy:")
for q in qs:
idx = int(q * len(accs_sorted))
print(f" {q:.0%} quantile: {accs_sorted[idx]:.3%}")
# Frequency table (rounded)
acc_counts = Counter(round(a, 2) for a in accs)
print("\nFull frequency table of accuracies (rounded):")
for acc_val in sorted(acc_counts):
freq = acc_counts[acc_val]
pct = freq / args.trials
print(f" {acc_val:.3f}: {freq} times ({pct:.2%})")
if __name__ == "__main__":
main()