google-meridian 1.4.0__py3-none-any.whl → 1.5.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. {google_meridian-1.4.0.dist-info → google_meridian-1.5.1.dist-info}/METADATA +14 -11
  2. {google_meridian-1.4.0.dist-info → google_meridian-1.5.1.dist-info}/RECORD +50 -46
  3. {google_meridian-1.4.0.dist-info → google_meridian-1.5.1.dist-info}/WHEEL +1 -1
  4. meridian/analysis/analyzer.py +558 -398
  5. meridian/analysis/optimizer.py +90 -68
  6. meridian/analysis/review/checks.py +118 -116
  7. meridian/analysis/review/constants.py +3 -3
  8. meridian/analysis/review/results.py +131 -68
  9. meridian/analysis/review/reviewer.py +8 -23
  10. meridian/analysis/summarizer.py +6 -1
  11. meridian/analysis/test_utils.py +2898 -2538
  12. meridian/analysis/visualizer.py +28 -9
  13. meridian/backend/__init__.py +106 -0
  14. meridian/constants.py +1 -0
  15. meridian/data/input_data.py +30 -52
  16. meridian/data/input_data_builder.py +2 -9
  17. meridian/data/test_utils.py +25 -41
  18. meridian/data/validator.py +48 -0
  19. meridian/mlflow/autolog.py +19 -9
  20. meridian/model/adstock_hill.py +3 -5
  21. meridian/model/context.py +134 -0
  22. meridian/model/eda/constants.py +334 -4
  23. meridian/model/eda/eda_engine.py +724 -312
  24. meridian/model/eda/eda_outcome.py +177 -33
  25. meridian/model/model.py +159 -110
  26. meridian/model/model_test_data.py +38 -0
  27. meridian/model/posterior_sampler.py +103 -62
  28. meridian/model/prior_sampler.py +114 -94
  29. meridian/model/spec.py +23 -14
  30. meridian/templates/card.html.jinja +9 -7
  31. meridian/templates/chart.html.jinja +1 -6
  32. meridian/templates/finding.html.jinja +19 -0
  33. meridian/templates/findings.html.jinja +33 -0
  34. meridian/templates/formatter.py +41 -5
  35. meridian/templates/formatter_test.py +127 -0
  36. meridian/templates/style.css +66 -9
  37. meridian/templates/style.scss +85 -4
  38. meridian/templates/table.html.jinja +1 -0
  39. meridian/version.py +1 -1
  40. scenarioplanner/linkingapi/constants.py +1 -1
  41. scenarioplanner/mmm_ui_proto_generator.py +1 -0
  42. schema/processors/marketing_processor.py +11 -10
  43. schema/processors/model_processor.py +4 -1
  44. schema/serde/distribution.py +12 -7
  45. schema/serde/hyperparameters.py +54 -107
  46. schema/serde/meridian_serde.py +12 -3
  47. schema/utils/__init__.py +1 -0
  48. schema/utils/proto_enum_converter.py +127 -0
  49. {google_meridian-1.4.0.dist-info → google_meridian-1.5.1.dist-info}/licenses/LICENSE +0 -0
  50. {google_meridian-1.4.0.dist-info → google_meridian-1.5.1.dist-info}/top_level.txt +0 -0
@@ -29,7 +29,7 @@ CheckType = typing.Type[checks.BaseCheck]
29
29
  ConfigInstance = configs.BaseConfig
30
30
  ChecksBattery = immutabledict.immutabledict[CheckType, ConfigInstance]
31
31
 
32
- _DEFAULT_POST_CONVERGENCE_CHECKS: ChecksBattery = immutabledict.immutabledict({
32
+ _POST_CONVERGENCE_CHECKS: ChecksBattery = immutabledict.immutabledict({
33
33
  checks.BaselineCheck: configs.BaselineConfig(),
34
34
  checks.BayesianPPPCheck: configs.BayesianPPPConfig(),
35
35
  checks.GoodnessOfFitCheck: configs.GoodnessOfFitConfig(),
@@ -39,44 +39,29 @@ _DEFAULT_POST_CONVERGENCE_CHECKS: ChecksBattery = immutabledict.immutabledict({
39
39
 
40
40
 
41
41
  class ModelReviewer:
42
- """Executes a series of quality checks on a Meridian model.
42
+ """A tool for executing a series of quality checks on a Meridian model.
43
43
 
44
44
  The reviewer first runs a convergence check. If the model has converged, it
45
45
  proceeds to run a battery of post-convergence checks.
46
46
 
47
- The default battery of post-convergence checks includes:
47
+ The battery of post-convergence checks includes:
48
48
  - BaselineCheck
49
49
  - BayesianPPPCheck
50
50
  - GoodnessOfFitCheck
51
51
  - PriorPosteriorShiftCheck
52
52
  - ROIConsistencyCheck
53
- Each with its default configuration.
54
-
55
- This battery of checks can be customized by passing a dictionary to the
56
- `post_convergence_checks` argument of the constructor, mapping check
57
- classes to their configuration instances. For example, to run only the
58
- BaselineCheck with a non-default configuration:
59
-
60
- ```python
61
- my_checks = {
62
- checks.BaselineCheck: configs.BaselineConfig(
63
- negative_baseline_prob_review_threshold=0.1,
64
- negative_baseline_prob_fail_threshold=0.5,
65
- )
66
- }
67
- reviewer = ModelReviewer(meridian_model, post_convergence_checks=my_checks)
68
- ```
69
53
  """
70
54
 
71
55
  def __init__(
72
56
  self,
73
57
  meridian,
74
- post_convergence_checks: ChecksBattery = _DEFAULT_POST_CONVERGENCE_CHECKS,
75
58
  ):
76
59
  self._meridian = meridian
77
60
  self._results: list[results.CheckResult] = []
78
- self._analyzer = analyzer_module.Analyzer(meridian)
79
- self._post_convergence_checks = post_convergence_checks
61
+ self._analyzer = analyzer_module.Analyzer(
62
+ model_context=meridian.model_context,
63
+ inference_data=meridian.inference_data,
64
+ )
80
65
 
81
66
  def _run_and_handle(self, check_class, config):
82
67
  instance = check_class(self._meridian, self._analyzer, config) # pytype: disable=not-instantiable
@@ -136,7 +121,7 @@ class ModelReviewer:
136
121
  )
137
122
 
138
123
  # Run all other checks in sequence.
139
- for check_class, config in self._post_convergence_checks.items():
124
+ for check_class, config in _POST_CONVERGENCE_CHECKS.items():
140
125
  if (
141
126
  check_class == checks.PriorPosteriorShiftCheck
142
127
  and not self._uses_roi_priors()
@@ -60,10 +60,15 @@ RESPONSE_CURVES_CARD_SPEC = formatter.CardSpec(
60
60
  class Summarizer:
61
61
  """Generates HTML summary visualizations from the model fitting."""
62
62
 
63
+ # TODO: Switch to model_context, model_equations, and
64
+ # inference_data.
63
65
  def __init__(self, meridian: model.Meridian, use_kpi: bool = False):
64
66
  """Initialize the visualizer classes that are not time-dependent."""
65
67
  self._meridian = meridian
66
- self._use_kpi = analyzer.Analyzer(meridian)._use_kpi(use_kpi)
68
+ self._use_kpi = analyzer.Analyzer(
69
+ model_context=meridian.model_context,
70
+ inference_data=meridian.inference_data,
71
+ )._use_kpi(use_kpi)
67
72
 
68
73
  @functools.cached_property
69
74
  def _model_fit(self):