LLDDSS commited on
Commit
18104f9
·
verified ·
1 Parent(s): d87238e

Upload folder using huggingface_hub

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .codex +0 -0
  2. .gitattributes +1 -0
  3. .gitignore +11 -0
  4. analysis/analyze_baseline_overlap.py +284 -0
  5. analysis/dataset_level_analysis/accuracy_by_baseline.csv +97 -0
  6. analysis/dataset_level_analysis/analyze_dataset_level.py +291 -0
  7. analysis/dataset_level_analysis/build_notebook.py +463 -0
  8. analysis/dataset_level_analysis/dataset_difficulty.ipynb +0 -0
  9. analysis/dataset_level_analysis/figures/01_accuracy_vs_floor.png +0 -0
  10. analysis/dataset_level_analysis/figures/02_headroom_heatmap.png +0 -0
  11. analysis/dataset_level_analysis/figures/03_difficulty_profile.png +0 -0
  12. analysis/dataset_level_analysis/figures/04_baseline_sensitivity.png +3 -0
  13. analysis/dataset_level_analysis/figures/05_item_difficulty.png +0 -0
  14. analysis/dataset_level_analysis/figures/06_failure_overlap.png +0 -0
  15. analysis/dataset_level_analysis/figures/07_answer_bias.png +0 -0
  16. analysis/dataset_level_analysis/figures/08_level2_guard.png +0 -0
  17. analysis/dataset_level_analysis/level2_structure_use.csv +25 -0
  18. analysis/dataset_level_analysis/prediction_bias.csv +97 -0
  19. analysis/dataset_level_analysis/readme.md +133 -0
  20. analysis/dataset_level_analysis/summary_by_model_task.csv +17 -0
  21. analysis/intervention_analysis/Qwen_Qwen2.5-VL-3B-Instruct__vsr_failure_overlap.csv +16 -0
  22. analysis/intervention_analysis/Qwen_Qwen2.5-VL-3B-Instruct__vsr_per_sample.csv +0 -0
  23. analysis/intervention_analysis/Qwen_Qwen2.5-VL-3B-Instruct__youtube_level1_failure_overlap.csv +16 -0
  24. analysis/intervention_analysis/Qwen_Qwen2.5-VL-3B-Instruct__youtube_level1_per_sample.csv +0 -0
  25. analysis/intervention_analysis/Qwen_Qwen2.5-VL-3B-Instruct__youtube_level2_failure_overlap.csv +16 -0
  26. analysis/intervention_analysis/Qwen_Qwen2.5-VL-3B-Instruct__youtube_level2_per_sample.csv +0 -0
  27. analysis/intervention_analysis/Qwen_Qwen2.5-VL-3B-Instruct__youtube_level3_failure_overlap.csv +16 -0
  28. analysis/intervention_analysis/Qwen_Qwen2.5-VL-3B-Instruct__youtube_level3_per_sample.csv +0 -0
  29. analysis/intervention_analysis/Qwen_Qwen2.5-VL-7B-Instruct__vsr_failure_overlap.csv +16 -0
  30. analysis/intervention_analysis/Qwen_Qwen2.5-VL-7B-Instruct__vsr_per_sample.csv +0 -0
  31. analysis/intervention_analysis/Qwen_Qwen2.5-VL-7B-Instruct__youtube_level1_failure_overlap.csv +16 -0
  32. analysis/intervention_analysis/Qwen_Qwen2.5-VL-7B-Instruct__youtube_level1_per_sample.csv +0 -0
  33. analysis/intervention_analysis/Qwen_Qwen2.5-VL-7B-Instruct__youtube_level2_failure_overlap.csv +16 -0
  34. analysis/intervention_analysis/Qwen_Qwen2.5-VL-7B-Instruct__youtube_level2_per_sample.csv +0 -0
  35. analysis/intervention_analysis/Qwen_Qwen2.5-VL-7B-Instruct__youtube_level3_failure_overlap.csv +16 -0
  36. analysis/intervention_analysis/Qwen_Qwen2.5-VL-7B-Instruct__youtube_level3_per_sample.csv +0 -0
  37. analysis/intervention_analysis/Qwen_Qwen3.5-4B-Base__vsr_failure_overlap.csv +16 -0
  38. analysis/intervention_analysis/Qwen_Qwen3.5-4B-Base__vsr_per_sample.csv +0 -0
  39. analysis/intervention_analysis/Qwen_Qwen3.5-4B-Base__youtube_level1_failure_overlap.csv +16 -0
  40. analysis/intervention_analysis/Qwen_Qwen3.5-4B-Base__youtube_level1_per_sample.csv +0 -0
  41. analysis/intervention_analysis/Qwen_Qwen3.5-4B-Base__youtube_level2_failure_overlap.csv +16 -0
  42. analysis/intervention_analysis/Qwen_Qwen3.5-4B-Base__youtube_level2_per_sample.csv +0 -0
  43. analysis/intervention_analysis/Qwen_Qwen3.5-4B-Base__youtube_level3_failure_overlap.csv +16 -0
  44. analysis/intervention_analysis/Qwen_Qwen3.5-4B-Base__youtube_level3_per_sample.csv +0 -0
  45. analysis/intervention_analysis/Qwen_Qwen3.5-4B__vsr_failure_overlap.csv +16 -0
  46. analysis/intervention_analysis/Qwen_Qwen3.5-4B__vsr_per_sample.csv +0 -0
  47. analysis/intervention_analysis/Qwen_Qwen3.5-4B__youtube_level1_failure_overlap.csv +16 -0
  48. analysis/intervention_analysis/Qwen_Qwen3.5-4B__youtube_level1_per_sample.csv +0 -0
  49. analysis/intervention_analysis/Qwen_Qwen3.5-4B__youtube_level2_failure_overlap.csv +16 -0
  50. analysis/intervention_analysis/Qwen_Qwen3.5-4B__youtube_level2_per_sample.csv +0 -0
