anhtld commited on
Commit
32d209b
·
verified ·
1 Parent(s): 6ba7436

auto-sync 2026-07-02T23:07:00Z workspace

Browse files
workspace/cil/__init__.py CHANGED
@@ -7,26 +7,38 @@ stable place to import benchmark metrics from.
7
 
8
  from cil.metrics import (
9
  bootstrap_ci,
 
10
  branch_causal_action_regret,
11
  car_decomposition,
12
  macro_micro_summary,
 
 
13
  negative_near_at_threshold,
 
14
  pairwise_causal_dominance_ece,
15
  positive_tangent_recall_at_k,
16
  positives_closer_than_negatives,
 
 
17
  selector_regret_at_k,
18
  support_gap,
19
  )
20
 
21
  __all__ = [
22
  "bootstrap_ci",
 
23
  "branch_causal_action_regret",
24
  "car_decomposition",
25
  "macro_micro_summary",
 
 
26
  "negative_near_at_threshold",
 
27
  "pairwise_causal_dominance_ece",
28
  "positive_tangent_recall_at_k",
29
  "positives_closer_than_negatives",
 
 
30
  "selector_regret_at_k",
31
  "support_gap",
32
  ]
 
7
 
8
  from cil.metrics import (
9
  bootstrap_ci,
10
+ branch_car,
11
  branch_causal_action_regret,
12
  car_decomposition,
13
  macro_micro_summary,
14
+ measured_support_gap,
15
+ MetricInputError,
16
  negative_near_at_threshold,
17
+ outcome_ptr_at_k,
18
  pairwise_causal_dominance_ece,
19
  positive_tangent_recall_at_k,
20
  positives_closer_than_negatives,
21
+ proxy_positive_tangent_coverage_at_k,
22
+ proxy_support_distance,
23
  selector_regret_at_k,
24
  support_gap,
25
  )
26
 
27
  __all__ = [
28
  "bootstrap_ci",
29
+ "branch_car",
30
  "branch_causal_action_regret",
31
  "car_decomposition",
32
  "macro_micro_summary",
33
+ "measured_support_gap",
34
+ "MetricInputError",
35
  "negative_near_at_threshold",
36
+ "outcome_ptr_at_k",
37
  "pairwise_causal_dominance_ece",
38
  "positive_tangent_recall_at_k",
39
  "positives_closer_than_negatives",
40
+ "proxy_positive_tangent_coverage_at_k",
41
+ "proxy_support_distance",
42
  "selector_regret_at_k",
43
  "support_gap",
44
  ]
workspace/cil/metrics.py CHANGED
@@ -12,6 +12,10 @@ Vector = Sequence[Number]
12
  Matrix = Sequence[Vector]
13
 
14
 
 
 
 
 
15
  def branch_causal_action_regret(best_measured_branch: Number, selected_branch: Number) -> float:
16
  """Regret to the best measured branch in a same-state action chart.
17
 
@@ -22,28 +26,93 @@ def branch_causal_action_regret(best_measured_branch: Number, selected_branch: N
22
  return max(0.0, float(best_measured_branch) - float(selected_branch))
23
 
24
 
25
- def positive_tangent_recall_at_k(
 
 
 
 
 
 
26
  generated_utilities: Sequence[Number],
27
  base_utility: Number,
28
  *,
29
  epsilon: float = 0.0,
30
  k: int | None = None,
 
31
  ) -> float:
32
- """Return 1.0 if any generated proposal improves over the base action."""
 
 
 
 
 
33
 
 
 
 
 
 
34
  prefix = _prefix(generated_utilities, k)
35
  threshold = float(base_utility) + float(epsilon)
36
  return 1.0 if any(float(value) > threshold for value in prefix) else 0.0
37
 
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  def selector_regret_at_k(
40
  generated_utilities: Sequence[Number],
41
  *,
42
  selected_index: int = 0,
43
  k: int | None = None,
 
44
  ) -> float:
45
  """Selector regret inside the generated proposal prefix."""
46
 
 
 
 
 
47
  prefix = _prefix(generated_utilities, k)
48
  if not prefix:
49
  return 0.0
@@ -58,6 +127,23 @@ def support_gap(best_hidden_chart: Number, best_generated_set: Number) -> float:
58
  return max(0.0, float(best_hidden_chart) - float(best_generated_set))
59
 
60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  def car_decomposition(
62
  *,
63
  best_hidden_chart: Number,
@@ -102,6 +188,24 @@ def car_decomposition(
102
  return payload
103
 
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  def negative_near_at_threshold(
106
  generated_tangents: Matrix,
107
  negative_tangents: Matrix,
 
12
  Matrix = Sequence[Vector]
13
 
14
 
15
+ class MetricInputError(ValueError):
16
+ """Raised when a measured metric is requested from proxy-only inputs."""
17
+
18
+
19
  def branch_causal_action_regret(best_measured_branch: Number, selected_branch: Number) -> float:
20
  """Regret to the best measured branch in a same-state action chart.
21
 
 
26
  return max(0.0, float(best_measured_branch) - float(selected_branch))
27
 
28
 
