ahmed taha commited on
Commit
ae1d2e8
·
verified ·
1 Parent(s): cfdc5e4

Upload sample_pairs.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. sample_pairs.py +85 -0
sample_pairs.py ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import json
5
+ import random
6
+ from collections import defaultdict
7
+ from pathlib import Path
8
+
9
+
10
+ def classify_transformation(pair: dict) -> str:
11
+ age_changed = pair.get("source_age") != pair.get("target_age")
12
+ sex_changed = pair.get("source_sex") != pair.get("target_sex")
13
+ if age_changed and sex_changed:
14
+ return "intersectional"
15
+ if age_changed:
16
+ return "age_only"
17
+ if sex_changed:
18
+ return "sex_only"
19
+ return "none"
20
+
21
+
22
+ def stratified_sample(
23
+ pairs: list[dict],
24
+ n_per_stratum: int,
25
+ seed: int,
26
+ ) -> list[int]:
27
+ rng = random.Random(seed)
28
+
29
+ by_stratum: dict[str, list[int]] = defaultdict(list)
30
+ for i, pair in enumerate(pairs):
31
+ stratum = classify_transformation(pair)
32
+ if stratum != "none":
33
+ by_stratum[stratum].append(i)
34
+
35
+ selected: list[int] = []
36
+ for stratum in ["age_only", "sex_only", "intersectional"]:
37
+ pool = by_stratum[stratum]
38
+ rng.shuffle(pool)
39
+ n = min(n_per_stratum, len(pool))
40
+ selected.extend(pool[:n])
41
+ if n < n_per_stratum:
42
+ print(
43
+ f"Warning: only {n} pairs available for {stratum} "
44
+ f"(requested {n_per_stratum})"
45
+ )
46
+
47
+ return selected
48
+
49
+
50
+ def main() -> None:
51
+ parser = argparse.ArgumentParser(
52
+ description="Stratified sampling of pairs for radiologist validation"
53
+ )
54
+ parser.add_argument("--pairs", type=str, required=True)
55
+ parser.add_argument("--n-per-stratum", type=int, default=150)
56
+ parser.add_argument("--seed", type=int, default=42)
57
+ parser.add_argument("--output", type=str, default="data/pairs.json")
58
+ args = parser.parse_args()
59
+
60
+ with open(args.pairs) as f:
61
+ all_pairs = json.load(f)
62
+
63
+ indices = stratified_sample(all_pairs, args.n_per_stratum, args.seed)
64
+ sampled = [all_pairs[i] for i in indices]
65
+
66
+ for pair in sampled:
67
+ pair["_transform_type"] = classify_transformation(pair)
68
+
69
+ counts: dict[str, int] = defaultdict(int)
70
+ for pair in sampled:
71
+ counts[pair["_transform_type"]] += 1
72
+
73
+ output_path = Path(args.output)
74
+ output_path.parent.mkdir(parents=True, exist_ok=True)
75
+ with open(output_path, "w") as f:
76
+ json.dump(sampled, f, indent=2)
77
+
78
+ print(f"Sampled {len(sampled)} pairs from {len(all_pairs)} total")
79
+ for stratum, count in sorted(counts.items()):
80
+ print(f" {stratum}: {count}")
81
+ print(f"Saved to: {output_path}")
82
+
83
+
84
+ if __name__ == "__main__":
85
+ main()