feat: MMM exporters container mode (aggregation_result= + scale=) on the 3.9 aggregation surface - #765
Merged
Conversation
…the 3.9 aggregation surface
Both MMM exporters now accept the pinned AggregationResult container from
post-fit results.aggregate('simple'|'group') via aggregation_result=, with a
required scale= (numeric, or "auto" for the audited ImputationDiD/TwoStageDiD
producers whose n matches the ATT's averaged support on unweighted, fully
identified fits). Derivation is effect = att * scale, se = se * scale, per row
in to_dataframe() order; everything the container cannot verify fails closed
(raw results objects, EventStudyResults, unsupported levels, non-"att" targets,
unusable inference, non-allowlisted "auto" with per-estimator hints keyed on
the container's estimator provenance).
Docs: REGISTRY MMM section reworded to the new posture with container-mode
Notes; api/mmm.rst examples made self-contained and added to the doc-snippet
executor; both LLM guides updated; producer-side n docstrings and REGISTRY
relay notes gain the finite-support qualifier; DEFERRED.md row rewritten to
the estimator-owned-totals remainder (CS/EfficientDiD/StackedDiD).
Tests: extraction/routing matrix on hand-built containers, container-mode
exporter tests, end-to-end workflows with frame-derived oracles, non-finite
identification divergence pins for both allowlisted estimators, overflow pin,
and a contract pin of exactly the AggregationResult surface consumed. One
CONSUMER_ALLOWLIST entry (estimator, diff_diff/mmm.py) for the container's
provenance field read.
Overall assessment: ✅ Looks goodExecutive summary
Methodology
Code QualityNo findings. PerformanceNo findings. MaintainabilityNo findings; schema and provenance contracts have explicit regression pins. Tech Debt
SecurityNo findings or apparent secrets. Documentation/Tests
Changed Python files passed syntax compilation. Runtime tests could not be executed because the review environment lacks pytest/numpy/pandas/scipy. |
… (TwoStageDiD group counts are post-filter)
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall assessment: ✅ Looks goodExecutive summary
Methodology
Code QualityNo findings. PerformanceNo findings. MaintainabilityNo findings; provenance and aggregation-schema contracts have regression coverage. Tech Debt
SecurityNo findings or apparent secrets. Documentation/TestsNo findings. The previous P2 is fixed: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
to_pymc_marketing_lift_test,to_meridian_roi_prior) gain a container mode:aggregation_result=accepts the pinnedAggregationResultreturned by post-fitresults.aggregate('simple')(one experiment row) or'group'(one row per cohort), together with the new requiredscale=, derivingeffect = att * scaleandse = se * scaleper row into_dataframe()order. The explicit-numbers route is unchanged; the two routes are mutually exclusive.scale="auto"reads the container's per-rownand is honored ONLY for ImputationDiD/TwoStageDiD provenance — the audited producers whosenmatches the ATT's averaged support on unweighted, fully identified fits. Passing"auto"acknowledges the three assumptions the container cannot verify (additive-level outcome, unweighted fit, fully identified effects); everything else fails closed with the remedy inline (raw results objects andEventStudyResults, unsupported levels, non-"att"targets rejected whole, unusable inference, non-allowlisted"auto"with per-estimator hints keyed on the container'sestimatorfield — never onn_kind, which serves only as a drift guard).**Note:**bullets;docs/api/mmm.rstOverview and examples rewritten (now self-contained and executed bytests/test_doc_snippets.py); both LLM guides updated; producer-sidendocstrings (imputation_results.py,two_stage_results.py) and their REGISTRY relay notes gain the finite-support qualifier so estimator sections and the MMM section agree;DEFERRED.mdrow rewritten to the estimator-owned-totals remainder (CS/EfficientDiD/StackedDiD, whose containers report units/cells).tests/test_naming_guard.py: oneCONSUMER_ALLOWLISTentry("estimator", "diff_diff/mmm.py")mirroringaggregation.py's existing entry for the same independent container field.Methodology references (required if estimator / math changes)
lognormal_dist_from_mean_std(Meridian 1.7.0). See the REGISTRY "MMM Calibration Export (interop)" section.scale="auto"assumptions (additive outcome, unweighted fit, fully identified effects) and the correlated-group-container caveats are documented as REGISTRY**Note:**bullets; no pooling/lognormal math changed.Validation
tests/test_mmm.py(extraction/routing matrix, container-mode exporter tests, end-to-end workflows with frame-derived oracles, non-finite identification divergence pins for both allowlisted estimators, overflow pin,AggregationResultcontract pin, runtime-resolvable annotations pin),tests/test_naming_guard.py(allowlist entry),tests/test_doc_snippets.py(api/mmm.rstadded to the executed roster).att * nagainst counts derived independently from the input frames.Security / privacy