Spaces:
Paused
Paused
File size: 7,187 Bytes
6342806 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | """Baseline-vs-candidate regression analysis across strata, with statistical
and safety significance kept STRICTLY separate.
Strata: global / class / scenario-type / safety / ODD. For each stratum we
report absolute + relative delta, a cluster-robust confidence interval,
sample size, and two independent verdicts:
* statistical significance — is the delta distinguishable from noise?
Delegated to sensorflow.seqeval (anytime-valid PairedSequentialTest on
cluster means) — REUSE, not reimplementation. The descriptive CI uses
seqeval's cluster machinery (units.py) as well.
* safety significance — does the delta matter for safety? A deterministic
policy question: the stratum's safety margin (tighter for safety strata)
and the direction of the effect. A tiny-but-certain regression can be
statistically significant yet safety-insignificant; a large regression on
a small safety stratum can be safety-significant (blocking further
evaluation, demanding more data) while statistically unresolved. The two
are NEVER combined into one number.
Launch recommendation policy (deterministic):
* lineage invalid -> INVALID (never launchable)
* any safety-significant regression that
is also statistically confirmed -> DO_NOT_LAUNCH
* safety-significant but statistically
unresolved -> INSUFFICIENT_EVIDENCE
* otherwise -> LAUNCH
"""
from __future__ import annotations
from typing import Dict, List, Optional
import numpy as np
# REUSE: all sequential statistics from seqeval.
from sensorflow.seqeval.sequential import (
DECISION_INSUFFICIENT, DECISION_PASS, DECISION_REGRESSION,
PairedSequentialTest,
)
from sensorflow.seqeval.units import cluster_summary, cluster_units
from sensorflow.nextgen.lineage import validate_lineage
from sensorflow.nextgen.models import LaunchRecommendation, LineageRecord
# Safety margins per stratum kind (absolute metric points).
SAFETY_MARGINS = {"safety": 0.005, "odd": 0.010, "scenario": 0.010,
"class": 0.015, "global": 0.010}
STATISTICAL_MARGIN = 0.005 # practical-significance margin for the e-process
ALPHA = 0.05
def analyze_stratum(name: str, kind: str,
baseline: np.ndarray, candidate: np.ndarray,
cluster_ids: np.ndarray,
data_label: str = "SIMULATED") -> Dict:
"""Full per-stratum record from paired per-unit outcomes."""
b = np.asarray(baseline, dtype=np.float64)
c = np.asarray(candidate, dtype=np.float64)
d = c - b
test = PairedSequentialTest(delta=STATISTICAL_MARGIN, alpha=ALPHA)
means, _sizes = cluster_units(d, cluster_ids)
test.update_clusters(means)
test.record_objects(b.astype(bool), c.astype(bool))
decision = test.evaluate()
lo, hi = test.delta_interval()
base_rate = float(b.mean()) if b.size else None
cand_rate = float(c.mean()) if c.size else None
delta_abs = None if base_rate is None else cand_rate - base_rate
delta_rel = (None if not base_rate else delta_abs / base_rate)
margin = SAFETY_MARGINS.get(kind, 0.010)
# Safety significance: the point estimate breaches the stratum's safety
# margin in the harmful direction. Deliberately a POLICY statement about
# magnitude, independent of the statistical verdict.
safety_significant = delta_abs is not None and delta_abs < -margin
statistically_significant = decision == DECISION_REGRESSION
return {
"stratum": name, "kind": kind, "data_label": data_label,
"n": int(b.size),
"clustering": cluster_summary(d, cluster_ids),
"baseline_rate": _r(base_rate), "candidate_rate": _r(cand_rate),
"delta_abs": _r(delta_abs), "delta_rel": _r(delta_rel),
"delta_ci": [_r(lo), _r(hi)],
"ci_method": "anytime-valid empirical-Bernstein confidence sequence "
"on cluster means (seqeval)",
"statistical": {
"decision": decision,
"significant_regression": statistically_significant,
"e_regression": round(test.e_reg.e_value, 4),
"e_pass": round(test.e_pass.e_value, 4),
"margin": STATISTICAL_MARGIN, "alpha": ALPHA,
},
"safety": {
"margin": margin,
"significant": bool(safety_significant),
"note": "safety significance is a policy magnitude judgment; it "
"is never derived from, nor equated with, the "
"statistical verdict",
},
}
def launch_recommendation(run_id: str, strata: List[Dict],
lineage: Optional[LineageRecord],
data_labels: List[str]) -> LaunchRecommendation:
lineage_ok, lineage_reasons = validate_lineage(lineage)
blockers: List[str] = []
stat_summary: Dict = {"regressions": [], "passes": [], "unresolved": []}
safety_summary: Dict = {"significant_regressions": [], "margins": SAFETY_MARGINS}
for s in strata:
dec = s["statistical"]["decision"]
if dec == DECISION_REGRESSION:
stat_summary["regressions"].append(s["stratum"])
elif dec == DECISION_PASS:
stat_summary["passes"].append(s["stratum"])
else:
stat_summary["unresolved"].append(s["stratum"])
if s["safety"]["significant"]:
safety_summary["significant_regressions"].append(
{"stratum": s["stratum"], "delta_abs": s["delta_abs"],
"statistical_decision": dec})
if not lineage_ok:
recommendation = "INVALID"
blockers.extend(lineage_reasons)
blockers.append("run is INVALID for launch purposes: incomplete lineage")
else:
confirmed = [r for r in safety_summary["significant_regressions"]
if r["statistical_decision"] == DECISION_REGRESSION]
unresolved = [r for r in safety_summary["significant_regressions"]
if r["statistical_decision"] == DECISION_INSUFFICIENT]
if confirmed:
recommendation = "DO_NOT_LAUNCH"
for r in confirmed:
blockers.append(
f"safety-significant regression in {r['stratum']} "
f"(delta {r['delta_abs']:+.4f}), statistically confirmed")
elif unresolved:
recommendation = "INSUFFICIENT_EVIDENCE"
for r in unresolved:
blockers.append(
f"safety-significant point estimate in {r['stratum']} "
f"(delta {r['delta_abs']:+.4f}) not yet statistically "
f"resolved — needs more evidence, not a launch")
else:
recommendation = "LAUNCH"
return LaunchRecommendation(
run_id=run_id, recommendation=recommendation, blockers=blockers,
statistical_significance=stat_summary,
safety_significance=safety_summary,
lineage_valid=lineage_ok,
data_labels=list(dict.fromkeys(data_labels))) # type: ignore[arg-type]
def _r(v: Optional[float], nd: int = 5) -> Optional[float]:
return None if v is None else round(float(v), nd)
|