Skip to content

Commit 6baefcc

Browse files
committed
Document cross-language semantic parity matrix
1 parent 527234d commit 6baefcc

1 file changed

Lines changed: 186 additions & 0 deletions

File tree

PARITY.md

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
# Cross-language semantic parity matrix
2+
3+
This document records the semantic parity findings established by the Stage 0
4+
contract and Stage 1 characterization tests in `rtichoke` and
5+
`rtichoke_python`.
6+
7+
It is descriptive. It does not change public APIs, statistical calculations,
8+
input formats, plotting behavior, or `rtichoke_viz`.
9+
10+
## Target semantic model
11+
12+
The cross-language target remains:
13+
14+
- **model**: what produced the predictions;
15+
- **population**: the subjects and observed outcomes used for evaluation;
16+
- **evaluation**: one `model × population` pair;
17+
- **evaluation context**: conditions qualifying that evaluation, including the
18+
fixed time horizon for time-dependent outputs;
19+
- **plotted series**: one evaluation in one applicable context;
20+
- **reference scope**: the population/context that determines a benchmark,
21+
independent of whether two benchmarks happen to have equal numerical values.
22+
23+
`reference_group` remains compatibility terminology. It is not the target
24+
domain abstraction.
25+
26+
## Input and grouping semantics
27+
28+
| Scenario | R | Python | Parity assessment |
29+
| --- | --- | --- | --- |
30+
| One model × one population | One plotted evaluation | One plotted evaluation | Semantic parity |
31+
| Multiple models × same population | Explicit `model` grouping | Generic `reference_group` labels act as models | Same semantics, different representation |
32+
| Same model × multiple populations | Explicit `population` grouping | Generic `reference_group` labels act as populations | Same semantics, different representation |
33+
| Distinct populations with equal prevalence | Remain distinct populations | Remain distinct static population contexts | Semantic parity for static outputs |
34+
| Explicit paired model-population inputs | Pair labels are represented through the population-shaped path | Pair labels remain generic `reference_group`s | Same plotted-evaluation cardinality, representation divergence |
35+
| Time-dependent evaluations | No corresponding characterized R time API in Stage 1 | Series are keyed by `reference_group × fixed_time_horizon` | Python-only characterization |
36+
37+
The main static representation difference is therefore structural rather than
38+
statistical: R exposes whether the keyed dimension is a model or population in
39+
its prepared data, while Python currently collapses both into
40+
`reference_group`.
41+
42+
## Reference-line parity by output
43+
44+
The table below describes semantic scope, not implementation-specific names.
45+
46+
| Output | Global reference | Population-dependent reference | Static R/Python parity |
47+
| --- | --- | --- | --- |
48+
| ROC | Random/identity diagonal | None | Aligned |
49+
| Precision-recall | None beyond the prevalence baseline | Random baseline = population prevalence | Aligned |
50+
| Gains | Random baseline | Perfect-model reference depends on population prevalence | Aligned |
51+
| Lift | Random baseline | Perfect-model reference depends on population prevalence | Aligned |
52+
| Decision curve | Treat-none | Treat-all depends on population prevalence | Aligned |
53+
| Interventions avoided | Treat-all | Treat-none counterpart depends on population prevalence | Aligned |
54+
| Calibration | Perfect-calibration identity line | None | Aligned |
55+
| Performance tables | Not applicable | Rows/groups represent evaluation grouping rather than reference lines | Broad semantic parity; representation differs |
56+
57+
For multiple models evaluated in one population, both implementations share the
58+
same population-dependent references across the models. For different
59+
populations, both static implementations retain population ownership of
60+
population-dependent references.
61+
62+
Critically, two distinct static populations with equal prevalence remain
63+
separate contexts in both languages even when their prevalence-dependent
64+
references are numerically identical. Coincident values do not collapse
65+
semantic ownership.
66+
67+
## Plot labels, legends, and colors
68+
69+
Both languages use the currently active grouping key to label and color plotted
70+
series. With multiple models in one population, model labels remain distinct;
71+
with multiple population-shaped inputs, population labels remain distinct.
72+
73+
This is presentation parity at the level needed for the semantic contract, but
74+
not evidence that the underlying representation is identical. In particular,
75+
Python labels and colors are still organized through `reference_group`, whereas
76+
R can retain an explicit `model` or `population` column before plotting.
77+
78+
Plotly renderer bookkeeping traces, cutoff markers, and animation traces are not
79+
additional semantic evaluations. A plotted series is identified by its model
80+
and evaluation context, not by raw trace count.
81+
82+
## Performance-table semantics
83+
84+
Static performance tables follow the same evaluation cardinality as the curve
85+
inputs in both languages:
86+
87+
- multiple models in the same population remain separate model evaluations;
88+
- multiple populations remain separate evaluation contexts;
89+
- paired inputs remain separate evaluations.
90+
91+
The representation differs: R can expose `model` versus `population` in the
92+
prepared data, whereas Python preserves the generic `reference_group` field.
93+
94+
For Python time-dependent performance data and tables, the characterized key is
95+
`reference_group × fixed_time_horizon`. This preserves separate horizon-specific
96+
rows/groups but does not separately encode model and population identity.
97+
98+
## Time-dependent Python findings
99+
100+
The Python time-dependent API is the main semantic divergence identified so far.
101+
102+
A model-derived time series is characterized by a generic group plus horizon,
103+
which corresponds conceptually to
104+
105+
`evaluation × fixed_time_horizon`.
106+
107+
However, the current implementation infers whether multiple groups represent
108+
multiple populations from whether their horizon-specific event risks differ.
109+
This makes reference ownership depend on numerical equality rather than
110+
population identity.
111+
112+
Consequences:
113+
114+
1. Multiple models sharing one outcome population correctly share reference
115+
lines at each horizon.
116+
2. Distinct populations with different event risks get population-specific
117+
references at that horizon.
118+
3. Distinct populations with equal event risk remain separate plotted series,
119+
but their population-dependent references collapse to shared references.
120+
4. The same pair of populations can therefore have shared references at one
121+
horizon and population-specific references at another if their risks first
122+
coincide and later diverge.
123+
124+
This behavior differs from the target semantic contract. Population ownership
125+
should not disappear merely because two populations happen to yield the same
126+
risk at one horizon.
127+
128+
## Classification of current differences
129+
130+
### Semantic parity
131+
132+
- evaluation cardinality for the static scenarios;
133+
- static curve grouping across ROC, precision-recall, gains, lift, decision,
134+
interventions avoided, and calibration;
135+
- static reference-line scope for all characterized outputs;
136+
- preservation of distinct static populations when prevalence is equal;
137+
- calibration identity-line semantics.
138+
139+
### Different representation of the same semantics
140+
141+
- R uses explicit `model` or `population` columns in key static paths;
142+
- Python uses the generic `reference_group` field for model-, population-, and
143+
paired-evaluation labels;
144+
- paired inputs are not explicitly decomposed into separate model and population
145+
dimensions in either characterized path.
146+
147+
### True semantic divergence to address later
148+
149+
- Python time-dependent population detection and reference ownership can depend
150+
on equality of event risk rather than stable population identity;
151+
- Python time-dependent prepared data does not separately encode model and
152+
population dimensions, so the implementation cannot reliably distinguish
153+
two models in one population from two populations with equal horizon-specific
154+
risk using semantic identity alone.
155+
156+
## Recommended parity direction
157+
158+
Future parity work should preserve existing public APIs until a migration plan
159+
is explicit, but internal semantics should move toward stable evaluation
160+
identity:
161+
162+
1. represent or derive **model identity** and **population identity** separately;
163+
2. define an evaluation as their pair;
164+
3. add horizon only as evaluation context, not as a substitute for population
165+
identity;
166+
4. scope prevalence/event-risk-dependent references to population (and horizon
167+
for time-dependent outputs), even when values coincide numerically;
168+
5. treat `reference_group` as a compatibility/display grouping field rather than
169+
the source of semantic truth;
170+
6. derive colors, labels, legends, tables, and eventually visualization specs
171+
from the explicit evaluation/context model.
172+
173+
This direction does **not** imply that every public function must immediately
174+
accept new `model` and `population` arguments. The next implementation stage
175+
should first identify the smallest internal representation change that can
176+
preserve existing APIs while making population ownership explicit.
177+
178+
## Implication for `rtichoke_viz`
179+
180+
No `rtichoke_viz` schema change should be made from this document alone.
181+
182+
When parity work reaches the visualization layer, the schema should be derived
183+
from explicit evaluation and reference ownership rather than promoting the
184+
current `reference_group` compatibility key into a permanent domain concept.
185+
Until the package-level semantics are aligned, the existing visualization proof
186+
should remain unchanged.

0 commit comments

Comments
 (0)