.codex ADDED
File without changes
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ analysis/dataset_level_analysis/figures/04_baseline_sensitivity.png filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __pycache__/
2
+ *.log
3
+
4
+ # Inference and analysis outputs are regenerated from the scripts; only the two
5
+ # source files that live alongside them are tracked. Git needs each parent
6
+ # directory un-ignored before a file inside it can be negated.
7
+ result/*
8
+ !result/analysis/
9
+ result/analysis/*
10
+ !result/analysis/readme.md
11
+ !result/analysis/baseline_intervention.ipynb
analysis/analyze_baseline_overlap.py ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Cross-baseline stability and failure-case overlap.
2
+
3
+ Reads the per-baseline prediction files written by inference/run_inference.py
4
+ and, for each (model, task), lines the samples up by sample_id to answer:
5
+
6
+ accuracy per baseline, plus how much it moves across the sweep.
7
+ flip rate fraction of samples whose ANSWER changes relative to the
8
+ reference baseline (default 0.00). This is the direct test of
9
+ the premise: a visual tower that modelled the scene perfectly
10
+ would answer identically at every baseline, so the flip rate
11
+ is the size of the effect the intervention has, independent of
12
+ whether the answer was right to begin with.
13
+ stability fraction of samples correct at every baseline / wrong at every
14
+ baseline / unstable (correct at some, wrong at others).
15
+ failure overlap for every pair of baselines, |F_a & F_b| / |F_a | F_b| over
16
+ the failure sets, plus the raw counts. High overlap means the
17
+ baselines fail on the SAME samples (a shared difficulty);
18
+ low overlap means each baseline breaks a different subset,
19
+ i.e. the failures are driven by the intervention itself.
20
+
21
+ Usage
22
+ python analysis/analyze_baseline_overlap.py --result_dir result
23
+ python analysis/analyze_baseline_overlap.py --result_dir result --dump_per_sample
24
+
25
+ Writes analysis_summary.json and one <model>__<task>_overlap.csv per run next
26
+ to the results, and prints a readable table.
27
+ """
28
+
29
+ import argparse
30
+ import csv
31
+ import itertools
32
+ import json
33
+ import os
34
+ import pathlib
35
+ import sys
36
+ from collections import defaultdict
37
+
38
+ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
39
+
40
+ from dataset import BASELINES # noqa: E402
41
+
42
+
43
+ def parse_args():
44
+ parser = argparse.ArgumentParser(description=__doc__.split("\n")[0])
45
+ default_result = pathlib.Path(__file__).resolve().parent.parent / "result"
46
+ parser.add_argument("--result_dir", default=str(default_result))
47
+ parser.add_argument(
48
+ "--output_dir",
49
+ default=str(pathlib.Path(__file__).resolve().parent / "intervention_analysis"),
50
+ help="Defaults to analysis/intervention_analysis, beside the notebook that reads it.",
51
+ )
52
+ parser.add_argument(
53
+ "--reference_baseline",
54
+ default="0.00",
55
+ help="Baseline that flip rate and per-pair comparisons are measured against.",
56
+ )
57
+ parser.add_argument(
58
+ "--dump_per_sample",
59
+ action="store_true",
60
+ help="Also write a per-sample correctness/answer matrix for each run.",
61
+ )
62
+ return parser.parse_args()
63
+
64
+
65
+ def sample_key(row):
66
+ """A key that identifies one question, unique within a task.
67
+
68
+ VSR reuses an image across several statements, so its `sample_id` is the
69
+ image id and repeats (2195 rows over 1874 ids). Keying the cross-baseline
70
+ alignment on `sample_id` alone would silently keep only the last question
71
+ per image and drop the rest, so the question text is part of the key. The
72
+ Youtube levels already have unique ids and are unaffected.
73
+ """
74
+ return (row["sample_id"], row.get("question", ""))
75
+
76
+
77
+ def load_runs(result_dir):
78
+ """{(model, task): {baseline: {sample_key: row}}} from result/<model>/<task>/baseline_<b>/."""
79
+ runs = defaultdict(dict)
80
+ for metrics_path in sorted(pathlib.Path(result_dir).glob("*/*/baseline_*/metrics.json")):
81
+ predictions_path = metrics_path.parent / "predictions.jsonl"
82
+ if not predictions_path.is_file():
83
+ print(f" skipping {metrics_path.parent} (no predictions.jsonl)", file=sys.stderr)
84
+ continue
85
+ with metrics_path.open(encoding="utf-8") as f:
86
+ metrics = json.load(f)
87
+ with predictions_path.open(encoding="utf-8") as f:
88
+ rows = {}
89
+ for line in f:
90
+ if not line.strip():
91
+ continue
92
+ row = json.loads(line)
93
+ rows[sample_key(row)] = row
94
+ key = (metrics.get("model_id", metrics_path.parents[2].name), metrics.get("task", metrics_path.parents[1].name))
95
+ runs[key][metrics["baseline"]] = {"metrics": metrics, "rows": rows}
96
+ return runs
97
+
98
+
99
+ def analyse_run(baselines_data, reference_baseline):
100
+ """Accuracy / flip rate / stability / pairwise failure overlap for one run."""
101
+ baselines = [b for b in BASELINES if b in baselines_data]
102
+ common = set.intersection(*(set(baselines_data[b]["rows"]) for b in baselines))
103
+ dropped = {b: len(baselines_data[b]["rows"]) - len(common) for b in baselines}
104
+
105
+ correct = {b: {sid for sid in common if baselines_data[b]["rows"][sid]["correct"]} for b in baselines}
106
+ answers = {b: {sid: baselines_data[b]["rows"][sid]["prediction_norm"] for sid in common} for b in baselines}
107
+ failures = {b: common - correct[b] for b in baselines}
108
+
109
+ per_baseline = []
110
+ reference = reference_baseline if reference_baseline in baselines else baselines[0]
111
+ for b in baselines:
112
+ flipped = {sid for sid in common if answers[b][sid] != answers[reference][sid]}
113
+ per_baseline.append(
114
+ {
115
+ "baseline": b,
116
+ "num_samples": len(common),
117
+ "accuracy": len(correct[b]) / len(common) if common else 0.0,
118
+ "num_failures": len(failures[b]),
119
+ "flip_rate_vs_reference": len(flipped) / len(common) if common else 0.0,
120
+ "unparsed_rate": baselines_data[b]["metrics"].get("unparsed_rate"),
121
+ }
122
+ )
123
+
124
+ always_correct = set.intersection(*(correct[b] for b in baselines)) if baselines else set()
125
+ always_wrong = set.intersection(*(failures[b] for b in baselines)) if baselines else set()
126
+ unstable = common - always_correct - always_wrong
127
+
128
+ pairwise = []
129
+ for a, b in itertools.combinations(baselines, 2):
130
+ intersection = failures[a] & failures[b]
131
+ union = failures[a] | failures[b]
132
+ agree = sum(1 for sid in common if answers[a][sid] == answers[b][sid])
133
+ pairwise.append(
134
+ {
135
+ "baseline_a": a,
136
+ "baseline_b": b,
137
+ "failures_a": len(failures[a]),
138
+ "failures_b": len(failures[b]),
139
+ "failures_shared": len(intersection),
140
+ "failure_jaccard": len(intersection) / len(union) if union else 1.0,
141
+ # Of the samples a fails, how many does b also fail.
142
+ "failure_recall_a_in_b": len(intersection) / len(failures[a]) if failures[a] else float("nan"),
143
+ # The same measure over the samples each baseline gets RIGHT. It is
144
+ # not redundant with the failure Jaccard: with 4-way answers the
145
+ # success sets are small and the failure sets large, so the two
146
+ # move independently and a task can share its successes while its
147
+ # failures scatter (or the reverse).
148
+ "successes_a": len(correct[a]),
149
+ "successes_b": len(correct[b]),
150
+ "successes_shared": len(correct[a] & correct[b]),
151
+ "success_jaccard": (
152
+ len(correct[a] & correct[b]) / len(correct[a] | correct[b])
153
+ if (correct[a] | correct[b]) else 1.0
154
+ ),
155
+ "answer_agreement": agree / len(common) if common else 0.0,
156
+ }
157
+ )
158
+
159
+ return {
160
+ "baselines": baselines,
161
+ "reference_baseline": reference,
162
+ "num_common_samples": len(common),
163
+ "dropped_per_baseline": dropped,
164
+ "per_baseline": per_baseline,
165
+ "accuracy_spread": (
166
+ max(r["accuracy"] for r in per_baseline) - min(r["accuracy"] for r in per_baseline)
167
+ if per_baseline
168
+ else 0.0
169
+ ),
170
+ "stability": {
171
+ "always_correct": len(always_correct),
172
+ "always_wrong": len(always_wrong),
173
+ "unstable": len(unstable),
174
+ "always_correct_rate": len(always_correct) / len(common) if common else 0.0,
175
+ "always_wrong_rate": len(always_wrong) / len(common) if common else 0.0,
176
+ "unstable_rate": len(unstable) / len(common) if common else 0.0,
177
+ },
178
+ "pairwise": pairwise,
179
+ "_common": common,
180
+ "_answers": answers,
181
+ "_correct": correct,
182
+ }
183
+
184
+
185
+ def write_pairwise_csv(path, result):
186
+ with path.open("w", newline="", encoding="utf-8") as f:
187
+ writer = csv.DictWriter(
188
+ f,
189
+ fieldnames=[
190
+ "baseline_a", "baseline_b",
191
+ "failures_a", "failures_b", "failures_shared",
192
+ "failure_jaccard", "failure_recall_a_in_b",
193
+ "successes_a", "successes_b", "successes_shared", "success_jaccard",
194
+ "answer_agreement",
195
+ ],
196
+ )
197
+ writer.writeheader()
198
+ writer.writerows(result["pairwise"])
199
+
200
+
201
+ def write_per_sample_csv(path, result):
202
+ baselines = result["baselines"]
203
+ with path.open("w", newline="", encoding="utf-8") as f:
204
+ writer = csv.writer(f)
205
+ writer.writerow(
206
+ ["sample_id", "question"]
207
+ + [f"answer_{b}" for b in baselines]
208
+ + [f"correct_{b}" for b in baselines]
209
+ + ["num_correct", "stability"]
210
+ )
211
+ for sid in sorted(result["_common"]):
212
+ flags = [sid in result["_correct"][b] for b in baselines]
213
+ total = sum(flags)
214
+ stability = "always_correct" if total == len(baselines) else (
215
+ "always_wrong" if total == 0 else "unstable"
216
+ )
217
+ writer.writerow(
218
+ list(sid)
219
+ + [result["_answers"][b][sid] for b in baselines]
220
+ + [int(flag) for flag in flags]
221
+ + [total, stability]
222
+ )
223
+
224
+
225
+ def main():
226
+ args = parse_args()
227
+ runs = load_runs(args.result_dir)
228
+ if not runs:
229
+ raise SystemExit(
230
+ f"No results under {args.result_dir}; expected "
231
+ "<result_dir>/<model>/<task>/baseline_<b>/{metrics.json,predictions.jsonl}"
232
+ )
233
+
234
+ output_dir = pathlib.Path(args.output_dir or os.path.join(args.result_dir, "analysis"))
235
+ output_dir.mkdir(parents=True, exist_ok=True)
236
+
237
+ summary = []
238
+ for (model_id, task), baselines_data in sorted(runs.items()):
239
+ result = analyse_run(baselines_data, args.reference_baseline)
240
+ tag = f"{model_id.replace('/', '_')}__{task}"
241
+
242
+ write_pairwise_csv(output_dir / f"{tag}_failure_overlap.csv", result)
243
+ if args.dump_per_sample:
244
+ write_per_sample_csv(output_dir / f"{tag}_per_sample.csv", result)
245
+
246
+ print(f"\n=== {model_id} | {task} | n={result['num_common_samples']} ===")
247
+ print(f"{'baseline':>10} {'accuracy':>10} {'failures':>10} {'flip vs ' + result['reference_baseline']:>14}")
248
+ for row in result["per_baseline"]:
249
+ print(
250
+ f"{row['baseline']:>10} {row['accuracy']:>10.4f} {row['num_failures']:>10d} "
251
+ f"{row['flip_rate_vs_reference']:>14.4f}"
252
+ )
253
+ stability = result["stability"]
254
+ print(
255
+ f" accuracy spread {result['accuracy_spread']:.4f} | "
256
+ f"always correct {stability['always_correct_rate']:.4f} | "
257
+ f"always wrong {stability['always_wrong_rate']:.4f} | "
258
+ f"unstable {stability['unstable_rate']:.4f}"
259
+ )
260
+ print(" failure-set overlap (Jaccard):")
261
+ for pair in result["pairwise"]:
262
+ print(
263
+ f" {pair['baseline_a']} vs {pair['baseline_b']}: "
264
+ f"J={pair['failure_jaccard']:.4f} shared={pair['failures_shared']:>5d} "
265
+ f"(|F_a|={pair['failures_a']}, |F_b|={pair['failures_b']}) "
266
+ f"answer agreement={pair['answer_agreement']:.4f}"
267
+ )
268
+
269
+ summary.append(
270
+ {
271
+ "model_id": model_id,
272
+ "task": task,
273
+ **{k: v for k, v in result.items() if not k.startswith("_")},
274
+ }
275
+ )
276
+
277
+ summary_path = output_dir / "analysis_summary.json"
278
+ with summary_path.open("w", encoding="utf-8") as f:
279
+ json.dump({"result_dir": os.path.abspath(args.result_dir), "runs": summary}, f, indent=2)
280
+ print(f"\nSummary saved to {summary_path}")
281
+
282
+
283
+ if __name__ == "__main__":
284
+ main()
analysis/dataset_level_analysis/accuracy_by_baseline.csv ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ model,task,baseline,n,accuracy,num_correct,unparsed_rate,scoring,chance,floor,headroom_captured
2
+ Qwen_Qwen2.5-VL-3B-Instruct,vsr,0.00,2195,0.7713,1693,0.0,generate,0.5,0.5,0.5426
3
+ Qwen_Qwen2.5-VL-3B-Instruct,vsr,0.05,2195,0.7677,1685,0.0,generate,0.5,0.5,0.5353
4
+ Qwen_Qwen2.5-VL-3B-Instruct,vsr,0.10,2195,0.7595,1667,0.0,generate,0.5,0.5,0.5189
5
+ Qwen_Qwen2.5-VL-3B-Instruct,vsr,0.15,2195,0.7581,1664,0.0,generate,0.5,0.5,0.5162
6
+ Qwen_Qwen2.5-VL-3B-Instruct,vsr,0.20,2195,0.7526,1652,0.0,generate,0.5,0.5,0.5052
7
+ Qwen_Qwen2.5-VL-3B-Instruct,vsr,0.25,2195,0.7481,1642,0.0,generate,0.5,0.5,0.4961
8
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level1,0.00,821,0.3995,328,0.0,generate,0.25,0.25,0.1994
9
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level1,0.05,821,0.4056,333,0.0,generate,0.25,0.25,0.2075
10
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level1,0.10,821,0.4117,338,0.0,generate,0.25,0.25,0.2156
11
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level1,0.15,821,0.4105,337,0.0,generate,0.25,0.25,0.214
12
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level1,0.20,821,0.3995,328,0.0,generate,0.25,0.25,0.1994
13
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level1,0.25,821,0.4007,329,0.0,generate,0.25,0.25,0.201
14
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level2,0.00,764,0.3626,277,0.0,generate,0.25,0.25,0.1501
15
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level2,0.05,764,0.3743,286,0.0,generate,0.25,0.25,0.1658
16
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level2,0.10,764,0.3783,289,0.0,generate,0.25,0.25,0.171
17
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level2,0.15,764,0.3796,290,0.0,generate,0.25,0.25,0.1728
18
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level2,0.20,764,0.3809,291,0.0,generate,0.25,0.25,0.1745
19
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level2,0.25,764,0.3704,283,0.0,generate,0.25,0.25,0.1606
20
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level3,0.00,836,0.2667,223,0.0,generate,0.25,0.25,0.0223
21
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level3,0.05,836,0.2452,205,0.0,generate,0.25,0.25,-0.0064
22
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level3,0.10,836,0.2392,200,0.0,generate,0.25,0.25,-0.0144
23
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level3,0.15,836,0.2524,211,0.0,generate,0.25,0.25,0.0032
24
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level3,0.20,836,0.2596,217,0.0,generate,0.25,0.25,0.0128
25
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level3,0.25,836,0.2656,222,0.0,generate,0.25,0.25,0.0207
26
+ Qwen_Qwen2.5-VL-7B-Instruct,vsr,0.00,2195,0.8223,1805,0.0,generate,0.5,0.5,0.6446
27
+ Qwen_Qwen2.5-VL-7B-Instruct,vsr,0.05,2195,0.8077,1773,0.0,generate,0.5,0.5,0.6155
28
+ Qwen_Qwen2.5-VL-7B-Instruct,vsr,0.10,2195,0.8027,1762,0.0,generate,0.5,0.5,0.6055
29
+ Qwen_Qwen2.5-VL-7B-Instruct,vsr,0.15,2195,0.8068,1771,0.0,generate,0.5,0.5,0.6137
30
+ Qwen_Qwen2.5-VL-7B-Instruct,vsr,0.20,2195,0.8023,1761,0.0,generate,0.5,0.5,0.6046
31
+ Qwen_Qwen2.5-VL-7B-Instruct,vsr,0.25,2195,0.7882,1730,0.0,generate,0.5,0.5,0.5763
32
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level1,0.00,821,0.447,367,0.0,generate,0.25,0.25,0.2627
33
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level1,0.05,821,0.4482,368,0.0,generate,0.25,0.25,0.2643
34
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level1,0.10,821,0.4555,374,0.0,generate,0.25,0.25,0.2741
35
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level1,0.15,821,0.4665,383,0.0,generate,0.25,0.25,0.2887
36
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level1,0.20,821,0.4421,363,0.0,generate,0.25,0.25,0.2562
37
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level1,0.25,821,0.4519,371,0.0,generate,0.25,0.25,0.2692
38
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level2,0.00,764,0.4031,308,0.0,generate,0.25,0.25,0.2042
39
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level2,0.05,764,0.394,301,0.0,generate,0.25,0.25,0.192
40
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level2,0.10,764,0.3979,304,0.0,generate,0.25,0.25,0.1972
41
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level2,0.15,764,0.4018,307,0.0,generate,0.25,0.25,0.2024
42
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level2,0.20,764,0.377,288,0.0,generate,0.25,0.25,0.1693
43
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level2,0.25,764,0.377,288,0.0,generate,0.25,0.25,0.1693
44
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level3,0.00,836,0.2799,234,0.0,generate,0.25,0.25,0.0399
45
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level3,0.05,836,0.2871,240,0.0,generate,0.25,0.25,0.0494
46
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level3,0.10,836,0.2679,224,0.0,generate,0.25,0.25,0.0239
47
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level3,0.15,836,0.2823,236,0.0,generate,0.25,0.25,0.0431
48
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level3,0.20,836,0.2763,231,0.0,generate,0.25,0.25,0.0351
49
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level3,0.25,836,0.2739,229,0.0,generate,0.25,0.25,0.0319
50
+ Qwen_Qwen3.5-4B,vsr,0.00,2195,0.8214,1803,0.0,generate,0.5,0.5,0.6428
51
+ Qwen_Qwen3.5-4B,vsr,0.05,2195,0.8173,1794,0.0,generate,0.5,0.5,0.6346
52
+ Qwen_Qwen3.5-4B,vsr,0.10,2195,0.8187,1797,0.0,generate,0.5,0.5,0.6374
53
+ Qwen_Qwen3.5-4B,vsr,0.15,2195,0.8114,1781,0.0,generate,0.5,0.5,0.6228
54
+ Qwen_Qwen3.5-4B,vsr,0.20,2195,0.8073,1772,0.0,generate,0.5,0.5,0.6146
55
+ Qwen_Qwen3.5-4B,vsr,0.25,2195,0.8046,1766,0.0,generate,0.5,0.5,0.6091
56
+ Qwen_Qwen3.5-4B,youtube_level1,0.00,821,0.5274,433,0.0037,generate,0.25,0.25,0.3699
57
+ Qwen_Qwen3.5-4B,youtube_level1,0.05,821,0.5213,428,0.0073,generate,0.25,0.25,0.3618
58
+ Qwen_Qwen3.5-4B,youtube_level1,0.10,821,0.5189,426,0.0012,generate,0.25,0.25,0.3585
59
+ Qwen_Qwen3.5-4B,youtube_level1,0.15,821,0.5408,444,0.0049,generate,0.25,0.25,0.3877
60
+ Qwen_Qwen3.5-4B,youtube_level1,0.20,821,0.5347,439,0.0012,generate,0.25,0.25,0.3796
61
+ Qwen_Qwen3.5-4B,youtube_level1,0.25,821,0.5347,439,0.0,generate,0.25,0.25,0.3796
62
+ Qwen_Qwen3.5-4B,youtube_level2,0.00,764,0.3914,299,0.0,generate,0.25,0.25,0.1885
63
+ Qwen_Qwen3.5-4B,youtube_level2,0.05,764,0.3901,298,0.0,generate,0.25,0.25,0.1867
64
+ Qwen_Qwen3.5-4B,youtube_level2,0.10,764,0.3822,292,0.0,generate,0.25,0.25,0.1763
65
+ Qwen_Qwen3.5-4B,youtube_level2,0.15,764,0.3874,296,0.0,generate,0.25,0.25,0.1832
66
+ Qwen_Qwen3.5-4B,youtube_level2,0.20,764,0.3796,290,0.0,generate,0.25,0.25,0.1728
67
+ Qwen_Qwen3.5-4B,youtube_level2,0.25,764,0.3848,294,0.0,generate,0.25,0.25,0.1798
68
+ Qwen_Qwen3.5-4B,youtube_level3,0.00,836,0.2931,245,0.0,generate,0.25,0.25,0.0574
69
+ Qwen_Qwen3.5-4B,youtube_level3,0.05,836,0.299,250,0.0,generate,0.25,0.25,0.0654
70
+ Qwen_Qwen3.5-4B,youtube_level3,0.10,836,0.2967,248,0.0,generate,0.25,0.25,0.0622
71
+ Qwen_Qwen3.5-4B,youtube_level3,0.15,836,0.3038,254,0.0,generate,0.25,0.25,0.0718
72
+ Qwen_Qwen3.5-4B,youtube_level3,0.20,836,0.2883,241,0.0,generate,0.25,0.25,0.051
73
+ Qwen_Qwen3.5-4B,youtube_level3,0.25,836,0.2931,245,0.0,generate,0.25,0.25,0.0574
74
+ Qwen_Qwen3.5-4B-Base,vsr,0.00,2195,0.8319,1826,0.0,likelihood,0.5,0.5,0.6638
75
+ Qwen_Qwen3.5-4B-Base,vsr,0.05,2195,0.8314,1825,0.0,likelihood,0.5,0.5,0.6629
76
+ Qwen_Qwen3.5-4B-Base,vsr,0.10,2195,0.8323,1827,0.0,likelihood,0.5,0.5,0.6647
77
+ Qwen_Qwen3.5-4B-Base,vsr,0.15,2195,0.8278,1817,0.0,likelihood,0.5,0.5,0.6556
78
+ Qwen_Qwen3.5-4B-Base,vsr,0.20,2195,0.8241,1809,0.0,likelihood,0.5,0.5,0.6483
79
+ Qwen_Qwen3.5-4B-Base,vsr,0.25,2195,0.8164,1792,0.0,likelihood,0.5,0.5,0.6328
80
+ Qwen_Qwen3.5-4B-Base,youtube_level1,0.00,821,0.542,445,0.0,likelihood,0.25,0.25,0.3894
81
+ Qwen_Qwen3.5-4B-Base,youtube_level1,0.05,821,0.5457,448,0.0,likelihood,0.25,0.25,0.3942
82
+ Qwen_Qwen3.5-4B-Base,youtube_level1,0.10,821,0.5603,460,0.0,likelihood,0.25,0.25,0.4137
83
+ Qwen_Qwen3.5-4B-Base,youtube_level1,0.15,821,0.5725,470,0.0,likelihood,0.25,0.25,0.43
84
+ Qwen_Qwen3.5-4B-Base,youtube_level1,0.20,821,0.5664,465,0.0,likelihood,0.25,0.25,0.4218
85
+ Qwen_Qwen3.5-4B-Base,youtube_level1,0.25,821,0.5554,456,0.0,likelihood,0.25,0.25,0.4072
86
+ Qwen_Qwen3.5-4B-Base,youtube_level2,0.00,764,0.4424,338,0.0,likelihood,0.25,0.25,0.2565
87
+ Qwen_Qwen3.5-4B-Base,youtube_level2,0.05,764,0.4529,346,0.0,likelihood,0.25,0.25,0.2705
88
+ Qwen_Qwen3.5-4B-Base,youtube_level2,0.10,764,0.4503,344,0.0,likelihood,0.25,0.25,0.267
89
+ Qwen_Qwen3.5-4B-Base,youtube_level2,0.15,764,0.4542,347,0.0,likelihood,0.25,0.25,0.2723
90
+ Qwen_Qwen3.5-4B-Base,youtube_level2,0.20,764,0.4503,344,0.0,likelihood,0.25,0.25,0.267
91
+ Qwen_Qwen3.5-4B-Base,youtube_level2,0.25,764,0.4398,336,0.0,likelihood,0.25,0.25,0.2531
92
+ Qwen_Qwen3.5-4B-Base,youtube_level3,0.00,836,0.3026,253,0.0,likelihood,0.25,0.25,0.0702
93
+ Qwen_Qwen3.5-4B-Base,youtube_level3,0.05,836,0.2715,227,0.0,likelihood,0.25,0.25,0.0287
94
+ Qwen_Qwen3.5-4B-Base,youtube_level3,0.10,836,0.2775,232,0.0,likelihood,0.25,0.25,0.0367
95
+ Qwen_Qwen3.5-4B-Base,youtube_level3,0.15,836,0.2667,223,0.0,likelihood,0.25,0.25,0.0223
96
+ Qwen_Qwen3.5-4B-Base,youtube_level3,0.20,836,0.2727,228,0.0,likelihood,0.25,0.25,0.0303
97
+ Qwen_Qwen3.5-4B-Base,youtube_level3,0.25,836,0.2823,236,0.0,likelihood,0.25,0.25,0.0431
analysis/dataset_level_analysis/analyze_dataset_level.py ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Compare every model across the four evaluation splits.
3
+
4
+ python analysis/dataset_level_analysis/analyze_dataset_level.py
5
+
6
+ Reads result/<model>/<task>/baseline_<b>/{metrics.json,predictions.jsonl} and
7
+ writes the CSVs next to this script.
8
+
9
+ Raw accuracy is not comparable across the four splits: VSR is a two-way
10
+ true/false question while the three Youtube levels are four-way, and level 2
11
+ carries a structural floor of its own (see FLOORS). Everything is therefore
12
+ also reported as *headroom captured*, (acc - floor) / (1 - floor): the share of
13
+ the distance between guessing and perfect that the model actually covers. It
14
+ is negative when a model does worse than the floor, which happens here.
15
+ """
16
+ from __future__ import annotations
17
+
18
+ import argparse
19
+ import collections
20
+ import csv
21
+ import json
22
+ import math
23
+ import os
24
+ import statistics
25
+
26
+ BASELINES = ["0.00", "0.05", "0.10", "0.15", "0.20", "0.25"]
27
+ TASKS = ["vsr", "youtube_level1", "youtube_level2", "youtube_level3"]
28
+
29
+ # What a model scores on each split without looking at the image: pure guessing
30
+ # among the choices. Level 2's three distractors are drawn uniformly from the
31
+ # 23 wrong orderings, so the four options are exchangeable and every text-only
32
+ # heuristic sits at chance -- measured on the split: prefix vote 0.252, medoid
33
+ # 0.256, outlier 0.254, positional majority 0.245. Earlier structured variants
34
+ # did NOT have this property; see disparity_qa/level2_choices.py.
35
+ FLOORS = {"vsr": 0.500, "youtube_level1": 0.250,
36
+ "youtube_level2": 0.250, "youtube_level3": 0.250}
37
+ CHANCE = dict(FLOORS)
38
+
39
+
40
+ def load_metrics(root: str, model: str, task: str, baseline: str) -> dict:
41
+ with open(os.path.join(root, "result", model, task,
42
+ f"baseline_{baseline}", "metrics.json")) as fh:
43
+ return json.load(fh)
44
+
45
+
46
+ def load_predictions(root: str, model: str, task: str, baseline: str):
47
+ path = os.path.join(root, "result", model, task,
48
+ f"baseline_{baseline}", "predictions.jsonl")
49
+ with open(path) as fh:
50
+ for line in fh:
51
+ line = line.strip()
52
+ if line:
53
+ yield json.loads(line)
54
+
55
+
56
+ def entropy(counter: collections.Counter) -> float:
57
+ n = sum(counter.values())
58
+ if not n:
59
+ return 0.0
60
+ return -sum((v / n) * math.log2(v / n) for v in counter.values() if v)
61
+
62
+
63
+ def slope(xs, ys) -> float:
64
+ """Least-squares slope of accuracy against baseline (per unit of baseline)."""
65
+ mx, my = statistics.mean(xs), statistics.mean(ys)
66
+ den = sum((x - mx) ** 2 for x in xs)
67
+ return sum((x - mx) * (y - my) for x, y in zip(xs, ys)) / den if den else 0.0
68
+
69
+
70
+ def main() -> int:
71
+ here = os.path.dirname(os.path.abspath(__file__))
72
+ p = argparse.ArgumentParser()
73
+ p.add_argument("--root", default=os.path.abspath(os.path.join(here, "..", "..")))
74
+ p.add_argument("--out_dir", default=here)
75
+ args = p.parse_args()
76
+
77
+ models = sorted(m for m in os.listdir(os.path.join(args.root, "result"))
78
+ if not m.startswith("_")
79
+ and os.path.isdir(os.path.join(args.root, "result", m)))
80
+
81
+ acc = {} # (model, task, baseline) -> metrics dict
82
+ for m in models:
83
+ for t in TASKS:
84
+ for b in BASELINES:
85
+ acc[(m, t, b)] = load_metrics(args.root, m, t, b)
86
+
87
+ # ---------------------------------------------------------- per baseline
88
+ rows = []
89
+ for m in models:
90
+ for t in TASKS:
91
+ for b in BASELINES:
92
+ d = acc[(m, t, b)]
93
+ rows.append({
94
+ "model": m, "task": t, "baseline": b,
95
+ "n": d["num_samples"], "accuracy": round(d["accuracy"], 4),
96
+ "num_correct": d["num_correct"],
97
+ "unparsed_rate": round(d["unparsed_rate"], 4),
98
+ "scoring": d["scoring"],
99
+ "chance": CHANCE[t], "floor": FLOORS[t],
100
+ "headroom_captured": round(
101
+ (d["accuracy"] - FLOORS[t]) / (1 - FLOORS[t]), 4),
102
+ })
103
+ write_csv(os.path.join(args.out_dir, "accuracy_by_baseline.csv"), rows)
104
+
105
+ # ------------------------------------------------------- per model/task
106
+ summary = []
107
+ for m in models:
108
+ for t in TASKS:
109
+ a = [acc[(m, t, b)]["accuracy"] for b in BASELINES]
110
+ xs = [float(b) for b in BASELINES]
111
+ summary.append({
112
+ "model": m, "task": t, "n": acc[(m, t, "0.00")]["num_samples"],
113
+ "scoring": acc[(m, t, "0.00")]["scoring"],
114
+ "chance": CHANCE[t], "floor": FLOORS[t],
115
+ "acc_b0": round(a[0], 4), "acc_mean": round(statistics.mean(a), 4),
116
+ "acc_min": round(min(a), 4), "acc_max": round(max(a), 4),
117
+ "acc_range": round(max(a) - min(a), 4),
118
+ "acc_std": round(statistics.pstdev(a), 4),
119
+ "slope_per_baseline": round(slope(xs, a), 4),
120
+ "delta_b025_minus_b0": round(a[-1] - a[0], 4),
121
+ "headroom_captured_mean": round(
122
+ (statistics.mean(a) - FLOORS[t]) / (1 - FLOORS[t]), 4),
123
+ "above_floor": statistics.mean(a) > FLOORS[t],
124
+ })
125
+ write_csv(os.path.join(args.out_dir, "summary_by_model_task.csv"), summary)
126
+
127
+ # --------------------------------------------------------------- biases
128
+ bias = []
129
+ for m in models:
130
+ for t in TASKS:
131
+ for b in BASELINES:
132
+ pred = collections.Counter()
133
+ ref = collections.Counter()
134
+ n = 0
135
+ for r in load_predictions(args.root, m, t, b):
136
+ pred[r["prediction_norm"]] += 1
137
+ ref[r["reference_norm"]] += 1
138
+ n += 1
139
+ top_label, top_n = pred.most_common(1)[0]
140
+ # what a model would score by always naming its own modal answer
141
+ majority_acc = ref[top_label] / n if n else 0.0
142
+ bias.append({
143
+ "model": m, "task": t, "baseline": b, "n": n,
144
+ "n_distinct_predictions": len(pred),
145
+ "modal_prediction": top_label,
146
+ "modal_share": round(top_n / n, 4),
147
+ "prediction_entropy_bits": round(entropy(pred), 4),
148
+ "reference_entropy_bits": round(entropy(ref), 4),
149
+ "always_modal_accuracy": round(majority_acc, 4),
150
+ "accuracy": round(acc[(m, t, b)]["accuracy"], 4),
151
+ "prediction_counts": json.dumps(dict(sorted(pred.items()))),
152
+ })
153
+ write_csv(os.path.join(args.out_dir, "prediction_bias.csv"), bias)
154
+
155
+ ladder = level2_ladder(args.root, models)
156
+ if ladder:
157
+ write_csv(os.path.join(args.out_dir, "level2_structure_use.csv"), ladder)
158
+
159
+ report(models, acc, summary, bias, ladder)
160
+ print(f"\nwrote {3 + bool(ladder)} CSVs to {args.out_dir}")
161
+ return 0
162
+
163
+
164
+ # the split lives in the repo, one level above this experiment directory
165
+ LEVEL2_TEST = os.path.join("..", "02_data", "Youtube_self_depth_QA",
166
+ "level2", "test.jsonl")
167
+
168
+
169
+ def _prefix_survivors(options):
170
+ """The options a majority vote on successive positions cannot rule out.
171
+
172
+ A regression guard. With random distractors this should leave most items
173
+ undecided and score at chance; if it ever climbs toward 0.5 again, the
174
+ option construction has reacquired a structural leak.
175
+ """
176
+ alive = list(options)
177
+ seqs = {lab: txt.split(" > ") for lab, txt in options.items()}
178
+ for k in range(4):
179
+ if len(alive) <= 1:
180
+ break
181
+ counts = collections.Counter(seqs[a][k] for a in alive)
182
+ top = counts.most_common(1)[0][1]
183
+ winners = [l for l, v in counts.items() if v == top]
184
+ if len(winners) == 1:
185
+ alive = [a for a in alive if seqs[a][k] == winners[0]]
186
+ return alive
187
+
188
+
189
+ def level2_ladder(root: str, models):
190
+ """How often each model's answer lands inside the structure-only survivor set."""
191
+ path = os.path.abspath(os.path.join(root, LEVEL2_TEST))
192
+ if not os.path.exists(path):
193
+ print(f"[warn] level-2 split not found at {path}; skipping ladder analysis")
194
+ return []
195
+ test = {}
196
+ with open(path) as fh:
197
+ for line in fh:
198
+ rec = json.loads(line)
199
+ if rec.get("options"):
200
+ test[rec["sample_id"]] = rec["options"]
201
+ if not test:
202
+ return []
203
+ out = []
204
+ for m in models:
205
+ for b in BASELINES:
206
+ inside = hit = n = 0
207
+ for r in load_predictions(root, m, "youtube_level2", b):
208
+ opts = test.get(r["sample_id"])
209
+ if not opts:
210
+ continue
211
+ alive = _prefix_survivors(opts)
212
+ n += 1
213
+ inside += int(r["prediction_norm"] in alive)
214
+ hit += int(r["correct"])
215
+ out.append({
216
+ "model": m, "baseline": b, "n": n,
217
+ "answer_in_survivor_set": round(inside / n, 4) if n else 0.0,
218
+ "accuracy": round(hit / n, 4) if n else 0.0,
219
+ # of the answers that did land in the survivor set, how many were
220
+ # right: this is the coin flip the structure cannot decide
221
+ "accuracy_within_survivors": round(hit / inside, 4) if inside else 0.0,
222
+ })
223
+ return out
224
+
225
+
226
+ def write_csv(path: str, rows) -> None:
227
+ with open(path, "w", newline="") as fh:
228
+ w = csv.DictWriter(fh, fieldnames=list(rows[0]))
229
+ w.writeheader()
230
+ w.writerows(rows)
231
+
232
+
233
+ def report(models, acc, summary, bias, ladder=()) -> None:
234
+ short = {m: m.replace("Qwen_Qwen", "").replace("-Instruct", "") for m in models}
235
+ idx = {(r["model"], r["task"]): r for r in summary}
236
+
237
+ print("=" * 96)
238
+ print("ACCURACY (mean over the six baselines; floor = what the split gives "
239
+ "away for free)")
240
+ print("=" * 96)
241
+ print(f'{"model":22s}' + "".join(f"{t.replace('youtube_','yt_'):>16s}" for t in TASKS))
242
+ print(f'{"floor":22s}' + "".join(f"{FLOORS[t]:>16.3f}" for t in TASKS))
243
+ print("-" * 96)
244
+ for m in models:
245
+ print(f"{short[m]:22s}" + "".join(
246
+ f'{idx[(m,t)]["acc_mean"]:>16.3f}' for t in TASKS))
247
+ print()
248
+ print("HEADROOM CAPTURED (acc - floor) / (1 - floor); negative = below floor")
249
+ print("-" * 96)
250
+ for m in models:
251
+ cells = []
252
+ for t in TASKS:
253
+ v = idx[(m, t)]["headroom_captured_mean"]
254
+ cells.append(f"{v:>+15.3f} " if v < 0 else f"{v:>16.3f}")
255
+ print(f"{short[m]:22s}" + "".join(cells))
256
+ print()
257
+ print("BASELINE SENSITIVITY range over 0.00-0.25 / slope per unit baseline")
258
+ print("-" * 96)
259
+ for m in models:
260
+ print(f"{short[m]:22s}" + "".join(
261
+ f'{idx[(m,t)]["acc_range"]:>7.3f}/{idx[(m,t)]["slope_per_baseline"]:>+8.3f}'
262
+ for t in TASKS))
263
+ print()
264
+ print("ANSWER COLLAPSE modal predicted label, its share, and what always "
265
+ "answering it would score (baseline 0.00)")
266
+ print("-" * 96)
267
+ bidx = {(r["model"], r["task"], r["baseline"]): r for r in bias}
268
+ for m in models:
269
+ cells = []
270
+ for t in TASKS:
271
+ r = bidx[(m, t, "0.00")]
272
+ cells.append(f'{r["modal_prediction"]:>7s}{r["modal_share"]:>6.2f}'
273
+ f'{r["always_modal_accuracy"]:>7.3f}')
274
+ print(f"{short[m]:22s}" + "".join(cells))
275
+ print(" (reference labels are near-uniform, so 'always modal' sits at chance)")
276
+
277
+ if ladder:
278
+ print()
279
+ print("LEVEL 2 REGRESSION GUARD -- can a text-only majority vote still help?")
280
+ print("-" * 96)
281
+ lidx = {(r["model"], r["baseline"]): r for r in ladder}
282
+ for m in models:
283
+ r = lidx[(m, "0.00")]
284
+ print(f'{short[m]:22s} answer inside the vote survivors '
285
+ f'{r["answer_in_survivor_set"]:.3f} accuracy {r["accuracy"]:.3f}')
286
+ print(" distractors are random, so the vote rarely decides anything; a")
287
+ print(" survivor rate near 1.0 means it eliminated nothing.")
288
+
289
+
290
+ if __name__ == "__main__":
291
+ raise SystemExit(main())
analysis/dataset_level_analysis/build_notebook.py ADDED
@@ -0,0 +1,463 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Build dataset_difficulty.ipynb from the cell sources below."""
3
+ import nbformat as nbf, os
4
+
5
+ OUT = ("/HDD2/disheng/Spatial_VLM_Stereo/June/Spatial_VLM_Stereo/"
6
+ "01_3_prelimilary_intervention_different_baseline/analysis/"
7
+ "dataset_level_analysis/dataset_difficulty.ipynb")
8
+
9
+ C = []
10
+ md = lambda s: C.append(nbf.v4.new_markdown_cell(s.strip("\n")))
11
+ co = lambda s: C.append(nbf.v4.new_code_cell(s.strip("\n")))
12
+
13
+ md(r"""
14
+ # How hard is each split, and do the models agree?
15
+
16
+ Four models answer four splits at six stereo baselines. This notebook asks two
17
+ things the raw accuracy table cannot: **how hard is each split once its own
18
+ guessing floor is taken out**, and **do the models find the same items hard**.
19
+
20
+ Raw accuracy is not comparable across splits. VSR is a two-way true/false
21
+ question, so guessing already scores 0.500; the three Youtube levels are
22
+ four-way, so guessing scores 0.250. Everything below is therefore reported as
23
+
24
+ $$\text{headroom captured} = \frac{\text{acc} - \text{floor}}{1 - \text{floor}}$$
25
+
26
+ the share of the distance between guessing and perfect that a model actually
27
+ covers. It goes negative when a model does worse than free.
28
+ """)
29
+
30
+ md("## Setup")
31
+
32
+ co(r"""
33
+ import json, pathlib, itertools, warnings
34
+ import numpy as np
35
+ import pandas as pd
36
+ import matplotlib as mpl
37
+ import matplotlib.pyplot as plt
38
+
39
+ warnings.filterwarnings("ignore")
40
+ pd.set_option("display.width", 200)
41
+
42
+ HERE = pathlib.Path.cwd()
43
+ ROOT = HERE if (HERE / "result").is_dir() else HERE.parents[1]
44
+ RESULT = ROOT / "result"
45
+ REPO = ROOT.parent
46
+ FIGDIR = ROOT / "analysis" / "dataset_level_analysis" / "figures"
47
+ FIGDIR.mkdir(parents=True, exist_ok=True)
48
+
49
+ BASELINES = ["0.00", "0.05", "0.10", "0.15", "0.20", "0.25"]
50
+ TASKS = ["vsr", "youtube_level1", "youtube_level2", "youtube_level3"]
51
+ NICE = {"vsr": "VSR", "youtube_level1": "YT L1", "youtube_level2": "YT L2",
52
+ "youtube_level3": "YT L3"}
53
+
54
+ # guessing floor per split -- all four are plain chance among the options
55
+ FLOOR = {"vsr": 0.500, "youtube_level1": 0.250,
56
+ "youtube_level2": 0.250, "youtube_level3": 0.250}
57
+ CHANCE = dict(FLOOR)
58
+
59
+ MODELS = sorted(p.name for p in RESULT.iterdir()
60
+ if p.is_dir() and not p.name.startswith("_"))
61
+ SHORT = {m: m.replace("Qwen_Qwen", "").replace("-Instruct", "") for m in MODELS}
62
+ COLOR = dict(zip(MODELS, ["#4C72B0", "#DD8452", "#55A868", "#C44E52"]))
63
+
64
+ mpl.rcParams.update({
65
+ "figure.dpi": 120, "savefig.dpi": 150, "font.size": 10,
66
+ "axes.spines.top": False, "axes.spines.right": False,
67
+ "axes.grid": True, "grid.alpha": .25, "grid.linewidth": .6,
68
+ "axes.axisbelow": True, "legend.frameon": False,
69
+ })
70
+ print(f"root : {ROOT}")
71
+ print(f"models : {[SHORT[m] for m in MODELS]}")
72
+ """)
73
+
74
+ md("### Load every run")
75
+
76
+ co(r"""
77
+ rows = []
78
+ for m in MODELS:
79
+ for t in TASKS:
80
+ for b in BASELINES:
81
+ d = json.loads((RESULT / m / t / f"baseline_{b}" / "metrics.json").read_text())
82
+ rows.append(dict(model=m, short=SHORT[m], task=t, baseline=float(b),
83
+ n=d["num_samples"], accuracy=d["accuracy"],
84
+ scoring=d["scoring"], unparsed=d["unparsed_rate"]))
85
+ runs = pd.DataFrame(rows)
86
+ runs["floor"] = runs["task"].map(FLOOR)
87
+ runs["headroom"] = (runs["accuracy"] - runs["floor"]) / (1 - runs["floor"])
88
+ assert len(runs) == len(MODELS) * len(TASKS) * len(BASELINES), "missing runs"
89
+
90
+ # An unparsed answer is scored wrong, so a model that narrates instead of naming
91
+ # a letter is penalised twice. Report the rate rather than assume it is zero.
92
+ bad = runs[runs.unparsed > 0]
93
+ if len(bad):
94
+ print("runs with unparsable answers (counted as wrong):")
95
+ print(bad.groupby(["short", "task"]).unparsed.agg(["max", "mean"]).round(4)
96
+ .to_string())
97
+ else:
98
+ print("every answer parsed in every run")
99
+
100
+ acc = runs.pivot_table(index="short", columns="task", values="accuracy", aggfunc="mean")[TASKS]
101
+ head = runs.pivot_table(index="short", columns="task", values="headroom", aggfunc="mean")[TASKS]
102
+ acc.columns = head.columns = [NICE[t] for t in TASKS]
103
+ display(acc.round(3).rename_axis("accuracy (mean over baselines)"))
104
+ display(head.round(3).rename_axis("headroom captured"))
105
+ """)
106
+
107
+ md(r"""
108
+ ## 1. Where each model sits relative to its free floor
109
+
110
+ The bar is the accuracy; the dashed rule is what the split hands over for
111
+ nothing. Anything below the rule is a model doing worse than a rule that ignores
112
+ the picture.
113
+ """)
114
+
115
+ co(r"""
116
+ fig, axes = plt.subplots(1, 4, figsize=(13, 3.4), sharey=True)
117
+ for ax, t in zip(axes, TASKS):
118
+ sub = runs[runs.task == t].groupby("short", sort=False)
119
+ means = [runs[(runs.task == t) & (runs.model == m)].accuracy.mean() for m in MODELS]
120
+ errs = [runs[(runs.task == t) & (runs.model == m)].accuracy.std() for m in MODELS]
121
+ x = np.arange(len(MODELS))
122
+ ax.bar(x, means, yerr=errs, capsize=3, color=[COLOR[m] for m in MODELS],
123
+ edgecolor="white", linewidth=.8)
124
+ ax.axhline(FLOOR[t], ls="--", lw=1.4, color="#333")
125
+ ax.text(len(MODELS) - .45, FLOOR[t] + .012, f"floor {FLOOR[t]:.2f}",
126
+ ha="right", fontsize=8.5, color="#333")
127
+ if CHANCE[t] != FLOOR[t]:
128
+ ax.axhline(CHANCE[t], ls=":", lw=1.1, color="#999")
129
+ ax.text(-.45, CHANCE[t] + .012, f"guessing {CHANCE[t]:.2f}",
130
+ fontsize=8, color="#888")
131
+ ax.set_xticks(x); ax.set_xticklabels([SHORT[m] for m in MODELS], rotation=30, ha="right")
132
+ ax.set_title(f"{NICE[t]} (n={runs[runs.task==t].n.iloc[0]})", fontsize=11)
133
+ axes[0].set_ylabel("accuracy"); axes[0].set_ylim(0, 1)
134
+ fig.suptitle("Accuracy against the free floor, averaged over the six baselines",
135
+ y=1.04, fontsize=12)
136
+ fig.tight_layout(); fig.savefig(FIGDIR / "01_accuracy_vs_floor.png", bbox_inches="tight")
137
+ """)
138
+
139
+ md(r"""
140
+ ## 2. Difficulty, on one scale
141
+
142
+ Headroom captured puts the four splits on a common axis. Red is a model losing
143
+ to its own floor.
144
+ """)
145
+
146
+ co(r"""
147
+ fig, ax = plt.subplots(figsize=(7.2, 3.2))
148
+ data = head.values
149
+ vmax = np.abs(data).max()
150
+ im = ax.imshow(data, cmap="RdYlGn", vmin=-vmax, vmax=vmax, aspect="auto")
151
+ ax.set_xticks(range(len(TASKS))); ax.set_xticklabels(head.columns)
152
+ ax.set_yticks(range(len(MODELS))); ax.set_yticklabels(head.index)
153
+ for i in range(data.shape[0]):
154
+ for j in range(data.shape[1]):
155
+ ax.text(j, i, f"{data[i,j]:+.2f}", ha="center", va="center", fontsize=10,
156
+ color="black")
157
+ ax.grid(False)
158
+ ax.set_title("Headroom captured (acc - floor) / (1 - floor)")
159
+ fig.colorbar(im, ax=ax, shrink=.85, label="share of headroom")
160
+ fig.tight_layout(); fig.savefig(FIGDIR / "02_headroom_heatmap.png", bbox_inches="tight")
161
+ """)
162
+
163
+ md(r"""
164
+ ## 3. Do the models rank the splits the same way?
165
+
166
+ One line per model across the four splits. Parallel lines mean the models agree
167
+ on which split is hard and differ only in overall strength; crossings mean a
168
+ model finds a particular split unusually easy or hard.
169
+ """)
170
+
171
+ co(r"""
172
+ order = list(head.mean().sort_values(ascending=False).index)
173
+ fig, ax = plt.subplots(figsize=(7.6, 4.0))
174
+ for m in MODELS:
175
+ y = [head.loc[SHORT[m], c] for c in order]
176
+ ax.plot(range(len(order)), y, "-o", color=COLOR[m], lw=2, ms=6, label=SHORT[m])
177
+ ax.axhline(0, color="#333", lw=1.2, ls="--")
178
+ ax.text(len(order) - 1, .015, "floor", ha="right", fontsize=8.5, color="#333")
179
+ ax.set_xticks(range(len(order))); ax.set_xticklabels(order)
180
+ ax.set_ylabel("headroom captured"); ax.set_title("Difficulty profile per model")
181
+ ax.legend(loc="upper right", ncol=2)
182
+ fig.tight_layout(); fig.savefig(FIGDIR / "03_difficulty_profile.png", bbox_inches="tight")
183
+
184
+ ranks = head.rank(axis=1, ascending=False).astype(int)
185
+ print("difficulty rank each model assigns (1 = most headroom captured):")
186
+ display(ranks)
187
+ print("Spearman between models (only four splits, so 1.00 means identical order):")
188
+ display(head.T.corr(method="spearman").round(2))
189
+ """)
190
+
191
+ md(r"""
192
+ ## 4. Does the stereo baseline move anything?
193
+
194
+ Each panel is one split; each line is one model across the six baselines. A
195
+ visual tower that models the scene properly should be flat here — the question
196
+ and the answer never change, only the viewpoint.
197
+ """)
198
+
199
+ co(r"""
200
+ fig, axes = plt.subplots(1, 4, figsize=(13.5, 3.2))
201
+ for ax, t in zip(axes, TASKS):
202
+ for m in MODELS:
203
+ s = runs[(runs.task == t) & (runs.model == m)].sort_values("baseline")
204
+ ax.plot(s.baseline, s.accuracy, "-o", ms=4, color=COLOR[m], label=SHORT[m])
205
+ ax.axhline(FLOOR[t], ls="--", lw=1.1, color="#666")
206
+ ax.set_title(NICE[t]); ax.set_xlabel("baseline")
207
+ lo = min(runs[runs.task == t].accuracy.min(), FLOOR[t]) - .03
208
+ hi = max(runs[runs.task == t].accuracy.max(), FLOOR[t]) + .03
209
+ ax.set_ylim(lo, hi)
210
+ axes[0].set_ylabel("accuracy")
211
+ axes[-1].legend(loc="center left", bbox_to_anchor=(1.02, .5))
212
+ fig.suptitle("Accuracy across the intervention, per split", y=1.05, fontsize=12)
213
+ fig.tight_layout(); fig.savefig(FIGDIR / "04_baseline_sensitivity.png", bbox_inches="tight")
214
+
215
+ spread = (runs.groupby(["short", "task"]).accuracy.agg(["min", "max"])
216
+ .assign(range=lambda d: d["max"] - d["min"])["range"]
217
+ .unstack()[TASKS].rename(columns=NICE))
218
+ display(spread.round(3).rename_axis("accuracy range over the six baselines"))
219
+ """)
220
+
221
+ md(r"""
222
+ ## 5. Item-level difficulty: do the models fail on the same pictures?
223
+
224
+ For every item, count how many of the four models get it right at baseline 0.00.
225
+ If difficulty were a property of the item, the counts would pile up at 0 and 4.
226
+ If each model failed idiosyncratically, the counts would follow the independent
227
+ (Poisson-binomial) null drawn behind the bars.
228
+ """)
229
+
230
+ co(r"""
231
+ def load_pred(m, t, b="0.00"):
232
+ path = RESULT / m / t / f"baseline_{b}" / "predictions.jsonl"
233
+ return {json.loads(l)["sample_id"]: json.loads(l)
234
+ for l in path.read_text().splitlines() if l.strip()}
235
+
236
+ correct_by_task = {}
237
+ for t in TASKS:
238
+ per = {m: load_pred(m, t) for m in MODELS}
239
+ ids = sorted(set.intersection(*(set(v) for v in per.values())))
240
+ correct_by_task[t] = pd.DataFrame(
241
+ {SHORT[m]: [per[m][i]["correct"] for i in ids] for m in MODELS}, index=ids)
242
+
243
+ def poisson_binomial(ps):
244
+ dist = np.zeros(len(ps) + 1); dist[0] = 1.0
245
+ for p in ps:
246
+ dist[1:] = dist[1:] * (1 - p) + dist[:-1] * p
247
+ dist[0] *= (1 - p)
248
+ return dist
249
+
250
+ fig, axes = plt.subplots(1, 4, figsize=(13.5, 3.2), sharey=True)
251
+ conc = {}
252
+ for ax, t in zip(axes, TASKS):
253
+ df = correct_by_task[t]
254
+ k = df.sum(axis=1).value_counts().reindex(range(5), fill_value=0).sort_index()
255
+ obs = k / k.sum()
256
+ null = poisson_binomial(df.mean().values)
257
+ ax.bar(range(5), null, color="#CCCCCC", width=.82, label="independent null")
258
+ ax.bar(range(5), obs, color="#4C72B0", width=.45, label="observed")
259
+ ax.set_title(f"{NICE[t]} (n={len(df)})"); ax.set_xlabel("# models correct")
260
+ ax.set_xticks(range(5))
261
+ # how much mass sits at the two extremes, versus the null
262
+ conc[NICE[t]] = dict(observed_0_or_4=obs.iloc[[0, 4]].sum(),
263
+ null_0_or_4=null[[0, 4]].sum())
264
+ axes[0].set_ylabel("share of items"); axes[0].legend(fontsize=8.5)
265
+ fig.suptitle("Agreement on which items are hard", y=1.05, fontsize=12)
266
+ fig.tight_layout(); fig.savefig(FIGDIR / "05_item_difficulty.png", bbox_inches="tight")
267
+
268
+ conc = pd.DataFrame(conc).T
269
+ conc["excess"] = conc["observed_0_or_4"] - conc["null_0_or_4"]
270
+ display(conc.round(3).rename_axis("mass at 0 or 4 models correct"))
271
+ """)
272
+
273
+ md(r"""
274
+ ## 6. Failure overlap between models
275
+
276
+ Jaccard overlap of the failure sets, per split. High values mean the models
277
+ stumble on the same items — shared difficulty rather than independent noise.
278
+ """)
279
+
280
+ co(r"""
281
+ fig, axes = plt.subplots(1, 4, figsize=(14, 3.4))
282
+ for ax, t in zip(axes, TASKS):
283
+ df = correct_by_task[t]
284
+ names = list(df.columns)
285
+ M = np.ones((len(names), len(names)))
286
+ for i, a in enumerate(names):
287
+ for j, b in enumerate(names):
288
+ if i == j:
289
+ continue
290
+ fa, fb = ~df[a].values, ~df[b].values
291
+ M[i, j] = (fa & fb).sum() / max((fa | fb).sum(), 1)
292
+ im = ax.imshow(M, cmap="Blues", vmin=0, vmax=1)
293
+ ax.set_xticks(range(len(names))); ax.set_xticklabels(names, rotation=40, ha="right", fontsize=8)
294
+ ax.set_yticks(range(len(names))); ax.set_yticklabels(names, fontsize=8)
295
+ for i in range(len(names)):
296
+ for j in range(len(names)):
297
+ ax.text(j, i, f"{M[i,j]:.2f}", ha="center", va="center", fontsize=8,
298
+ color="white" if M[i, j] > .55 else "black")
299
+ ax.grid(False); ax.set_title(NICE[t], fontsize=11)
300
+ fig.suptitle("Jaccard overlap of failure sets (baseline 0.00)", y=1.06, fontsize=12)
301
+ fig.tight_layout(); fig.savefig(FIGDIR / "06_failure_overlap.png", bbox_inches="tight")
302
+ """)
303
+
304
+ md(r"""
305
+ ## 7. Is the model answering, or just picking a letter?
306
+
307
+ The reference labels are near-uniform in every split, so a flat prediction
308
+ histogram is what an unbiased model produces. A spike means the model has
309
+ collapsed onto one option, and that spike caps how well it can possibly do.
310
+ """)
311
+
312
+ co(r"""
313
+ fig, axes = plt.subplots(len(MODELS), 4, figsize=(12, 2.3 * len(MODELS)),
314
+ sharey="row")
315
+ for r, m in enumerate(MODELS):
316
+ for c, t in enumerate(TASKS):
317
+ ax = axes[r, c]
318
+ pred = load_pred(m, t)
319
+ pc = pd.Series([v["prediction_norm"] for v in pred.values()]).value_counts()
320
+ rc = pd.Series([v["reference_norm"] for v in pred.values()]).value_counts()
321
+ labels = sorted(set(pc.index) | set(rc.index))
322
+ x = np.arange(len(labels))
323
+ ax.bar(x - .2, [rc.get(l, 0) / len(pred) for l in labels], width=.4,
324
+ color="#BBBBBB", label="reference")
325
+ ax.bar(x + .2, [pc.get(l, 0) / len(pred) for l in labels], width=.4,
326
+ color=COLOR[m], label="prediction")
327
+ ax.set_xticks(x); ax.set_xticklabels(labels, fontsize=8)
328
+ ax.axhline(1 / len(labels), ls=":", lw=1, color="#666")
329
+ if r == 0:
330
+ ax.set_title(NICE[t])
331
+ if c == 0:
332
+ ax.set_ylabel(SHORT[m], fontsize=9)
333
+ if r == 0 and c == 0:
334
+ ax.legend(fontsize=7.5)
335
+ fig.suptitle("Predicted vs reference label distribution (baseline 0.00)",
336
+ y=1.01, fontsize=12)
337
+ fig.tight_layout(); fig.savefig(FIGDIR / "07_answer_bias.png", bbox_inches="tight")
338
+ """)
339
+
340
+ md(r"""
341
+ ## 8. Level 2 regression guard: is the option text still uninformative?
342
+
343
+ Level 2's three distractors are drawn uniformly from the 23 wrong orderings, so
344
+ the four options should be statistically exchangeable and no text-only rule
345
+ should beat chance. Earlier, structured distractor sets did not have that
346
+ property — the worst of them let a majority vote on successive positions narrow
347
+ every item to two candidates and score 0.500 blind.
348
+
349
+ This cell re-runs that vote. `in survivor set` near 1.0 means the vote eliminated
350
+ nothing, which is what random distractors should produce. If it ever drops
351
+ toward 0.5 while accuracy rises, the construction has reacquired a leak.
352
+ """)
353
+
354
+ co(r"""
355
+ L2_TEST = REPO / "02_data" / "Youtube_self_depth_QA" / "level2" / "test.jsonl"
356
+ rows = []
357
+ if L2_TEST.exists():
358
+ opts = {}
359
+ for line in L2_TEST.read_text().splitlines():
360
+ rec = json.loads(line)
361
+ if rec.get("options"):
362
+ opts[rec["sample_id"]] = {k: v.split(" > ") for k, v in rec["options"].items()}
363
+
364
+ def survivors(o):
365
+ alive = list(o)
366
+ for k in range(4):
367
+ if len(alive) <= 1:
368
+ break
369
+ counts = pd.Series([o[a][k] for a in alive]).value_counts()
370
+ if len(counts) > 1 and counts.iloc[0] == counts.iloc[1]:
371
+ continue
372
+ alive = [a for a in alive if o[a][k] == counts.index[0]]
373
+ return alive
374
+
375
+ surv = {sid: survivors(o) for sid, o in opts.items()}
376
+ for m in MODELS:
377
+ pred = load_pred(m, "youtube_level2")
378
+ ins = [p["prediction_norm"] in surv[s] for s, p in pred.items() if s in surv]
379
+ hit = [p["correct"] for s, p in pred.items() if s in surv]
380
+ rows.append(dict(model=SHORT[m], accuracy=np.mean(hit),
381
+ in_survivor_set=np.mean(ins)))
382
+ l2 = pd.DataFrame(rows).set_index("model")
383
+ surv = np.mean([len(v) for v in surv.values()])
384
+ print(f"mean survivor-set size after the vote: {surv:.2f} of 4 options")
385
+ display(l2.round(3))
386
+
387
+ fig, ax = plt.subplots(figsize=(7, 3.2))
388
+ x = np.arange(len(l2))
389
+ ax.bar(x - .2, l2.in_survivor_set, width=.4, color="#999",
390
+ label="answer survives the text-only vote")
391
+ ax.bar(x + .2, l2.accuracy, width=.4, color="#C44E52", label="accuracy")
392
+ ax.axhline(.25, ls="--", color="#333", lw=1.3)
393
+ ax.text(len(l2) - .4, .265, "chance", ha="right", fontsize=8.5)
394
+ ax.set_xticks(x); ax.set_xticklabels(l2.index, rotation=25, ha="right")
395
+ ax.set_ylim(0, 1); ax.set_ylabel("share")
396
+ ax.set_title("Level 2: random distractors leave the text-only vote powerless")
397
+ ax.legend()
398
+ fig.tight_layout(); fig.savefig(FIGDIR / "08_level2_guard.png", bbox_inches="tight")
399
+ else:
400
+ print(f"level-2 split not found at {L2_TEST}; skipping")
401
+ """)
402
+
403
+ md(r"""
404
+ ## Findings
405
+
406
+ **1. Every model puts VSR first and YT L1 second; the two families then
407
+ disagree.** Qwen2.5-VL finds level 3 hardest, Qwen3.5 finds level 2 hardest.
408
+ Spearman is 1.00 within a family and 0.80 across, so the ordering of the two
409
+ Youtube reasoning levels is the one place where architecture, not just
410
+ strength, changes what looks hard.
411
+
412
+ **2. Only VSR is comfortably solved** (0.52-0.66 of headroom). It is also the
413
+ easiest question type: a binary relation that is often inferable from object
414
+ identity alone, without metric depth.
415
+
416
+ **3. Level 3 is the sharpest discriminator.** Qwen2.5-VL captures 0.03 (3B) and
417
+ 0.07 (7B) — indistinguishable from guessing — against 0.29 and 0.33 for
418
+ Qwen3.5. A 4-10x gap, far wider than anywhere else in the suite. Continuous
419
+ trajectory reasoning is what separates the two families.
420
+
421
+ **4. Level 2 sits at 0.17-0.26 of headroom for everyone**, a narrow band that
422
+ does not track model size or family. Its distractors are drawn at random from
423
+ the 23 wrong orderings, so nothing in the option text helps (figure 8: the
424
+ text-only vote leaves ~2 of 4 options standing and scores 0.252 on the split,
425
+ i.e. chance). The scores are what four-way depth ranking actually costs these
426
+ models: clearly above guessing, nowhere near solved.
427
+
428
+ **5. The base model beats the instruct model on every split.** Qwen3.5-4B-Base
429
+ scored by likelihood outperforms Qwen3.5-4B scored by generation everywhere,
430
+ and 4B-Instruct is the only model producing unparsable answers (up to 0.7% on
431
+ L1), which are scored wrong. Part of the instruct model's deficit is format
432
+ compliance, not perception.
433
+
434
+ **6. The stereo intervention barely moves the aggregate.** Accuracy ranges over
435
+ the six baselines are 0.012-0.044 with no consistent sign across models or
436
+ splits. Whether the same *items* flip is a separate question, answered in
437
+ `../intervention_analysis`.
438
+
439
+ **7. Models agree most on which L1 items are hard, least on L3.** Excess mass at
440
+ "0 or 4 models correct" over the independent null: +0.36 (L1), +0.27 (VSR),
441
+ +0.23 (L2), +0.14 (L3). On L3 the failures are close to independent noise, which
442
+ is what near-chance accuracy looks like — there is little shared signal to agree
443
+ about.
444
+
445
+ ### A note on the level-2 numbers
446
+
447
+ Level 2 was rebuilt three times before this run. Two earlier option
448
+ constructions leaked: distractors grown outward from the ground truth made it
449
+ the option most similar to the others (0.388 blind), and a prefix ladder let a
450
+ majority vote narrow every item to two (0.500 blind). Under the leaking
451
+ constructions these same models scored 0.40-0.47 on level 2; with random
452
+ distractors they score 0.37-0.45 against a real 0.25 floor. The drop of
453
+ 0.02-0.10 is the part of the old score that came from the option text rather
454
+ than the picture.
455
+ """)
456
+
457
+ nb = nbf.v4.new_notebook(cells=C)
458
+ nb.metadata.kernelspec = {"display_name": "Spatial_VLM", "language": "python",
459
+ "name": "python3"}
460
+ nb.metadata.language_info = {"name": "python"}
461
+ os.makedirs(os.path.dirname(OUT), exist_ok=True)
462
+ nbf.write(nb, OUT)
463
+ print("wrote", OUT, f"({len(C)} cells)")
analysis/dataset_level_analysis/dataset_difficulty.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
analysis/dataset_level_analysis/figures/01_accuracy_vs_floor.png ADDED
analysis/dataset_level_analysis/figures/02_headroom_heatmap.png ADDED
analysis/dataset_level_analysis/figures/03_difficulty_profile.png ADDED
analysis/dataset_level_analysis/figures/04_baseline_sensitivity.png ADDED

Git LFS Details

  • SHA256: 239a312a77c3cc845b5f70b8b34de24ab1d564198f584261babdebe7019d068d
  • Pointer size: 131 Bytes
  • Size of remote file: 104 kB
analysis/dataset_level_analysis/figures/05_item_difficulty.png ADDED
analysis/dataset_level_analysis/figures/06_failure_overlap.png ADDED
analysis/dataset_level_analysis/figures/07_answer_bias.png ADDED
analysis/dataset_level_analysis/figures/08_level2_guard.png ADDED
analysis/dataset_level_analysis/level2_structure_use.csv ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ model,baseline,n,answer_in_survivor_set,accuracy,accuracy_within_survivors
2
+ Qwen_Qwen2.5-VL-3B-Instruct,0.00,764,0.6898,0.3626,0.5256
3
+ Qwen_Qwen2.5-VL-3B-Instruct,0.05,764,0.6963,0.3743,0.5376
4
+ Qwen_Qwen2.5-VL-3B-Instruct,0.10,764,0.7042,0.3783,0.5372
5
+ Qwen_Qwen2.5-VL-3B-Instruct,0.15,764,0.7134,0.3796,0.5321
6
+ Qwen_Qwen2.5-VL-3B-Instruct,0.20,764,0.7186,0.3809,0.5301
7
+ Qwen_Qwen2.5-VL-3B-Instruct,0.25,764,0.7094,0.3704,0.5221
8
+ Qwen_Qwen2.5-VL-7B-Instruct,0.00,764,0.6898,0.4031,0.5844
9
+ Qwen_Qwen2.5-VL-7B-Instruct,0.05,764,0.7003,0.394,0.5626
10
+ Qwen_Qwen2.5-VL-7B-Instruct,0.10,764,0.699,0.3979,0.5693
11
+ Qwen_Qwen2.5-VL-7B-Instruct,0.15,764,0.6937,0.4018,0.5792
12
+ Qwen_Qwen2.5-VL-7B-Instruct,0.20,764,0.7016,0.377,0.5373
13
+ Qwen_Qwen2.5-VL-7B-Instruct,0.25,764,0.7068,0.377,0.5333
14
+ Qwen_Qwen3.5-4B,0.00,764,0.623,0.3914,0.6282
15
+ Qwen_Qwen3.5-4B,0.05,764,0.6178,0.3901,0.6314
16
+ Qwen_Qwen3.5-4B,0.10,764,0.6113,0.3822,0.6253
17
+ Qwen_Qwen3.5-4B,0.15,764,0.6191,0.3874,0.6258
18
+ Qwen_Qwen3.5-4B,0.20,764,0.6099,0.3796,0.6223
19
+ Qwen_Qwen3.5-4B,0.25,764,0.6034,0.3848,0.6377
20
+ Qwen_Qwen3.5-4B-Base,0.00,764,0.6178,0.4424,0.7161
21
+ Qwen_Qwen3.5-4B-Base,0.05,764,0.606,0.4529,0.7473
22
+ Qwen_Qwen3.5-4B-Base,0.10,764,0.6073,0.4503,0.7414
23
+ Qwen_Qwen3.5-4B-Base,0.15,764,0.6126,0.4542,0.7415
24
+ Qwen_Qwen3.5-4B-Base,0.20,764,0.6178,0.4503,0.7288
25
+ Qwen_Qwen3.5-4B-Base,0.25,764,0.6204,0.4398,0.7089
analysis/dataset_level_analysis/prediction_bias.csv ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ model,task,baseline,n,n_distinct_predictions,modal_prediction,modal_share,prediction_entropy_bits,reference_entropy_bits,always_modal_accuracy,accuracy,prediction_counts
2
+ Qwen_Qwen2.5-VL-3B-Instruct,vsr,0.00,2195,2,false,0.513,0.9995,0.9958,0.462,0.7713,"{""false"": 1126, ""true"": 1069}"
3
+ Qwen_Qwen2.5-VL-3B-Instruct,vsr,0.05,2195,2,false,0.523,0.9985,0.9958,0.462,0.7677,"{""false"": 1148, ""true"": 1047}"
4
+ Qwen_Qwen2.5-VL-3B-Instruct,vsr,0.10,2195,2,false,0.5303,0.9974,0.9958,0.462,0.7595,"{""false"": 1164, ""true"": 1031}"
5
+ Qwen_Qwen2.5-VL-3B-Instruct,vsr,0.15,2195,2,false,0.5235,0.9984,0.9958,0.462,0.7581,"{""false"": 1149, ""true"": 1046}"
6
+ Qwen_Qwen2.5-VL-3B-Instruct,vsr,0.20,2195,2,false,0.528,0.9977,0.9958,0.462,0.7526,"{""false"": 1159, ""true"": 1036}"
7
+ Qwen_Qwen2.5-VL-3B-Instruct,vsr,0.25,2195,2,false,0.5308,0.9973,0.9958,0.462,0.7481,"{""false"": 1165, ""true"": 1030}"
8
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level1,0.00,821,4,B,0.3642,1.9258,1.9983,0.2704,0.3995,"{""A"": 212, ""B"": 299, ""C"": 116, ""D"": 194}"
9
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level1,0.05,821,4,B,0.3752,1.9189,1.9983,0.2704,0.4056,"{""A"": 202, ""B"": 308, ""C"": 115, ""D"": 196}"
10
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level1,0.10,821,4,B,0.3715,1.9203,1.9983,0.2704,0.4117,"{""A"": 202, ""B"": 305, ""C"": 114, ""D"": 200}"
11
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level1,0.15,821,4,B,0.3788,1.922,1.9983,0.2704,0.4105,"{""A"": 196, ""B"": 311, ""C"": 121, ""D"": 193}"
12
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level1,0.20,821,4,B,0.3825,1.9177,1.9983,0.2704,0.3995,"{""A"": 190, ""B"": 314, ""C"": 119, ""D"": 198}"
13
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level1,0.25,821,4,B,0.3691,1.9332,1.9983,0.2704,0.4007,"{""A"": 194, ""B"": 303, ""C"": 127, ""D"": 197}"
14
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level2,0.00,764,4,A,0.3128,1.9633,1.9962,0.2343,0.3626,"{""A"": 239, ""B"": 227, ""C"": 139, ""D"": 159}"
15
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level2,0.05,764,4,B,0.3089,1.9612,1.9962,0.2814,0.3743,"{""A"": 234, ""B"": 236, ""C"": 144, ""D"": 150}"
16
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level2,0.10,764,4,B,0.3115,1.9653,1.9962,0.2814,0.3783,"{""A"": 227, ""B"": 238, ""C"": 146, ""D"": 153}"
17
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level2,0.15,764,4,B,0.3063,1.9627,1.9962,0.2814,0.3796,"{""A"": 234, ""B"": 234, ""C"": 142, ""D"": 154}"
18
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level2,0.20,764,4,B,0.3259,1.9659,1.9962,0.2814,0.3809,"{""A"": 212, ""B"": 249, ""C"": 147, ""D"": 156}"
19
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level2,0.25,764,4,B,0.3115,1.9677,1.9962,0.2814,0.3704,"{""A"": 224, ""B"": 238, ""C"": 149, ""D"": 153}"
20
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level3,0.00,836,4,A,0.5694,1.5259,1.9927,0.2847,0.2667,"{""A"": 476, ""B"": 233, ""C"": 40, ""D"": 87}"
21
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level3,0.05,836,4,A,0.5443,1.5853,1.9927,0.2847,0.2452,"{""A"": 455, ""B"": 239, ""C"": 48, ""D"": 94}"
22
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level3,0.10,836,4,A,0.5622,1.5541,1.9927,0.2847,0.2392,"{""A"": 470, ""B"": 231, ""C"": 46, ""D"": 89}"
23
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level3,0.15,836,4,A,0.5323,1.5953,1.9927,0.2847,0.2524,"{""A"": 445, ""B"": 250, ""C"": 49, ""D"": 92}"
24
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level3,0.20,836,4,A,0.5275,1.6189,1.9927,0.2847,0.2596,"{""A"": 441, ""B"": 246, ""C"": 55, ""D"": 94}"
25
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level3,0.25,836,4,A,0.5467,1.5792,1.9927,0.2847,0.2656,"{""A"": 457, ""B"": 240, ""C"": 49, ""D"": 90}"
26
+ Qwen_Qwen2.5-VL-7B-Instruct,vsr,0.00,2195,2,false,0.5385,0.9957,0.9958,0.462,0.8223,"{""false"": 1182, ""true"": 1013}"
27
+ Qwen_Qwen2.5-VL-7B-Instruct,vsr,0.05,2195,2,false,0.5421,0.9949,0.9958,0.462,0.8077,"{""false"": 1190, ""true"": 1005}"
28
+ Qwen_Qwen2.5-VL-7B-Instruct,vsr,0.10,2195,2,false,0.5417,0.995,0.9958,0.462,0.8027,"{""false"": 1189, ""true"": 1006}"
29
+ Qwen_Qwen2.5-VL-7B-Instruct,vsr,0.15,2195,2,false,0.5476,0.9935,0.9958,0.462,0.8068,"{""false"": 1202, ""true"": 993}"
30
+ Qwen_Qwen2.5-VL-7B-Instruct,vsr,0.20,2195,2,false,0.5485,0.9932,0.9958,0.462,0.8023,"{""false"": 1204, ""true"": 991}"
31
+ Qwen_Qwen2.5-VL-7B-Instruct,vsr,0.25,2195,2,false,0.5544,0.9914,0.9958,0.462,0.7882,"{""false"": 1217, ""true"": 978}"
32
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level1,0.00,821,4,D,0.4799,1.8231,1.9983,0.2436,0.447,"{""A"": 141, ""B"": 144, ""C"": 142, ""D"": 394}"
33
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level1,0.05,821,4,D,0.4641,1.8454,1.9983,0.2436,0.4482,"{""A"": 152, ""B"": 146, ""C"": 142, ""D"": 381}"
34
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level1,0.10,821,4,D,0.4555,1.8564,1.9983,0.2436,0.4555,"{""A"": 140, ""B"": 157, ""C"": 150, ""D"": 374}"
35
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level1,0.15,821,4,D,0.4641,1.8455,1.9983,0.2436,0.4665,"{""A"": 142, ""B"": 150, ""C"": 148, ""D"": 381}"
36
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level1,0.20,821,4,D,0.4507,1.8634,1.9983,0.2436,0.4421,"{""A"": 146, ""B"": 154, ""C"": 151, ""D"": 370}"
37
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level1,0.25,821,4,D,0.4677,1.8404,1.9983,0.2436,0.4519,"{""A"": 141, ""B"": 148, ""C"": 148, ""D"": 384}"
38
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level2,0.00,764,4,D,0.3455,1.9146,1.9962,0.2408,0.4031,"{""A"": 107, ""B"": 242, ""C"": 151, ""D"": 264}"
39
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level2,0.05,764,4,B,0.3325,1.9084,1.9962,0.2814,0.394,"{""A"": 100, ""B"": 254, ""C"": 156, ""D"": 254}"
40
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level2,0.10,764,4,D,0.3521,1.9016,1.9962,0.2408,0.3979,"{""A"": 97, ""B"": 242, ""C"": 156, ""D"": 269}"
41
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level2,0.15,764,4,D,0.3547,1.9012,1.9962,0.2408,0.4018,"{""A"": 97, ""B"": 240, ""C"": 156, ""D"": 271}"
42
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level2,0.20,764,4,D,0.3573,1.921,1.9962,0.2408,0.377,"{""A"": 108, ""B"": 222, ""C"": 161, ""D"": 273}"
43
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level2,0.25,764,4,D,0.3442,1.9182,1.9962,0.2408,0.377,"{""A"": 104, ""B"": 236, ""C"": 161, ""D"": 263}"
44
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level3,0.00,836,4,B,0.5598,1.6491,1.9927,0.2608,0.2799,"{""A"": 72, ""B"": 468, ""C"": 175, ""D"": 121}"
45
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level3,0.05,836,4,B,0.561,1.6452,1.9927,0.2608,0.2871,"{""A"": 71, ""B"": 469, ""C"": 176, ""D"": 120}"
46
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level3,0.10,836,4,B,0.5646,1.6367,1.9927,0.2608,0.2679,"{""A"": 67, ""B"": 472, ""C"": 172, ""D"": 125}"
47
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level3,0.15,836,4,B,0.5586,1.6493,1.9927,0.2608,0.2823,"{""A"": 67, ""B"": 467, ""C"": 169, ""D"": 133}"
48
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level3,0.20,836,4,B,0.5658,1.6353,1.9927,0.2608,0.2763,"{""A"": 66, ""B"": 473, ""C"": 168, ""D"": 129}"
49
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level3,0.25,836,4,B,0.5658,1.6529,1.9927,0.2608,0.2739,"{""A"": 81, ""B"": 473, ""C"": 160, ""D"": 122}"
50
+ Qwen_Qwen3.5-4B,vsr,0.00,2195,2,true,0.5882,0.9775,0.9958,0.538,0.8214,"{""false"": 904, ""true"": 1291}"
51
+ Qwen_Qwen3.5-4B,vsr,0.05,2195,2,true,0.5941,0.9743,0.9958,0.538,0.8173,"{""false"": 891, ""true"": 1304}"
52
+ Qwen_Qwen3.5-4B,vsr,0.10,2195,2,true,0.5854,0.9788,0.9958,0.538,0.8187,"{""false"": 910, ""true"": 1285}"
53
+ Qwen_Qwen3.5-4B,vsr,0.15,2195,2,true,0.5872,0.9779,0.9958,0.538,0.8114,"{""false"": 906, ""true"": 1289}"
54
+ Qwen_Qwen3.5-4B,vsr,0.20,2195,2,true,0.585,0.9791,0.9958,0.538,0.8073,"{""false"": 911, ""true"": 1284}"
55
+ Qwen_Qwen3.5-4B,vsr,0.25,2195,2,true,0.5831,0.98,0.9958,0.538,0.8046,"{""false"": 915, ""true"": 1280}"
56
+ Qwen_Qwen3.5-4B,youtube_level1,0.00,821,7,A,0.2984,2.02,1.9983,0.2473,0.5274,"{""A"": 245, ""B"": 181, ""C"": 176, ""D"": 216, ""G"": 1, ""O"": 1, ""R"": 1}"
57
+ Qwen_Qwen3.5-4B,youtube_level1,0.05,821,6,A,0.2899,2.0402,1.9983,0.2473,0.5213,"{""A"": 238, ""B"": 183, ""C"": 173, ""D"": 221, ""G"": 1, ""O"": 5}"
58
+ Qwen_Qwen3.5-4B,youtube_level1,0.10,821,5,A,0.2911,2.0004,1.9983,0.2473,0.5189,"{""A"": 239, ""B"": 180, ""C"": 182, ""D"": 219, ""O"": 1}"
59
+ Qwen_Qwen3.5-4B,youtube_level1,0.15,821,6,A,0.3021,2.0238,1.9983,0.2473,0.5408,"{""A"": 248, ""B"": 177, ""C"": 177, ""D"": 215, ""G"": 1, ""O"": 3}"
60
+ Qwen_Qwen3.5-4B,youtube_level1,0.20,821,5,A,0.2801,2.0008,1.9983,0.2473,0.5347,"{""A"": 230, ""B"": 171, ""C"": 193, ""D"": 226, ""O"": 1}"
61
+ Qwen_Qwen3.5-4B,youtube_level1,0.25,821,4,A,0.2887,1.9889,1.9983,0.2473,0.5347,"{""A"": 237, ""B"": 173, ""C"": 189, ""D"": 222}"
62
+ Qwen_Qwen3.5-4B,youtube_level2,0.00,764,4,A,0.5537,1.6082,1.9962,0.2343,0.3914,"{""A"": 423, ""B"": 60, ""C"": 201, ""D"": 80}"
63
+ Qwen_Qwen3.5-4B,youtube_level2,0.05,764,4,A,0.5785,1.56,1.9962,0.2343,0.3901,"{""A"": 442, ""B"": 68, ""C"": 193, ""D"": 61}"
64
+ Qwen_Qwen3.5-4B,youtube_level2,0.10,764,4,A,0.5877,1.5489,1.9962,0.2343,0.3822,"{""A"": 449, ""B"": 62, ""C"": 186, ""D"": 67}"
65
+ Qwen_Qwen3.5-4B,youtube_level2,0.15,764,4,A,0.5759,1.5768,1.9962,0.2343,0.3874,"{""A"": 440, ""B"": 63, ""C"": 188, ""D"": 73}"
66
+ Qwen_Qwen3.5-4B,youtube_level2,0.20,764,4,A,0.5746,1.5784,1.9962,0.2343,0.3796,"{""A"": 439, ""B"": 63, ""C"": 189, ""D"": 73}"
67
+ Qwen_Qwen3.5-4B,youtube_level2,0.25,764,4,A,0.5785,1.5697,1.9962,0.2343,0.3848,"{""A"": 442, ""B"": 62, ""C"": 188, ""D"": 72}"
68
+ Qwen_Qwen3.5-4B,youtube_level3,0.00,836,4,A,0.4677,1.778,1.9927,0.2847,0.2931,"{""A"": 391, ""B"": 132, ""C"": 229, ""D"": 84}"
69
+ Qwen_Qwen3.5-4B,youtube_level3,0.05,836,4,A,0.4426,1.8225,1.9927,0.2847,0.299,"{""A"": 370, ""B"": 147, ""C"": 227, ""D"": 92}"
70
+ Qwen_Qwen3.5-4B,youtube_level3,0.10,836,4,A,0.4474,1.8167,1.9927,0.2847,0.2967,"{""A"": 374, ""B"": 146, ""C"": 225, ""D"": 91}"
71
+ Qwen_Qwen3.5-4B,youtube_level3,0.15,836,4,A,0.4438,1.8283,1.9927,0.2847,0.3038,"{""A"": 371, ""B"": 144, ""C"": 223, ""D"": 98}"
72
+ Qwen_Qwen3.5-4B,youtube_level3,0.20,836,4,A,0.4438,1.8289,1.9927,0.2847,0.2883,"{""A"": 371, ""B"": 143, ""C"": 223, ""D"": 99}"
73
+ Qwen_Qwen3.5-4B,youtube_level3,0.25,836,4,A,0.4486,1.8317,1.9927,0.2847,0.2931,"{""A"": 375, ""B"": 141, ""C"": 215, ""D"": 105}"
74
+ Qwen_Qwen3.5-4B-Base,vsr,0.00,2195,2,true,0.5194,0.9989,0.9958,0.538,0.8319,"{""false"": 1055, ""true"": 1140}"
75
+ Qwen_Qwen3.5-4B-Base,vsr,0.05,2195,2,true,0.5162,0.9992,0.9958,0.538,0.8314,"{""false"": 1062, ""true"": 1133}"
76
+ Qwen_Qwen3.5-4B-Base,vsr,0.10,2195,2,true,0.5125,0.9995,0.9958,0.538,0.8323,"{""false"": 1070, ""true"": 1125}"
77
+ Qwen_Qwen3.5-4B-Base,vsr,0.15,2195,2,true,0.5116,0.9996,0.9958,0.538,0.8278,"{""false"": 1072, ""true"": 1123}"
78
+ Qwen_Qwen3.5-4B-Base,vsr,0.20,2195,2,true,0.5153,0.9993,0.9958,0.538,0.8241,"{""false"": 1064, ""true"": 1131}"
79
+ Qwen_Qwen3.5-4B-Base,vsr,0.25,2195,2,true,0.5075,0.9998,0.9958,0.538,0.8164,"{""false"": 1081, ""true"": 1114}"
80
+ Qwen_Qwen3.5-4B-Base,youtube_level1,0.00,821,4,A,0.3179,1.9803,1.9983,0.2473,0.542,"{""A"": 261, ""B"": 193, ""C"": 167, ""D"": 200}"
81
+ Qwen_Qwen3.5-4B-Base,youtube_level1,0.05,821,4,A,0.3228,1.9769,1.9983,0.2473,0.5457,"{""A"": 265, ""B"": 192, ""C"": 163, ""D"": 201}"
82
+ Qwen_Qwen3.5-4B-Base,youtube_level1,0.10,821,4,A,0.3337,1.971,1.9983,0.2473,0.5603,"{""A"": 274, ""B"": 187, ""C"": 161, ""D"": 199}"
83
+ Qwen_Qwen3.5-4B-Base,youtube_level1,0.15,821,4,A,0.3191,1.9772,1.9983,0.2473,0.5725,"{""A"": 262, ""B"": 190, ""C"": 161, ""D"": 208}"
84
+ Qwen_Qwen3.5-4B-Base,youtube_level1,0.20,821,4,A,0.3228,1.9773,1.9983,0.2473,0.5664,"{""A"": 265, ""B"": 184, ""C"": 167, ""D"": 205}"
85
+ Qwen_Qwen3.5-4B-Base,youtube_level1,0.25,821,4,A,0.3167,1.9769,1.9983,0.2473,0.5554,"{""A"": 260, ""B"": 192, ""C"": 158, ""D"": 211}"
86
+ Qwen_Qwen3.5-4B-Base,youtube_level2,0.00,764,4,A,0.4921,1.8009,1.9962,0.2343,0.4424,"{""A"": 376, ""B"": 112, ""C"": 144, ""D"": 132}"
87
+ Qwen_Qwen3.5-4B-Base,youtube_level2,0.05,764,4,A,0.5065,1.7772,1.9962,0.2343,0.4529,"{""A"": 387, ""B"": 112, ""C"": 146, ""D"": 119}"
88
+ Qwen_Qwen3.5-4B-Base,youtube_level2,0.10,764,4,A,0.5052,1.7811,1.9962,0.2343,0.4503,"{""A"": 386, ""B"": 113, ""C"": 141, ""D"": 124}"
89
+ Qwen_Qwen3.5-4B-Base,youtube_level2,0.15,764,4,A,0.4908,1.803,1.9962,0.2343,0.4542,"{""A"": 375, ""B"": 117, ""C"": 148, ""D"": 124}"
90
+ Qwen_Qwen3.5-4B-Base,youtube_level2,0.20,764,4,A,0.5026,1.7802,1.9962,0.2343,0.4503,"{""A"": 384, ""B"": 113, ""C"": 154, ""D"": 113}"
91
+ Qwen_Qwen3.5-4B-Base,youtube_level2,0.25,764,4,A,0.5262,1.7432,1.9962,0.2343,0.4398,"{""A"": 402, ""B"": 107, ""C"": 143, ""D"": 112}"
92
+ Qwen_Qwen3.5-4B-Base,youtube_level3,0.00,836,4,B,0.3457,1.9035,1.9927,0.2608,0.3026,"{""A"": 212, ""B"": 289, ""C"": 241, ""D"": 94}"
93
+ Qwen_Qwen3.5-4B-Base,youtube_level3,0.05,836,4,B,0.3481,1.8942,1.9927,0.2608,0.2715,"{""A"": 205, ""B"": 291, ""C"": 250, ""D"": 90}"
94
+ Qwen_Qwen3.5-4B-Base,youtube_level3,0.10,836,4,B,0.3301,1.9053,1.9927,0.2608,0.2775,"{""A"": 221, ""B"": 276, ""C"": 247, ""D"": 92}"
95
+ Qwen_Qwen3.5-4B-Base,youtube_level3,0.15,836,4,B,0.3577,1.8933,1.9927,0.2608,0.2667,"{""A"": 212, ""B"": 299, ""C"": 235, ""D"": 90}"
96
+ Qwen_Qwen3.5-4B-Base,youtube_level3,0.20,836,4,B,0.323,1.9153,1.9927,0.2608,0.2727,"{""A"": 225, ""B"": 270, ""C"": 244, ""D"": 97}"
97
+ Qwen_Qwen3.5-4B-Base,youtube_level3,0.25,836,4,B,0.3289,1.9209,1.9927,0.2608,0.2823,"{""A"": 211, ""B"": 275, ""C"": 247, ""D"": 103}"
analysis/dataset_level_analysis/readme.md ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Dataset-level difficulty
2
+
3
+ How hard each split is for each model, once the split's own guessing floor is
4
+ taken out, and whether the models find the same items hard.
5
+
6
+ ```
7
+ dataset_difficulty.ipynb the analysis, 8 figures, executed with outputs
8
+ build_notebook.py regenerates the notebook from source (nbformat)
9
+ analyze_dataset_level.py the same numbers as CSVs, no notebook needed
10
+ figures/*.png every figure, also written by the notebook
11
+ ```
12
+
13
+ Run either entry point from the experiment root:
14
+
15
+ ```bash
16
+ python analysis/dataset_level_analysis/analyze_dataset_level.py # CSVs + terminal tables
17
+ /home/disheng/miniconda3/envs/Spatial_VLM/bin/python \
18
+ analysis/dataset_level_analysis/build_notebook.py # rebuild the .ipynb
19
+ ```
20
+
21
+ ## Why not just compare accuracy
22
+
23
+ The four splits do not share a scale. VSR is a two-way true/false question, so
24
+ guessing scores 0.500; the three Youtube levels are four-way, so guessing scores
25
+ 0.250. Level 2's three distractors are drawn uniformly from the 23 wrong
26
+ orderings, so nothing in the option text helps and its floor is plain chance —
27
+ measured on the split, the strongest text-only heuristic scores 0.252.
28
+
29
+ Everything is therefore reported as **headroom captured**,
30
+ `(acc - floor) / (1 - floor)`: the share of the distance from guessing to
31
+ perfect that the model actually covers. It is negative when a model does worse
32
+ than free.
33
+
34
+ | split | n | choices | guessing | floor used |
35
+ |---|---|---|---|---|
36
+ | VSR | 2195 | 2 | 0.500 | 0.500 |
37
+ | YT level 1 | 821 | 4 | 0.250 | 0.250 |
38
+ | YT level 2 | 764 | 4 | 0.250 | 0.250 |
39
+ | YT level 3 | 836 | 4 | 0.250 | 0.250 |
40
+
41
+ ## Results
42
+
43
+ Accuracy, mean over the six baselines:
44
+
45
+ | model | VSR | YT L1 | YT L2 | YT L3 |
46
+ |---|---|---|---|---|
47
+ | Qwen2.5-VL-3B | 0.759 | 0.405 | 0.374 | 0.255 |
48
+ | Qwen2.5-VL-7B | 0.805 | 0.452 | 0.392 | 0.278 |
49
+ | Qwen3.5-4B | 0.813 | 0.530 | 0.386 | 0.296 |
50
+ | Qwen3.5-4B-Base | 0.827 | 0.557 | 0.448 | 0.279 |
51
+
52
+ Headroom captured:
53
+
54
+ | model | VSR | YT L1 | YT L2 | YT L3 |
55
+ |---|---|---|---|---|
56
+ | Qwen2.5-VL-3B | 0.519 | 0.206 | 0.166 | 0.006 |
57
+ | Qwen2.5-VL-7B | 0.610 | 0.269 | 0.189 | 0.037 |
58
+ | Qwen3.5-4B | 0.627 | 0.373 | 0.181 | 0.061 |
59
+ | Qwen3.5-4B-Base | 0.655 | 0.409 | 0.264 | 0.038 |
60
+
61
+ 1. **All four models now agree on the ordering**: VSR > L1 > L2 > L3, easiest to
62
+ hardest, with Spearman 1.00 for all six model pairs. The earlier split — where
63
+ Qwen2.5-VL found L3 hardest and Qwen3.5 found L2 hardest — was a property of
64
+ the level-3 v1 annotations, and did not survive their rebuild (see the level-3
65
+ caveat below).
66
+ 2. **Only VSR is comfortably solved** (0.52-0.66 of headroom). It is also the
67
+ easiest question type — a binary relation often inferable from object
68
+ identity without metric depth.
69
+ 3. **Level 3 is now at the floor for everyone**: 0.006-0.061 of headroom, a
70
+ 0.054 spread that is the narrowest of the four splits. With each path given
71
+ its own start point the split no longer separates the models; it only shows
72
+ that none of them can trace depth monotonicity along a path.
73
+ 4. **Level 1 is the sharpest discriminator**, 0.206 to 0.409, a 0.203 spread.
74
+ It is the only Youtube level where model strength still shows through.
75
+ 5. **Level 2 sits at 0.17-0.26 for everyone**, a narrow band that tracks neither
76
+ size nor family. Nothing in its option text helps, so this is what four-way
77
+ depth ranking actually costs these models: clearly above guessing, nowhere
78
+ near solved.
79
+ 6. **The base model wins on three splits of four.** Qwen3.5-4B-Base (likelihood
80
+ scoring) beats Qwen3.5-4B (generation) on VSR, L1 and L2, but not on L3
81
+ (0.038 vs 0.061) — where both are close enough to the floor that the ordering
82
+ carries little weight. 4B-Instruct is also the only model producing
83
+ unparsable answers (up to 0.7% on L1), which are scored wrong.
84
+ 7. **The stereo intervention barely moves the aggregate.** Accuracy ranges over
85
+ the six baselines are 0.012-0.036 with no consistent sign. Whether the same
86
+ *items* flip is a separate question — see `../intervention_analysis`.
87
+ 8. **Agreement on item difficulty is highest on L1, lowest on L3.** Excess mass
88
+ at "0 or 4 models correct" over the independent null: +0.358 (L1), +0.267
89
+ (VSR), +0.234 (L2), +0.160 (L3). On L3 the failures are close to independent
90
+ noise, which is what near-chance accuracy looks like.
91
+
92
+ ## Caveat on the level-2 numbers
93
+
94
+ Level 2 was rebuilt three times before this run, because two option
95
+ constructions leaked and one of them also leaked through the letters:
96
+
97
+ | construction | strongest text-only heuristic |
98
+ |---|---|
99
+ | distractors at Kendall distance 1 / 2 / >=3 from the gold | 0.388 (pick the medoid) |
100
+ | all three at the same distance | 0.750 |
101
+ | prefix ladder, distractors assigned to letters in fixed order | 0.759 (run the ladder, avoid D) |
102
+ | prefix ladder, letters shuffled | 0.500 (run the ladder) |
103
+ | **random distractors (current)** | **0.252** |
104
+
105
+ Under the leaking constructions these same models scored 0.40-0.47 on level 2;
106
+ with random distractors they score 0.37-0.45 against a real 0.25 floor. The
107
+ 0.02-0.10 drop is the part of the old score that came from the option text
108
+ rather than the picture. Any level-2 result from before `rerun_l2_v5.log` is
109
+ contaminated and has been deleted.
110
+
111
+ ## Caveat on the level-3 numbers
112
+
113
+ Level 3 was rebuilt on 2026-08-31 (`rerun_l3_v2.log`), and unlike level 2 the
114
+ change was to the task, not to a leak:
115
+
116
+ | version | n | paths | these models scored |
117
+ |---|---|---|---|
118
+ | v1 | 795 | all four start at a shared reference point R | 0.27 - 0.50 |
119
+ | **v2 (current)** | **836** | **each path has its own start point** | **0.26 - 0.30** |
120
+
121
+ Removing the shared start removed whatever local cue the models were reading off
122
+ it, and every model fell to the floor. The v1 runs are kept under
123
+ `result/_archive_l3_v1/`; they are not comparable to anything current.
124
+
125
+ The v2 annotations check out — all 836 gold paths are monotone (`worst_step` >=
126
+ 0), every distractor violates monotonicity (worst is -0.0007), and the median
127
+ margin between the gold and the strongest distractor is 0.069 — so the collapse
128
+ is difficulty, not a broken split. A little signal survives: accuracy over
129
+ quartiles of that margin rises by +0.088 (7B), +0.083 (3.5-4B) and +0.044
130
+ (Base), reaching 0.30-0.345 on the most separable quarter. Only 2.5-VL-3B is
131
+ flat (-0.005), i.e. reading nothing at all. Both subtypes are hard, with
132
+ `near_to_far` (0.280-0.334) consistently easier than `far_to_near`
133
+ (0.233-0.264).
analysis/dataset_level_analysis/summary_by_model_task.csv ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ model,task,n,scoring,chance,floor,acc_b0,acc_mean,acc_min,acc_max,acc_range,acc_std,slope_per_baseline,delta_b025_minus_b0,headroom_captured_mean,above_floor
2
+ Qwen_Qwen2.5-VL-3B-Instruct,vsr,2195,generate,0.5,0.5,0.7713,0.7595,0.7481,0.7713,0.0232,0.008,-0.0929,-0.0232,0.5191,True
3
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level1,821,generate,0.25,0.25,0.3995,0.4046,0.3995,0.4117,0.0122,0.005,-0.0077,0.0012,0.2061,True
4
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level2,764,generate,0.25,0.25,0.3626,0.3743,0.3626,0.3809,0.0183,0.0063,0.0344,0.0079,0.1658,True
5
+ Qwen_Qwen2.5-VL-3B-Instruct,youtube_level3,836,generate,0.25,0.25,0.2667,0.2548,0.2392,0.2667,0.0275,0.0102,0.0287,-0.0012,0.0064,True
6
+ Qwen_Qwen2.5-VL-7B-Instruct,vsr,2195,generate,0.5,0.5,0.8223,0.805,0.7882,0.8223,0.0342,0.0101,-0.1047,-0.0342,0.61,True
7
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level1,821,generate,0.25,0.25,0.447,0.4519,0.4421,0.4665,0.0244,0.0077,0.0097,0.0049,0.2692,True
8
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level2,764,generate,0.25,0.25,0.4031,0.3918,0.377,0.4031,0.0262,0.0109,-0.1017,-0.0262,0.1891,True
9
+ Qwen_Qwen2.5-VL-7B-Instruct,youtube_level3,836,generate,0.25,0.25,0.2799,0.2779,0.2679,0.2871,0.0191,0.0061,-0.0273,-0.006,0.0372,True
10
+ Qwen_Qwen3.5-4B,vsr,2195,generate,0.5,0.5,0.8214,0.8134,0.8046,0.8214,0.0169,0.0062,-0.0695,-0.0169,0.6269,True
11
+ Qwen_Qwen3.5-4B,youtube_level1,821,generate,0.25,0.25,0.5274,0.5296,0.5189,0.5408,0.0219,0.0078,0.0564,0.0073,0.3729,True
12
+ Qwen_Qwen3.5-4B,youtube_level2,764,generate,0.25,0.25,0.3914,0.3859,0.3796,0.3914,0.0118,0.0042,-0.0337,-0.0065,0.1812,True
13
+ Qwen_Qwen3.5-4B,youtube_level3,836,generate,0.25,0.25,0.2931,0.2957,0.2883,0.3038,0.0156,0.005,-0.0144,0.0,0.0609,True
14
+ Qwen_Qwen3.5-4B-Base,vsr,2195,likelihood,0.5,0.5,0.8319,0.8273,0.8164,0.8323,0.0159,0.0057,-0.0594,-0.0155,0.6547,True
15
+ Qwen_Qwen3.5-4B-Base,youtube_level1,821,likelihood,0.25,0.25,0.542,0.557,0.542,0.5725,0.0305,0.0107,0.0807,0.0134,0.4094,True
16
+ Qwen_Qwen3.5-4B-Base,youtube_level2,764,likelihood,0.25,0.25,0.4424,0.4483,0.4398,0.4542,0.0144,0.0053,-0.0097,-0.0026,0.2644,True
17
+ Qwen_Qwen3.5-4B-Base,youtube_level3,836,likelihood,0.25,0.25,0.3026,0.2789,0.2667,0.3026,0.0359,0.0117,-0.0622,-0.0203,0.0385,True
analysis/intervention_analysis/Qwen_Qwen2.5-VL-3B-Instruct__vsr_failure_overlap.csv ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ baseline_a,baseline_b,failures_a,failures_b,failures_shared,failure_jaccard,failure_recall_a_in_b,successes_a,successes_b,successes_shared,success_jaccard,answer_agreement
2
+ 0.00,0.05,502,510,429,0.7358490566037735,0.8545816733067729,1693,1685,1612,0.912797281993205,0.9298405466970388
3
+ 0.00,0.10,502,528,428,0.7109634551495017,0.852589641434263,1693,1667,1593,0.9015280135823429,0.9207289293849659
4
+ 0.00,0.15,502,531,420,0.6851549755301795,0.8366533864541833,1693,1664,1582,0.8912676056338028,0.9120728929384966
5
+ 0.00,0.20,502,543,413,0.6534810126582279,0.8227091633466136,1693,1652,1563,0.877104377104377,0.9002277904328019
6
+ 0.00,0.25,502,553,408,0.6306027820710973,0.8127490039840638,1693,1642,1548,0.8662562954672636,0.8911161731207289
7
+ 0.05,0.10,510,528,433,0.715702479338843,0.8490196078431372,1685,1667,1590,0.9023836549375709,0.9216400911161731
8
+ 0.05,0.15,510,531,434,0.71499176276771,0.8509803921568627,1685,1664,1588,0.9017603634298694,0.9211845102505695
9
+ 0.05,0.20,510,543,429,0.6875,0.8411764705882353,1685,1652,1571,0.8895809739524349,0.9111617312072893
10
+ 0.05,0.25,510,553,423,0.6609375,0.8294117647058824,1685,1642,1555,0.8775395033860045,0.9011389521640091
11
+ 0.10,0.15,528,531,445,0.7247557003257329,0.8428030303030303,1667,1664,1581,0.9034285714285715,0.9230068337129841
12
+ 0.10,0.20,528,543,441,0.7,0.8352272727272727,1667,1652,1565,0.8922462941847207,0.9138952164009112
13
+ 0.10,0.25,528,553,430,0.6605222734254992,0.8143939393939394,1667,1642,1544,0.8747875354107649,0.8993166287015946
14
+ 0.15,0.20,531,543,447,0.7129186602870813,0.8418079096045198,1664,1652,1568,0.897025171624714,0.9179954441913439
15
+ 0.15,0.25,531,553,445,0.6964006259780907,0.8380414312617702,1664,1642,1556,0.8891428571428571,0.911617312072893
16
+ 0.20,0.25,543,553,460,0.7232704402515723,0.8471454880294659,1652,1642,1559,0.8985590778097983,0.9198177676537586
analysis/intervention_analysis/Qwen_Qwen2.5-VL-3B-Instruct__vsr_per_sample.csv ADDED
The diff for this file is too large to render. See raw diff
 
analysis/intervention_analysis/Qwen_Qwen2.5-VL-3B-Instruct__youtube_level1_failure_overlap.csv ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ baseline_a,baseline_b,failures_a,failures_b,failures_shared,failure_jaccard,failure_recall_a_in_b,successes_a,successes_b,successes_shared,success_jaccard,answer_agreement
2
+ 0.00,0.05,493,488,450,0.847457627118644,0.9127789046653144,328,333,290,0.7816711590296496,0.8514007308160779
3
+ 0.00,0.10,493,483,451,0.8590476190476191,0.9148073022312373,328,338,296,0.8,0.8440925700365408
4
+ 0.00,0.15,493,484,450,0.8538899430740038,0.9127789046653144,328,337,294,0.7924528301886793,0.8367844092570037
5
+ 0.00,0.20,493,493,445,0.822550831792976,0.9026369168356998,328,328,280,0.7446808510638298,0.8185140073081608
6
+ 0.00,0.25,493,492,441,0.8106617647058824,0.8945233265720081,328,329,277,0.7289473684210527,0.8063337393422655
7
+ 0.05,0.10,488,483,449,0.8601532567049809,0.9200819672131147,333,338,299,0.803763440860215,0.8440925700365408
8
+ 0.05,0.15,488,484,447,0.8514285714285714,0.9159836065573771,333,337,296,0.7914438502673797,0.8392204628501827
9
+ 0.05,0.20,488,493,454,0.8614800759013282,0.930327868852459,333,328,294,0.8010899182561307,0.833130328867235
10
+ 0.05,0.25,488,492,442,0.8215613382899628,0.9057377049180327,333,329,283,0.7467018469656992,0.8063337393422655
11
+ 0.10,0.15,483,484,446,0.8560460652591171,0.9233954451345756,338,337,300,0.8,0.8453105968331304
12
+ 0.10,0.20,483,493,450,0.8555133079847909,0.9316770186335404,338,328,295,0.7951482479784366,0.8550548112058465
13
+ 0.10,0.25,483,492,445,0.839622641509434,0.9213250517598344,338,329,291,0.773936170212766,0.8270401948842875
14
+ 0.15,0.20,484,493,452,0.8609523809523809,0.9338842975206612,337,328,296,0.8021680216802168,0.8514007308160779
15
+ 0.15,0.25,484,492,441,0.8242990654205608,0.9111570247933884,337,329,286,0.7526315789473684,0.8136419001218027
16
+ 0.20,0.25,493,492,459,0.8726235741444867,0.9310344827586207,328,329,295,0.8149171270718232,0.8660170523751523
analysis/intervention_analysis/Qwen_Qwen2.5-VL-3B-Instruct__youtube_level1_per_sample.csv ADDED
The diff for this file is too large to render. See raw diff
 
analysis/intervention_analysis/Qwen_Qwen2.5-VL-3B-Instruct__youtube_level2_failure_overlap.csv ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ baseline_a,baseline_b,failures_a,failures_b,failures_shared,failure_jaccard,failure_recall_a_in_b,successes_a,successes_b,successes_shared,success_jaccard,answer_agreement
2
+ 0.00,0.05,487,478,450,0.8737864077669902,0.9240246406570842,277,286,249,0.7929936305732485,0.8612565445026178
3
+ 0.00,0.10,487,475,441,0.8464491362763915,0.9055441478439425,277,289,243,0.7523219814241486,0.8272251308900523
4
+ 0.00,0.15,487,474,437,0.833969465648855,0.8973305954825462,277,290,240,0.7339449541284404,0.8206806282722513
5
+ 0.00,0.20,487,473,437,0.8355640535372849,0.8973305954825462,277,291,241,0.7370030581039755,0.8259162303664922
6
+ 0.00,0.25,487,481,435,0.8161350844277674,0.893223819301848,277,283,231,0.7021276595744681,0.7892670157068062
7
+ 0.05,0.10,478,475,444,0.8722986247544204,0.9288702928870293,286,289,255,0.796875,0.8547120418848168
8
+ 0.05,0.15,478,474,438,0.8521400778210116,0.9163179916317992,286,290,250,0.7668711656441718,0.8416230366492147
9
+ 0.05,0.20,478,473,441,0.8647058823529412,0.9225941422594143,286,291,254,0.7863777089783281,0.8586387434554974
10
+ 0.05,0.25,478,481,435,0.8301526717557252,0.9100418410041841,286,283,240,0.729483282674772,0.8141361256544503
11
+ 0.10,0.15,475,474,436,0.8499025341130604,0.9178947368421052,289,290,251,0.7652439024390244,0.8390052356020943
12
+ 0.10,0.20,475,473,435,0.847953216374269,0.9157894736842105,289,291,251,0.7629179331306991,0.8390052356020943
13
+ 0.10,0.25,475,481,436,0.8384615384615385,0.9178947368421052,289,283,244,0.7439024390243902,0.8180628272251309
14
+ 0.15,0.20,474,473,436,0.8532289628180039,0.919831223628692,290,291,253,0.7713414634146342,0.8534031413612565
15
+ 0.15,0.25,474,481,438,0.8471953578336557,0.9240506329113924,290,283,247,0.7576687116564417,0.837696335078534
16
+ 0.20,0.25,473,481,439,0.8524271844660194,0.9281183932346723,291,283,249,0.7661538461538462,0.8298429319371727
analysis/intervention_analysis/Qwen_Qwen2.5-VL-3B-Instruct__youtube_level2_per_sample.csv ADDED
The diff for this file is too large to render. See raw diff
 
analysis/intervention_analysis/Qwen_Qwen2.5-VL-3B-Instruct__youtube_level3_failure_overlap.csv ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ baseline_a,baseline_b,failures_a,failures_b,failures_shared,failure_jaccard,failure_recall_a_in_b,successes_a,successes_b,successes_shared,success_jaccard,answer_agreement
2
+ 0.00,0.05,613,631,569,0.8429629629629629,0.9282218597063622,223,205,161,0.602996254681648,0.7547846889952153
3
+ 0.00,0.10,613,636,570,0.8394698085419735,0.9298531810766721,223,200,157,0.5902255639097744,0.7619617224880383
4
+ 0.00,0.15,613,625,562,0.8313609467455622,0.9168026101141925,223,211,160,0.583941605839416,0.7356459330143541
5
+ 0.00,0.20,613,619,561,0.8360655737704918,0.9151712887438825,223,217,165,0.6,0.7452153110047847
6
+ 0.00,0.25,613,614,551,0.8150887573964497,0.8988580750407831,223,222,160,0.5614035087719298,0.7260765550239234
7
+ 0.05,0.10,631,636,588,0.865979381443299,0.9318541996830428,205,200,157,0.6330645161290323,0.7811004784688995
8
+ 0.05,0.15,631,625,580,0.8579881656804734,0.919175911251981,205,211,160,0.625,0.7667464114832536
9
+ 0.05,0.20,631,619,571,0.8409425625920471,0.9049128367670365,205,217,157,0.5924528301886792,0.7667464114832536
10
+ 0.05,0.25,631,614,569,0.841715976331361,0.901743264659271,205,222,160,0.599250936329588,0.7464114832535885
11
+ 0.10,0.15,636,625,582,0.8571428571428571,0.9150943396226415,200,211,157,0.6181102362204725,0.7739234449760766
12
+ 0.10,0.20,636,619,582,0.8647845468053492,0.9150943396226415,200,217,163,0.6417322834645669,0.7918660287081339
13
+ 0.10,0.25,636,614,578,0.8601190476190477,0.9088050314465409,200,222,164,0.6356589147286822,0.7715311004784688
14
+ 0.15,0.20,625,619,574,0.8567164179104477,0.9184,211,217,166,0.6335877862595419,0.7799043062200957
15
+ 0.15,0.25,625,614,573,0.8603603603603603,0.9168,211,222,170,0.6463878326996197,0.7811004784688995
16
+ 0.20,0.25,619,614,578,0.8824427480916031,0.9337641357027464,217,222,181,0.7015503875968992,0.8014354066985646
analysis/intervention_analysis/Qwen_Qwen2.5-VL-3B-Instruct__youtube_level3_per_sample.csv ADDED
The diff for this file is too large to render. See raw diff
 
analysis/intervention_analysis/Qwen_Qwen2.5-VL-7B-Instruct__vsr_failure_overlap.csv ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ baseline_a,baseline_b,failures_a,failures_b,failures_shared,failure_jaccard,failure_recall_a_in_b,successes_a,successes_b,successes_shared,success_jaccard,answer_agreement
2
+ 0.00,0.05,390,422,340,0.7203389830508474,0.8717948717948718,1805,1773,1723,0.9288409703504044,0.939863325740319
3
+ 0.00,0.10,390,433,331,0.6727642276422764,0.8487179487179487,1805,1762,1703,0.9136266094420601,0.9266514806378132
4
+ 0.00,0.15,390,424,335,0.6993736951983298,0.8589743589743589,1805,1771,1716,0.9225806451612903,0.9343963553530752
5
+ 0.00,0.20,390,434,323,0.6447105788423154,0.8282051282051283,1805,1761,1694,0.9049145299145299,0.9189066059225512
6
+ 0.00,0.25,390,465,325,0.6132075471698113,0.8333333333333334,1805,1730,1665,0.8903743315508021,0.9066059225512528
7
+ 0.05,0.10,422,433,362,0.7342799188640974,0.8578199052132701,1773,1762,1702,0.928532460447354,0.9403189066059225
8
+ 0.05,0.15,422,424,355,0.7230142566191446,0.8412322274881516,1773,1771,1704,0.9260869565217391,0.9380410022779043
9
+ 0.05,0.20,422,434,345,0.675146771037182,0.8175355450236966,1773,1761,1684,0.9102702702702703,0.924373576309795
10
+ 0.05,0.25,422,465,348,0.6456400742115028,0.8246445497630331,1773,1730,1656,0.8965890633459664,0.9129840546697039
11
+ 0.10,0.15,433,424,359,0.7208835341365462,0.8290993071593533,1762,1771,1697,0.9242919389978214,0.9366742596810934
12
+ 0.10,0.20,433,434,357,0.7,0.8244803695150116,1762,1761,1685,0.9167573449401524,0.9302961275626423
13
+ 0.10,0.25,433,465,360,0.6691449814126395,0.8314087759815243,1762,1730,1657,0.9029972752043597,0.9189066059225512
14
+ 0.15,0.20,424,434,361,0.7263581488933601,0.8514150943396226,1771,1761,1698,0.925845147219193,0.9380410022779043
15
+ 0.15,0.25,424,465,363,0.6901140684410646,0.8561320754716981,1771,1730,1669,0.9110262008733624,0.9257403189066059
16
+ 0.20,0.25,434,465,376,0.7189292543021033,0.8663594470046083,1761,1730,1672,0.9191863661352392,0.9330296127562643
analysis/intervention_analysis/Qwen_Qwen2.5-VL-7B-Instruct__vsr_per_sample.csv ADDED
The diff for this file is too large to render. See raw diff
 
analysis/intervention_analysis/Qwen_Qwen2.5-VL-7B-Instruct__youtube_level1_failure_overlap.csv ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ baseline_a,baseline_b,failures_a,failures_b,failures_shared,failure_jaccard,failure_recall_a_in_b,successes_a,successes_b,successes_shared,success_jaccard,answer_agreement
2
+ 0.00,0.05,454,453,417,0.8510204081632653,0.9185022026431718,367,368,331,0.8193069306930693,0.8781973203410475
3
+ 0.00,0.10,454,447,413,0.8463114754098361,0.9096916299559471,367,374,333,0.8161764705882353,0.853836784409257
4
+ 0.00,0.15,454,438,405,0.8316221765913757,0.8920704845814978,367,383,334,0.8028846153846154,0.8501827040194885
5
+ 0.00,0.20,454,458,409,0.8131212723658051,0.9008810572687225,367,363,318,0.7718446601941747,0.8270401948842875
6
+ 0.00,0.25,454,450,394,0.7725490196078432,0.8678414096916299,367,371,311,0.7283372365339579,0.7978075517661388
7
+ 0.05,0.10,453,447,419,0.8711018711018711,0.9249448123620309,368,374,340,0.845771144278607,0.8830694275274056
8
+ 0.05,0.15,453,438,412,0.860125260960334,0.9094922737306843,368,383,342,0.8361858190709046,0.8842874543239951
9
+ 0.05,0.20,453,458,416,0.8404040404040404,0.9183222958057395,368,363,326,0.8049382716049382,0.8623629719853837
10
+ 0.05,0.25,453,450,408,0.8242424242424242,0.9006622516556292,368,371,326,0.7893462469733656,0.8428745432399513
11
+ 0.10,0.15,447,438,414,0.8789808917197452,0.9261744966442953,374,383,350,0.85995085995086,0.8842874543239951
12
+ 0.10,0.20,447,458,420,0.865979381443299,0.9395973154362416,374,363,336,0.8379052369077307,0.8721071863580999
13
+ 0.10,0.25,447,450,411,0.845679012345679,0.9194630872483222,374,371,335,0.8170731707317073,0.8501827040194885
14
+ 0.15,0.20,438,458,416,0.8666666666666667,0.9497716894977168,383,363,341,0.8419753086419753,0.8952496954933008
15
+ 0.15,0.25,438,450,406,0.8423236514522822,0.9269406392694064,383,371,339,0.8168674698795181,0.8611449451887941
16
+ 0.20,0.25,458,450,423,0.8721649484536083,0.9235807860262009,363,371,336,0.8442211055276382,0.879415347137637
analysis/intervention_analysis/Qwen_Qwen2.5-VL-7B-Instruct__youtube_level1_per_sample.csv ADDED
The diff for this file is too large to render. See raw diff
 
analysis/intervention_analysis/Qwen_Qwen2.5-VL-7B-Instruct__youtube_level2_failure_overlap.csv ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ baseline_a,baseline_b,failures_a,failures_b,failures_shared,failure_jaccard,failure_recall_a_in_b,successes_a,successes_b,successes_shared,success_jaccard,answer_agreement
2
+ 0.00,0.05,456,463,429,0.8755102040816326,0.9407894736842105,308,301,274,0.817910447761194,0.856020942408377
3
+ 0.00,0.10,456,460,428,0.8770491803278688,0.9385964912280702,308,304,276,0.8214285714285714,0.8678010471204188
4
+ 0.00,0.15,456,457,415,0.8333333333333334,0.9100877192982456,308,307,266,0.7621776504297995,0.8272251308900523
5
+ 0.00,0.20,456,476,421,0.8238747553816047,0.9232456140350878,308,288,253,0.7376093294460642,0.8102094240837696
6
+ 0.00,0.25,456,476,418,0.8132295719844358,0.9166666666666666,308,288,250,0.7225433526011561,0.7997382198952879
7
+ 0.05,0.10,463,460,436,0.8952772073921971,0.9416846652267818,301,304,277,0.8445121951219512,0.8835078534031413
8
+ 0.05,0.15,463,457,423,0.8511066398390342,0.9136069114470843,301,307,267,0.782991202346041,0.8481675392670157
9
+ 0.05,0.20,463,476,439,0.878,0.9481641468682506,301,288,264,0.8123076923076923,0.8586387434554974
10
+ 0.05,0.25,463,476,433,0.8557312252964426,0.9352051835853131,301,288,258,0.7794561933534743,0.849476439790576
11
+ 0.10,0.15,460,457,426,0.8676171079429735,0.9260869565217391,304,307,273,0.8076923076923077,0.8691099476439791
12
+ 0.10,0.20,460,476,439,0.8832997987927566,0.9543478260869566,304,288,267,0.8215384615384616,0.8717277486910995
13
+ 0.10,0.25,460,476,434,0.8645418326693227,0.9434782608695652,304,288,262,0.793939393939394,0.8455497382198953
14
+ 0.15,0.20,457,476,430,0.8548707753479126,0.9409190371991247,307,288,261,0.781437125748503,0.8638743455497382
15
+ 0.15,0.25,457,476,427,0.8438735177865613,0.9343544857768052,307,288,258,0.7655786350148368,0.8337696335078534
16
+ 0.20,0.25,476,476,451,0.9001996007984032,0.9474789915966386,288,288,263,0.8402555910543131,0.8887434554973822
analysis/intervention_analysis/Qwen_Qwen2.5-VL-7B-Instruct__youtube_level2_per_sample.csv ADDED
The diff for this file is too large to render. See raw diff
 
analysis/intervention_analysis/Qwen_Qwen2.5-VL-7B-Instruct__youtube_level3_failure_overlap.csv ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ baseline_a,baseline_b,failures_a,failures_b,failures_shared,failure_jaccard,failure_recall_a_in_b,successes_a,successes_b,successes_shared,success_jaccard,answer_agreement
2
+ 0.00,0.05,602,596,555,0.8631415241057543,0.9219269102990033,234,240,193,0.6868327402135231,0.8026315789473685
3
+ 0.00,0.10,602,612,567,0.8763523956723338,0.9418604651162791,234,224,189,0.7026022304832714,0.7954545454545454
4
+ 0.00,0.15,602,600,556,0.8606811145510835,0.9235880398671097,234,236,190,0.6785714285714286,0.7715311004784688
5
+ 0.00,0.20,602,605,551,0.8399390243902439,0.915282392026578,234,231,180,0.631578947368421,0.7547846889952153
6
+ 0.00,0.25,602,607,556,0.8514548238897397,0.9235880398671097,234,229,183,0.6535714285714286,0.7679425837320574
7
+ 0.05,0.10,596,612,561,0.8670788253477589,0.9412751677852349,240,224,189,0.6872727272727273,0.8205741626794258
8
+ 0.05,0.15,596,600,559,0.8775510204081632,0.9379194630872483,240,236,199,0.7184115523465704,0.8098086124401914
9
+ 0.05,0.20,596,605,554,0.8562596599690881,0.9295302013422819,240,231,189,0.6702127659574468,0.7954545454545454
10
+ 0.05,0.25,596,607,552,0.847926267281106,0.9261744966442953,240,229,185,0.6514084507042254,0.7715311004784688
11
+ 0.10,0.15,612,600,565,0.8732612055641422,0.923202614379085,224,236,189,0.6974169741697417,0.8169856459330144
12
+ 0.10,0.20,612,605,566,0.869431643625192,0.9248366013071896,224,231,185,0.6851851851851852,0.8169856459330144
13
+ 0.10,0.25,612,607,566,0.8667687595712098,0.9248366013071896,224,229,183,0.6777777777777778,0.8002392344497608
14
+ 0.15,0.20,600,605,565,0.8828125,0.9416666666666667,236,231,196,0.7232472324723247,0.8217703349282297
15
+ 0.15,0.25,600,607,560,0.865533230293663,0.9333333333333333,236,229,189,0.6847826086956522,0.7942583732057417
16
+ 0.20,0.25,605,607,564,0.8703703703703703,0.9322314049586777,231,229,188,0.6911764705882353,0.8014354066985646
analysis/intervention_analysis/Qwen_Qwen2.5-VL-7B-Instruct__youtube_level3_per_sample.csv ADDED
The diff for this file is too large to render. See raw diff
 
analysis/intervention_analysis/Qwen_Qwen3.5-4B-Base__vsr_failure_overlap.csv ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ baseline_a,baseline_b,failures_a,failures_b,failures_shared,failure_jaccard,failure_recall_a_in_b,successes_a,successes_b,successes_shared,success_jaccard,answer_agreement
2
+ 0.00,0.05,369,370,319,0.7595238095238095,0.8644986449864499,1826,1825,1775,0.9461620469083155,0.9539863325740319
3
+ 0.00,0.10,369,368,310,0.7259953161592506,0.8401084010840109,1826,1827,1768,0.9379310344827586,0.9466970387243736
4
+ 0.00,0.15,369,378,308,0.7015945330296127,0.8346883468834688,1826,1817,1756,0.9305776364599894,0.9403189066059225
5
+ 0.00,0.20,369,386,291,0.6271551724137931,0.7886178861788617,1826,1809,1731,0.9091386554621849,0.9211845102505695
6
+ 0.00,0.25,369,403,292,0.6083333333333333,0.7913279132791328,1826,1792,1715,0.9012086179716238,0.9143507972665148
7
+ 0.05,0.10,370,368,319,0.7613365155131265,0.8621621621621621,1825,1827,1776,0.9466950959488273,0.9544419134396356
8
+ 0.05,0.15,370,378,310,0.7077625570776256,0.8378378378378378,1825,1817,1757,0.9320954907161804,0.9416856492027335
9
+ 0.05,0.20,370,386,302,0.6651982378854625,0.8162162162162162,1825,1809,1741,0.9197041732699419,0.9307517084282461
10
+ 0.05,0.25,370,403,298,0.6273684210526316,0.8054054054054054,1825,1792,1720,0.9066947812335266,0.9193621867881548
11
+ 0.10,0.15,368,378,310,0.7110091743119266,0.842391304347826,1827,1817,1759,0.9331564986737401,0.9425968109339408
12
+ 0.10,0.20,368,386,316,0.7214611872146118,0.8586956521739131,1827,1809,1757,0.9350718467269824,0.9444191343963554
13
+ 0.10,0.25,368,403,310,0.6724511930585684,0.842391304347826,1827,1792,1734,0.919893899204244,0.9312072892938497
14
+ 0.15,0.20,378,386,323,0.7324263038548753,0.8544973544973545,1817,1809,1754,0.936965811965812,0.9462414578587699
15
+ 0.15,0.25,378,403,325,0.7127192982456141,0.8597883597883598,1817,1792,1739,0.9299465240641711,0.9403189066059225
16
+ 0.20,0.25,386,403,336,0.7417218543046358,0.8704663212435233,1809,1792,1742,0.9370629370629371,0.9466970387243736
analysis/intervention_analysis/Qwen_Qwen3.5-4B-Base__vsr_per_sample.csv ADDED
The diff for this file is too large to render. See raw diff
 
analysis/intervention_analysis/Qwen_Qwen3.5-4B-Base__youtube_level1_failure_overlap.csv ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ baseline_a,baseline_b,failures_a,failures_b,failures_shared,failure_jaccard,failure_recall_a_in_b,successes_a,successes_b,successes_shared,success_jaccard,answer_agreement
2
+ 0.00,0.05,376,373,341,0.8357843137254902,0.9069148936170213,445,448,413,0.8604166666666667,0.8915956151035322
3
+ 0.00,0.10,376,361,332,0.8197530864197531,0.8829787234042553,445,460,416,0.8507157464212679,0.8830694275274056
4
+ 0.00,0.15,376,351,322,0.7950617283950617,0.8563829787234043,445,470,416,0.8336673346693386,0.8672350791717418
5
+ 0.00,0.20,376,356,319,0.7723970944309927,0.848404255319149,445,465,408,0.8127490039840638,0.8501827040194885
6
+ 0.00,0.25,376,365,320,0.7600950118764845,0.851063829787234,445,456,400,0.7984031936127745,0.8428745432399513
7
+ 0.05,0.10,373,361,338,0.8535353535353535,0.9061662198391421,448,460,425,0.8799171842650103,0.9037758830694276
8
+ 0.05,0.15,373,351,321,0.7965260545905707,0.8605898123324397,448,470,418,0.836,0.8672350791717418
9
+ 0.05,0.20,373,356,318,0.7737226277372263,0.8525469168900804,448,465,410,0.8151093439363817,0.8489646772228989
10
+ 0.05,0.25,373,365,319,0.7613365155131265,0.8552278820375335,448,456,402,0.8007968127490039,0.8453105968331304
11
+ 0.10,0.15,361,351,318,0.8071065989847716,0.8808864265927978,460,470,427,0.8489065606361829,0.876979293544458
12
+ 0.10,0.20,361,356,325,0.8290816326530612,0.9002770083102493,460,465,429,0.8649193548387096,0.8855054811205847
13
+ 0.10,0.25,361,365,318,0.7794117647058824,0.8808864265927978,460,456,413,0.8210735586481114,0.8587088915956151
14
+ 0.15,0.20,351,356,320,0.8268733850129198,0.9116809116809117,470,465,434,0.8662674650698603,0.8842874543239951
15
+ 0.15,0.25,351,365,325,0.8312020460358056,0.9259259259259259,470,456,430,0.8669354838709677,0.8964677222898904
16
+ 0.20,0.25,356,365,324,0.8161209068010076,0.9101123595505618,465,456,424,0.8531187122736419,0.8891595615103532
analysis/intervention_analysis/Qwen_Qwen3.5-4B-Base__youtube_level1_per_sample.csv ADDED
The diff for this file is too large to render. See raw diff
 
analysis/intervention_analysis/Qwen_Qwen3.5-4B-Base__youtube_level2_failure_overlap.csv ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ baseline_a,baseline_b,failures_a,failures_b,failures_shared,failure_jaccard,failure_recall_a_in_b,successes_a,successes_b,successes_shared,success_jaccard,answer_agreement
2
+ 0.00,0.05,426,418,389,0.8549450549450549,0.9131455399061033,338,346,309,0.824,0.8691099476439791
3
+ 0.00,0.10,426,420,388,0.8471615720524017,0.9107981220657277,338,344,306,0.8138297872340425,0.862565445026178
4
+ 0.00,0.15,426,417,384,0.8366013071895425,0.9014084507042254,338,347,305,0.8026315789473685,0.8520942408376964
5
+ 0.00,0.20,426,420,382,0.8232758620689655,0.8967136150234741,338,344,300,0.7853403141361257,0.8219895287958116
6
+ 0.00,0.25,426,428,381,0.8054968287526427,0.8943661971830986,338,336,291,0.7597911227154047,0.8115183246073299
7
+ 0.05,0.10,418,420,388,0.8622222222222222,0.9282296650717703,346,344,314,0.8351063829787234,0.8808900523560209
8
+ 0.05,0.15,418,417,390,0.8764044943820225,0.9330143540669856,346,347,319,0.8529411764705882,0.8795811518324608
9
+ 0.05,0.20,418,420,384,0.8458149779735683,0.9186602870813397,346,344,310,0.8157894736842105,0.8416230366492147
10
+ 0.05,0.25,418,428,383,0.8272138228941684,0.916267942583732,346,336,301,0.7900262467191601,0.8350785340314136
11
+ 0.10,0.15,420,417,397,0.9022727272727272,0.9452380952380952,344,347,324,0.8828337874659401,0.9070680628272252
12
+ 0.10,0.20,420,420,391,0.8708240534521158,0.930952380952381,344,344,315,0.8445040214477212,0.8638743455497382
13
+ 0.10,0.25,420,428,386,0.8354978354978355,0.919047619047619,344,336,302,0.798941798941799,0.8520942408376964
14
+ 0.15,0.20,417,420,393,0.8851351351351351,0.9424460431654677,347,344,320,0.862533692722372,0.8808900523560209
15
+ 0.15,0.25,417,428,391,0.8612334801762115,0.9376498800959233,347,336,310,0.8310991957104558,0.8730366492146597
16
+ 0.20,0.25,420,428,395,0.8719646799116998,0.9404761904761905,344,336,311,0.8428184281842819,0.8848167539267016
analysis/intervention_analysis/Qwen_Qwen3.5-4B-Base__youtube_level2_per_sample.csv ADDED
The diff for this file is too large to render. See raw diff
 
analysis/intervention_analysis/Qwen_Qwen3.5-4B-Base__youtube_level3_failure_overlap.csv ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ baseline_a,baseline_b,failures_a,failures_b,failures_shared,failure_jaccard,failure_recall_a_in_b,successes_a,successes_b,successes_shared,success_jaccard,answer_agreement
2
+ 0.00,0.05,583,609,545,0.8423493044822257,0.934819897084048,253,227,189,0.6494845360824743,0.7523923444976076
3
+ 0.00,0.10,583,604,541,0.8374613003095975,0.9279588336192109,253,232,190,0.6440677966101694,0.7547846889952153
4
+ 0.00,0.15,583,613,542,0.8287461773700305,0.9296740994854202,253,223,182,0.6190476190476191,0.7344497607655502
5
+ 0.00,0.20,583,608,534,0.8127853881278538,0.9159519725557461,253,228,179,0.5927152317880795,0.7236842105263158
6
+ 0.00,0.25,583,600,528,0.8061068702290076,0.9056603773584906,253,236,181,0.5876623376623377,0.715311004784689
7
+ 0.05,0.10,609,604,563,0.8661538461538462,0.9244663382594417,227,232,186,0.6813186813186813,0.7906698564593302
8
+ 0.05,0.15,609,613,567,0.8656488549618321,0.9310344827586207,227,223,181,0.6728624535315985,0.7727272727272727
9
+ 0.05,0.20,609,608,562,0.8580152671755725,0.922824302134647,227,228,181,0.6605839416058394,0.7691387559808612
10
+ 0.05,0.25,609,600,550,0.834597875569044,0.90311986863711,227,236,177,0.6188811188811189,0.7559808612440191
11
+ 0.10,0.15,604,613,569,0.8780864197530864,0.9420529801324503,232,223,188,0.704119850187266,0.819377990430622
12
+ 0.10,0.20,604,608,566,0.8761609907120743,0.9370860927152318,232,228,190,0.7037037037037037,0.8038277511961722
13
+ 0.10,0.25,604,600,560,0.8695652173913043,0.9271523178807947,232,236,192,0.6956521739130435,0.7954545454545454
14
+ 0.15,0.20,613,608,570,0.8755760368663594,0.9298531810766721,223,228,185,0.6954887218045113,0.8098086124401914
15
+ 0.15,0.25,613,600,563,0.8661538461538462,0.9184339314845025,223,236,186,0.6813186813186813,0.7894736842105263
16
+ 0.20,0.25,608,600,560,0.8641975308641975,0.9210526315789473,228,236,188,0.6811594202898551,0.7978468899521531
analysis/intervention_analysis/Qwen_Qwen3.5-4B-Base__youtube_level3_per_sample.csv ADDED
The diff for this file is too large to render. See raw diff
 
analysis/intervention_analysis/Qwen_Qwen3.5-4B__vsr_failure_overlap.csv ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ baseline_a,baseline_b,failures_a,failures_b,failures_shared,failure_jaccard,failure_recall_a_in_b,successes_a,successes_b,successes_shared,success_jaccard,answer_agreement
2
+ 0.00,0.05,392,401,347,0.7780269058295964,0.8852040816326531,1803,1794,1749,0.9464285714285714,0.9548974943052392
3
+ 0.00,0.10,392,398,343,0.767337807606264,0.875,1803,1797,1748,0.9438444924406048,0.952619589977221
4
+ 0.00,0.15,392,414,334,0.7076271186440678,0.8520408163265306,1803,1781,1723,0.9258463191832348,0.937129840546697
5
+ 0.00,0.20,392,423,326,0.6666666666666666,0.8316326530612245,1803,1772,1706,0.9127875869448903,0.9257403189066059
6
+ 0.00,0.25,392,429,327,0.6619433198380567,0.8341836734693877,1803,1766,1701,0.9105995717344754,0.9239179954441914
7
+ 0.05,0.10,401,398,356,0.8036117381489842,0.8877805486284289,1794,1797,1752,0.9526916802610114,0.9603644646924829
8
+ 0.05,0.15,401,414,350,0.7526881720430108,0.8728179551122195,1794,1781,1730,0.9376693766937669,0.9476082004555809
9
+ 0.05,0.20,401,423,341,0.7060041407867494,0.8503740648379052,1794,1772,1712,0.9234088457389428,0.9353075170842825
10
+ 0.05,0.25,401,429,337,0.6835699797160243,0.8403990024937655,1794,1766,1702,0.9160387513455328,0.9289293849658314
11
+ 0.10,0.15,398,414,355,0.7768052516411379,0.8919597989949749,1797,1781,1738,0.9445652173913044,0.9535307517084283
12
+ 0.10,0.20,398,423,350,0.7430997876857749,0.8793969849246231,1797,1772,1724,0.9344173441734417,0.944874715261959
13
+ 0.10,0.25,398,429,341,0.7016460905349794,0.8567839195979899,1797,1766,1709,0.9217907227615966,0.9339407744874715
14
+ 0.15,0.20,414,423,359,0.7510460251046025,0.8671497584541062,1781,1772,1717,0.9351851851851852,0.9457858769931663
15
+ 0.15,0.25,414,429,354,0.7239263803680982,0.855072463768116,1781,1766,1706,0.9266702878870179,0.9384965831435079
16
+ 0.20,0.25,423,429,372,0.775,0.8794326241134752,1772,1766,1715,0.9407569939659901,0.9507972665148063
analysis/intervention_analysis/Qwen_Qwen3.5-4B__vsr_per_sample.csv ADDED
The diff for this file is too large to render. See raw diff
 
analysis/intervention_analysis/Qwen_Qwen3.5-4B__youtube_level1_failure_overlap.csv ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ baseline_a,baseline_b,failures_a,failures_b,failures_shared,failure_jaccard,failure_recall_a_in_b,successes_a,successes_b,successes_shared,success_jaccard,answer_agreement
2
+ 0.00,0.05,388,393,361,0.8595238095238096,0.9304123711340206,433,428,401,0.8717391304347826,0.8964677222898904
3
+ 0.00,0.10,388,395,354,0.8251748251748252,0.9123711340206185,433,426,392,0.8394004282655246,0.8745432399512789
4
+ 0.00,0.15,388,377,342,0.8085106382978723,0.8814432989690721,433,444,398,0.8308977035490606,0.8599269183922046
5
+ 0.00,0.20,388,382,339,0.7865429234338747,0.8737113402061856,433,439,390,0.8091286307053942,0.8404384896467723
6
+ 0.00,0.25,388,382,338,0.7824074074074074,0.8711340206185567,433,439,389,0.8053830227743272,0.8343483556638246
7
+ 0.05,0.10,393,395,363,0.8541176470588235,0.9236641221374046,428,426,396,0.8646288209606987,0.8855054811205847
8
+ 0.05,0.15,393,377,342,0.7990654205607477,0.8702290076335878,428,444,393,0.8204592901878914,0.8635809987819733
9
+ 0.05,0.20,393,382,343,0.7939814814814815,0.8727735368956743,428,439,389,0.8138075313807531,0.8453105968331304
10
+ 0.05,0.25,393,382,338,0.7734553775743707,0.8600508905852418,428,439,384,0.7950310559006211,0.8258221680876979
11
+ 0.10,0.15,395,377,349,0.8250591016548463,0.8835443037974684,426,444,398,0.8432203389830508,0.8781973203410475
12
+ 0.10,0.20,395,382,350,0.819672131147541,0.8860759493670886,426,439,394,0.8365180467091295,0.8684531059683313
13
+ 0.10,0.25,395,382,347,0.8069767441860465,0.8784810126582279,426,439,391,0.8248945147679325,0.8514007308160779
14
+ 0.15,0.20,377,382,341,0.8157894736842105,0.9045092838196287,444,439,403,0.8395833333333333,0.8721071863580999
15
+ 0.15,0.25,377,382,338,0.8028503562945368,0.896551724137931,444,439,400,0.8281573498964804,0.8611449451887941
16
+ 0.20,0.25,382,382,346,0.8277511961722488,0.9057591623036649,439,439,403,0.848421052631579,0.8781973203410475
analysis/intervention_analysis/Qwen_Qwen3.5-4B__youtube_level1_per_sample.csv ADDED
The diff for this file is too large to render. See raw diff
 
analysis/intervention_analysis/Qwen_Qwen3.5-4B__youtube_level2_failure_overlap.csv ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ baseline_a,baseline_b,failures_a,failures_b,failures_shared,failure_jaccard,failure_recall_a_in_b,successes_a,successes_b,successes_shared,success_jaccard,answer_agreement
2
+ 0.00,0.05,465,466,438,0.8884381338742393,0.9419354838709677,299,298,271,0.8312883435582822,0.8782722513089005
3
+ 0.00,0.10,465,472,438,0.8777555110220441,0.9419354838709677,299,292,265,0.8128834355828221,0.8586387434554974
4
+ 0.00,0.15,465,468,433,0.866,0.9311827956989247,299,296,264,0.797583081570997,0.8363874345549738
5
+ 0.00,0.20,465,474,434,0.8594059405940594,0.9333333333333333,299,290,259,0.7848484848484848,0.8285340314136126
6
+ 0.00,0.25,465,470,423,0.826171875,0.9096774193548387,299,294,252,0.7390029325513197,0.81282722513089
7
+ 0.05,0.10,466,472,441,0.8873239436619719,0.9463519313304721,298,292,267,0.826625386996904,0.8821989528795812
8
+ 0.05,0.15,466,468,438,0.8830645161290323,0.9399141630901288,298,296,268,0.8220858895705522,0.8664921465968587
9
+ 0.05,0.20,466,474,437,0.8687872763419483,0.9377682403433476,298,290,261,0.7981651376146789,0.856020942408377
10
+ 0.05,0.25,466,470,432,0.8571428571428571,0.927038626609442,298,294,260,0.7831325301204819,0.8599476439790575
11
+ 0.10,0.15,472,468,445,0.898989898989899,0.9427966101694916,292,296,269,0.8432601880877743,0.8821989528795812
12
+ 0.10,0.20,472,474,447,0.8957915831663327,0.9470338983050848,292,290,265,0.8359621451104101,0.8678010471204188
13
+ 0.10,0.25,472,470,438,0.8690476190476191,0.9279661016949152,292,294,260,0.7975460122699386,0.856020942408377
14
+ 0.15,0.20,468,474,446,0.8991935483870968,0.9529914529914529,296,290,268,0.8427672955974843,0.8704188481675392
15
+ 0.15,0.25,468,470,440,0.8835341365461847,0.9401709401709402,296,294,266,0.8209876543209876,0.8704188481675392
16
+ 0.20,0.25,474,470,443,0.8842315369261478,0.9345991561181435,290,294,263,0.8193146417445483,0.8520942408376964
analysis/intervention_analysis/Qwen_Qwen3.5-4B__youtube_level2_per_sample.csv ADDED
The diff for this file is too large to render. See raw diff