29
+ def branch_car(best_measured_branch: Number, selected_branch: Number) -> float:
30
+ """Alias matching the paper metric name BranchCAR."""
31
+
32
+ return branch_causal_action_regret(best_measured_branch, selected_branch)
33
+
34
+
35
+ def outcome_ptr_at_k(
36
  generated_utilities: Sequence[Number],
37
  base_utility: Number,
38
  *,
39
  epsilon: float = 0.0,
40
  k: int | None = None,
41
+ candidates_evaluated: bool = True,
42
  ) -> float:
43
+ """OutcomePTR@K for generated candidates with measured outcomes.
44
+
45
+ This is a measured metric. It must not be computed from nearest-neighbor
46
+ distances to hidden positives. Use ``proxy_positive_tangent_coverage_at_k``
47
+ for distance-only support diagnostics.
48
+ """
49
 
50
+ if not candidates_evaluated:
51
+ raise MetricInputError(
52
+ "OutcomePTR@K requires rolled-out/evaluated generated candidates; "
53
+ "use PPTC@K for distance-only support proxies"
54
+ )
55
  prefix = _prefix(generated_utilities, k)
56
  threshold = float(base_utility) + float(epsilon)
57
  return 1.0 if any(float(value) > threshold for value in prefix) else 0.0
58
 
59
 
60
+ def positive_tangent_recall_at_k(
61
+ generated_utilities: Sequence[Number],
62
+ base_utility: Number,
63
+ *,
64
+ epsilon: float = 0.0,
65
+ k: int | None = None,
66
+ ) -> float:
67
+ """Legacy alias for measured OutcomePTR@K.
68
+
69
+ New code should call ``outcome_ptr_at_k``. Distance-based support diagnostics
70
+ must call ``proxy_positive_tangent_coverage_at_k`` and be reported as PPTC.
71
+ """
72
+
73
+ return outcome_ptr_at_k(
74
+ generated_utilities,
75
+ base_utility,
76
+ epsilon=epsilon,
77
+ k=k,
78
+ candidates_evaluated=True,
79
+ )
80
+
81
+
82
+ def proxy_positive_tangent_coverage_at_k(
83
+ generated_tangents: Matrix,
84
+ positive_tangents: Matrix,
85
+ *,
86
+ threshold: float,
87
+ k: int | None = None,
88
+ ) -> float:
89
+ """PPTC@K: distance-only proxy coverage of measured positive tangents."""
90
+
91
+ if threshold < 0:
92
+ raise ValueError("threshold must be non-negative")
93
+ generated = _prefix(generated_tangents, k)
94
+ if not generated or not positive_tangents:
95
+ return 0.0
96
+ for tangent in generated:
97
+ nearest_positive = min(_rms_l2(tangent, positive) for positive in positive_tangents)
98
+ if nearest_positive <= threshold:
99
+ return 1.0
100
+ return 0.0
101
+
102
+
103
  def selector_regret_at_k(
104
  generated_utilities: Sequence[Number],
105
  *,
106
  selected_index: int = 0,
107
  k: int | None = None,
108
+ candidates_evaluated: bool = True,
109
  ) -> float:
110
  """Selector regret inside the generated proposal prefix."""
111
 
112
+ if not candidates_evaluated:
113
+ raise MetricInputError(
114
+ "SelectorRegret@K requires measured generated-candidate outcomes"
115
+ )
116
  prefix = _prefix(generated_utilities, k)
117
  if not prefix:
118
  return 0.0
 
127
  return max(0.0, float(best_hidden_chart) - float(best_generated_set))
128
 
129
 
