burt-imma / scripts /generate_arithmetic.py
SNAPKITTYWEST's picture
push from SNAPKITTYWEST/burt-imma
b88c26d verified
Raw
History Blame Contribute Delete
3.31 kB
#!/usr/bin/env python3
"""
Generate Arithmetic Expression Dataset
Generates corpus of arithmetic expressions with distractors for MMEP training.
Output format: JSONL with query, answer, and distractor values.
Usage:
python scripts/generate_arithmetic.py --corpus-size 10000 --output data/arithmetic.jsonl
Contact: jessica@collectivekitty.com
"""
import argparse
import json
import random
import os
from pathlib import Path
def generate_expression(rng, max_val=100, max_ops=3):
"""Generate a random arithmetic expression and its result."""
ops = ['+', '-', '*']
num_ops = rng.randint(1, max_ops)
values = [rng.randint(1, max_val) for _ in range(num_ops + 1)]
operators = [rng.choice(ops) for _ in range(num_ops)]
# Build expression string
expr_parts = [str(values[0])]
for i, op in enumerate(operators):
expr_parts.append(f" {op} {values[i+1]}")
expr = "".join(expr_parts)
# Compute answer
try:
answer = eval(expr)
except Exception:
answer = values[0]
return expr, int(answer)
def generate_distractors(answer, rng, num_distractors=3):
"""Generate plausible wrong answers."""
distractors = set()
attempts = 0
while len(distractors) < num_distractors and attempts < 100:
offset = rng.choice([-10, -5, -2, -1, 1, 2, 5, 10, 20])
d = answer + offset
if d != answer:
distractors.add(d)
attempts += 1
return list(distractors)[:num_distractors]
def generate_dataset(size, rng, split_name="train"):
"""Generate a dataset of arithmetic expressions."""
data = []
for _ in range(size):
expr, answer = generate_expression(rng)
distractors = generate_distractors(answer, rng)
data.append({
"query": expr,
"answer": answer,
"distractors": distractors,
"split": split_name
})
return data
def main():
parser = argparse.ArgumentParser(description="Generate arithmetic dataset")
parser.add_argument("--corpus-size", type=int, default=10000)
parser.add_argument("--train-queries", type=int, default=5000)
parser.add_argument("--val-queries", type=int, default=500)
parser.add_argument("--test-queries", type=int, default=1000)
parser.add_argument("--seed", type=int, default=42)
parser.add_argument("--output", type=str, default="data/arithmetic.jsonl")
args = parser.parse_args()
rng = random.Random(args.seed)
output_path = Path(args.output)
output_path.parent.mkdir(parents=True, exist_ok=True)
print(f"Generating arithmetic dataset (seed={args.seed})...")
train = generate_dataset(args.train_queries, rng, "train")
val = generate_dataset(args.val_queries, rng, "val")
test = generate_dataset(args.test_queries, rng, "test")
all_data = train + val + test
with open(output_path, 'w') as f:
for item in all_data:
f.write(json.dumps(item) + '\n')
print(f"Generated {len(all_data)} examples:")
print(f" Train: {len(train)}")
print(f" Val: {len(val)}")
print(f" Test: {len(test)}")
print(f" Output: {output_path}")
if __name__ == "__main__":
main()