Commit 6bd60b8
authored
Support fixed/user-defined scaling factors for stable model refreshes (#2479)
* Support fixed/user-defined scaling factors for stable model refreshes (#2478)
Add method="fixed" to VariableScaling so users can pin scaling constants
that remain stable across production model refreshes, eliminating
scale-induced prior drift when data distributions change.
Made-with: Cursor
* Address review feedback: serialization, dict-valued scaling, key validation
- Fix legacy MMM serialization round-trip: use model_dump() in
create_idata_attrs and pass value through in _deserialize_scaling so
fixed scaling survives save/load.
- Support dict-valued fixed channel scaling in legacy MMM (per-channel
constants keyed by column name); reject dict-valued target with a
clear error since the 1-D MMM has a single target.
- Validate dict keys against coordinate labels in multidimensional MMM:
report missing and unexpected keys explicitly instead of late KeyError
or silent ignore.
- Add regression tests for all three fixes.
Made-with: Cursor
* Improve patch coverage: add tests, remove dead code
- Remove dead `scaling is None` branch in create_idata_attrs (scaling is
always set in __init__)
- Replace isinstance guard with cast() for mypy narrowing
- Add test for dict-valued scaling with wrong remaining dims count
- Add tests for VariableScaling dims validation (date, duplicates)
Made-with: Cursor
* Restore legacy MMM scaling type check
This preserves the legacy TypeError contract for non-fixed scaling so the shard 5 edge-case test passes after the fixed-scaling refactor.
Made-with: Cursor
* Refactor VariableScaling into a two-class hierarchy
Split the single VariableScaling class into an abstract base with two
concrete subclasses (DataDerivedScaling and FixedScaling) to eliminate
the awkward optional value field and its cross-field validation, per
code review feedback.
- VariableScaling(ABC) keeps dims + _validate_dims
- DataDerivedScaling has method: Literal["max", "mean"]
- FixedScaling has value: float | dict[str, float] (non-optional)
- Scaling.to_dict/from_dict use the __type__ registry for polymorphic
serialization; legacy format (no __type__) still loads correctly
- Updated legacy MMM and multidimensional MMM to use isinstance checks
and the new concrete classes
- All 844 tests pass across test_scaling, test_mmm, test_multidimensional
Made-with: Cursor
* Extract _build_fixed_scale to eliminate multiple returns
Address review comment by refactoring _compute_scale_for_variable into
two methods: the main method now has a single return, dispatching to a
dedicated _build_fixed_scale helper for FixedScaling logic.
Made-with: Cursor
* Validate dict-valued FixedScaling keys at init, not build_model
Move the missing/extra key checks for dict-valued channel FixedScaling
from build_model() to MMM.__init__() in both legacy and multidimensional
implementations, so users get immediate feedback on key mismatches.
Made-with: Cursor
* feat(mmm): multidimensional fixed scaling with DataArray and init fix
- Validate dict channel keys at init only when remaining dim is channel
- Support FixedScaling.value as xarray.DataArray (broadcast to reduced grid)
- JSON-safe DataArray serialization; from_long_dataframe helper
- Clearer dict error when multiple remaining dims; target dict keys at build
- Tests: broadcast, full grids, 3D panel, misaligned coords, idata round-trip
- Doc examples for panel fixed scaling
Made-with: Cursor
* fix(test): add fastprogress to test extras for BlackJAX mlflow autolog
BlackJAX sampling uses jax.io_callback for progress bars, which requires
fastprogress. CI installs only .[test]; without it, test_autolog_pymc_model
fails with CpuCallback errors on Linux runners.
Made-with: Cursor
* revert: drop fastprogress from test extras (unrelated to fixed scaling PR)
Restore prior test dependency set; BlackJAX/mlflow env gap can be
addressed separately on main.
Made-with: Cursor1 parent 7dfb966 commit 6bd60b8
7 files changed
Lines changed: 1546 additions & 125 deletions
File tree
- pymc_marketing/mmm
- tests/mmm
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
63 | 63 | | |
64 | 64 | | |
65 | 65 | | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
66 | 72 | | |
67 | 73 | | |
68 | 74 | | |
| |||
78 | 84 | | |
79 | 85 | | |
80 | 86 | | |
| 87 | + | |
81 | 88 | | |
82 | 89 | | |
| 90 | + | |
83 | 91 | | |
84 | 92 | | |
85 | 93 | | |
| |||
99 | 107 | | |
100 | 108 | | |
101 | 109 | | |
| 110 | + | |
102 | 111 | | |
103 | 112 | | |
104 | 113 | | |
105 | 114 | | |
106 | 115 | | |
107 | 116 | | |
| 117 | + | |
108 | 118 | | |
109 | 119 | | |
110 | 120 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
| 20 | + | |
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
| |||
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
57 | | - | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
58 | 64 | | |
59 | 65 | | |
60 | 66 | | |
| |||
205 | 211 | | |
206 | 212 | | |
207 | 213 | | |
208 | | - | |
209 | 214 | | |
210 | 215 | | |
211 | 216 | | |
212 | 217 | | |
213 | | - | |
| 218 | + | |
214 | 219 | | |
215 | | - | |
| 220 | + | |
216 | 221 | | |
217 | 222 | | |
218 | 223 | | |
219 | 224 | | |
220 | | - | |
221 | | - | |
| 225 | + | |
| 226 | + | |
222 | 227 | | |
223 | 228 | | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
224 | 240 | | |
225 | 241 | | |
226 | 242 | | |
| |||
450 | 466 | | |
451 | 467 | | |
452 | 468 | | |
453 | | - | |
454 | | - | |
455 | | - | |
456 | | - | |
457 | | - | |
458 | | - | |
459 | | - | |
460 | | - | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
461 | 492 | | |
462 | | - | |
463 | | - | |
464 | | - | |
465 | | - | |
466 | | - | |
467 | | - | |
468 | | - | |
469 | | - | |
470 | | - | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
471 | 522 | | |
472 | 523 | | |
473 | 524 | | |
| |||
493 | 544 | | |
494 | 545 | | |
495 | 546 | | |
496 | | - | |
497 | | - | |
498 | | - | |
499 | | - | |
500 | | - | |
501 | | - | |
502 | | - | |
503 | | - | |
504 | | - | |
505 | | - | |
506 | | - | |
507 | | - | |
508 | | - | |
509 | | - | |
510 | | - | |
511 | | - | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
512 | 550 | | |
513 | 551 | | |
514 | 552 | | |
| |||
1254 | 1292 | | |
1255 | 1293 | | |
1256 | 1294 | | |
| 1295 | + | |
| 1296 | + | |
| 1297 | + | |
1257 | 1298 | | |
1258 | 1299 | | |
1259 | 1300 | | |
| |||
1267 | 1308 | | |
1268 | 1309 | | |
1269 | 1310 | | |
| 1311 | + | |
| 1312 | + | |
| 1313 | + | |
| 1314 | + | |
| 1315 | + | |
1270 | 1316 | | |
1271 | | - | |
1272 | | - | |
1273 | | - | |
1274 | | - | |
1275 | | - | |
1276 | | - | |
1277 | | - | |
1278 | | - | |
| 1317 | + | |
| 1318 | + | |
1279 | 1319 | | |
1280 | 1320 | | |
1281 | 1321 | | |
| |||
0 commit comments