130
+ def measured_support_gap(
131
+ best_hidden_chart: Number,
132
+ best_measured_generated_candidate: Number,
133
+ *,
134
+ candidates_evaluated: bool = True,
135
+ generated_subset_of_hidden: bool = False,
136
+ ) -> float:
137
+ """SupportGap when generated candidates have measured outcomes."""
138
+
139
+ if not candidates_evaluated and not generated_subset_of_hidden:
140
+ raise MetricInputError(
141
+ "SupportGap requires evaluated generated candidates or a generated set "
142
+ "that is a subset of measured hidden chart branches"
143
+ )
144
+ return support_gap(best_hidden_chart, best_measured_generated_candidate)
145
+
146
+
147
  def car_decomposition(
148
  *,
149
  best_hidden_chart: Number,
 
188
  return payload
189
 
190
 
191
+ def proxy_support_distance(
192
+ generated_tangents: Matrix,
193
+ positive_tangents: Matrix,
194
+ *,
195
+ k: int | None = None,
196
+ ) -> float | None:
197
+ """Minimum RMS-L2 distance from generated tangents to target positives."""
198
+
199
+ generated = _prefix(generated_tangents, k)
200
+ if not generated or not positive_tangents:
201
+ return None
202
+ return min(
203
+ _rms_l2(tangent, positive)
204
+ for tangent in generated
205
+ for positive in positive_tangents
206
+ )
207
+
208
+
209
  def negative_near_at_threshold(
210
  generated_tangents: Matrix,
211
  negative_tangents: Matrix,
workspace/data/cil_charts/train/charts_00000.npz CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:2561285532fe5f7445b34c726fc592f53863ba6e3ab05ffabd693c8b40e82528
3
  size 39156136
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e310a85a4b772d3013c51c1283d49f6a1365d8309e335d4f2e2c2beb6d97269b
3
  size 39156136
workspace/data/cil_charts/train/index.json CHANGED
The diff for this file is too large to render. See raw diff
 
workspace/latex/main.log CHANGED
@@ -1,4 +1,4 @@
1
- This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2021 Gentoo Linux) (preloaded format=pdflatex 2023.8.23) 2 JUL 2026 18:44
2
  entering extended mode
3
  restricted \write18 enabled.
4
  %&-line parsing enabled.
@@ -489,11 +489,11 @@ Package rerunfilecheck Info: File `main.out' has not changed.
489
  (rerunfilecheck) Checksum: B3D461B4FEC67164F7152E09ACAEE494;1245.
490
  )
491
  Here is how much of TeX's memory you used:
492
- 9900 strings out of 480884
493
- 146747 string characters out of 5900692
494
  460545 words of memory out of 5000000
495
- 26980 multiletter control sequences out of 15000+600000
496
- 414083 words of font info for 68 fonts, out of 8000000 for 9000
497
  36 hyphenation exceptions out of 8191
498
  71i,8n,74p,371b,393s stack positions out of 5000i,500n,10000p,200000b,80000s
499
  {/cvmfs/soft.computecanada.ca/gentoo/2023/x86-64-v3/usr/share/texmf-dist/font
@@ -521,13 +521,15 @@ share/texmf-dist/fonts/type1/public/amsfonts/cm/cmr9.pfb></cvmfs/soft.computeca
521
  nada.ca/gentoo/2023/x86-64-v3/usr/share/texmf-dist/fonts/type1/public/amsfonts/
522
  cm/cmsy10.pfb></cvmfs/soft.computecanada.ca/gentoo/2023/x86-64-v3/usr/share/tex
523
  mf-dist/fonts/type1/public/amsfonts/cm/cmsy7.pfb></cvmfs/soft.computecanada.ca/
524
- gentoo/2023/x86-64-v3/usr/share/texmf-dist/fonts/type1/public/amsfonts/symbols/
525
- msbm10.pfb></cvmfs/soft.computecanada.ca/gentoo/2023/x86-64-v3/usr/share/texmf-
526
- dist/fonts/type1/public/cm-super/sfrm1000.pfb>
527
- Output written on main.pdf (6 pages, 214742 bytes).
 
 
528
  PDF statistics:
529
- 158 PDF objects out of 1000 (max. 8388607)
530
- 130 compressed objects within 2 object streams
531
  22 named destinations out of 1000 (max. 500000)
532
  81 words of extra memory for PDF output out of 10000 (max. 10000000)
533
 
 
1
+ This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2021 Gentoo Linux) (preloaded format=pdflatex 2023.8.23) 2 JUL 2026 19:02
2
  entering extended mode
3
  restricted \write18 enabled.
4
  %&-line parsing enabled.
 
489
  (rerunfilecheck) Checksum: B3D461B4FEC67164F7152E09ACAEE494;1245.
490
  )
491
  Here is how much of TeX's memory you used:
492
+ 9904 strings out of 480884
493
+ 146795 string characters out of 5900692
494
  460545 words of memory out of 5000000
495
+ 26983 multiletter control sequences out of 15000+600000
496
+ 414251 words of font info for 69 fonts, out of 8000000 for 9000
497
  36 hyphenation exceptions out of 8191
498
  71i,8n,74p,371b,393s stack positions out of 5000i,500n,10000p,200000b,80000s
499
  {/cvmfs/soft.computecanada.ca/gentoo/2023/x86-64-v3/usr/share/texmf-dist/font
 
521
  nada.ca/gentoo/2023/x86-64-v3/usr/share/texmf-dist/fonts/type1/public/amsfonts/
522
  cm/cmsy10.pfb></cvmfs/soft.computecanada.ca/gentoo/2023/x86-64-v3/usr/share/tex
523
  mf-dist/fonts/type1/public/amsfonts/cm/cmsy7.pfb></cvmfs/soft.computecanada.ca/
524
+ gentoo/2023/x86-64-v3/usr/share/texmf-dist/fonts/type1/public/amsfonts/cm/cmtt1
525
+ 0.pfb></cvmfs/soft.computecanada.ca/gentoo/2023/x86-64-v3/usr/share/texmf-dist/
526
+ fonts/type1/public/amsfonts/symbols/msbm10.pfb></cvmfs/soft.computecanada.ca/ge
527
+ ntoo/2023/x86-64-v3/usr/share/texmf-dist/fonts/type1/public/cm-super/sfrm1000.p
528
+ fb>
529
+ Output written on main.pdf (6 pages, 226804 bytes).
530
  PDF statistics:
531
+ 162 PDF objects out of 1000 (max. 8388607)
532
+ 133 compressed objects within 2 object streams
533
  22 named destinations out of 1000 (max. 500000)
534
  81 words of extra memory for PDF output out of 10000 (max. 10000000)
535