|
| 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