google-meridian 1.2.0__py3-none-any.whl → 1.2.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.
- {google_meridian-1.2.0.dist-info → google_meridian-1.2.1.dist-info}/METADATA +2 -2
- {google_meridian-1.2.0.dist-info → google_meridian-1.2.1.dist-info}/RECORD +24 -24
- meridian/analysis/analyzer.py +101 -37
- meridian/analysis/optimizer.py +132 -88
- meridian/analysis/summarizer.py +31 -16
- meridian/analysis/visualizer.py +16 -5
- meridian/backend/__init__.py +475 -14
- meridian/backend/config.py +75 -16
- meridian/backend/test_utils.py +87 -1
- meridian/constants.py +14 -9
- meridian/data/input_data.py +7 -2
- meridian/data/test_utils.py +5 -3
- meridian/mlflow/autolog.py +2 -2
- meridian/model/adstock_hill.py +10 -9
- meridian/model/eda/eda_engine.py +440 -11
- meridian/model/knots.py +1 -1
- meridian/model/model_test_data.py +15 -9
- meridian/model/posterior_sampler.py +365 -365
- meridian/model/prior_distribution.py +104 -39
- meridian/model/transformers.py +5 -5
- meridian/version.py +1 -1
- {google_meridian-1.2.0.dist-info → google_meridian-1.2.1.dist-info}/WHEEL +0 -0
- {google_meridian-1.2.0.dist-info → google_meridian-1.2.1.dist-info}/licenses/LICENSE +0 -0
- {google_meridian-1.2.0.dist-info → google_meridian-1.2.1.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: google-meridian
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: Google's open source mixed marketing model library, helps you understand your return on investment and direct your ad spend with confidence.
|
|
5
5
|
Author-email: The Meridian Authors <no-reply@google.com>
|
|
6
6
|
License:
|
|
@@ -403,7 +403,7 @@ To cite this repository:
|
|
|
403
403
|
author = {Google Meridian Marketing Mix Modeling Team},
|
|
404
404
|
title = {Meridian: Marketing Mix Modeling},
|
|
405
405
|
url = {https://github.com/google/meridian},
|
|
406
|
-
version = {1.2.
|
|
406
|
+
version = {1.2.1},
|
|
407
407
|
year = {2025},
|
|
408
408
|
}
|
|
409
409
|
```
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
google_meridian-1.2.
|
|
1
|
+
google_meridian-1.2.1.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
|
2
2
|
meridian/__init__.py,sha256=0fOT5oNZF7-pbiWWGUefV-ysafttieG079m1ijMFQO8,861
|
|
3
|
-
meridian/constants.py,sha256=
|
|
4
|
-
meridian/version.py,sha256=
|
|
3
|
+
meridian/constants.py,sha256=19A4Hzhfdrdj6CzjoqKxqTg3d3wbTGHgvz9TBwdIRZg,18485
|
|
4
|
+
meridian/version.py,sha256=2wFL4gzqzx21aqU1XHRxIuP5xZOZFXVxiDQUG5v38do,644
|
|
5
5
|
meridian/analysis/__init__.py,sha256=nGBYz7k9FVdadO_WVGMKJcfq7Yy_TuuP8zgee4i9pSA,836
|
|
6
|
-
meridian/analysis/analyzer.py,sha256=
|
|
6
|
+
meridian/analysis/analyzer.py,sha256=ftcjavIPKy1y0uL_uEKfFaSYnWdQYMc8YBnw8p7mf6g,217876
|
|
7
7
|
meridian/analysis/formatter.py,sha256=ENIdR1CRiaVqIGEXx1HcnsA4ewgDD_nhsYCweJAThaw,7270
|
|
8
|
-
meridian/analysis/optimizer.py,sha256=
|
|
9
|
-
meridian/analysis/summarizer.py,sha256=
|
|
8
|
+
meridian/analysis/optimizer.py,sha256=4LhEbPBz8NtWWzwLuYiAhkuTiLfIJbhhdBPn973EVeQ,120492
|
|
9
|
+
meridian/analysis/summarizer.py,sha256=VF4uuZ5xavrfZdLk1Cwf1ZPrkiQ2-kVnLkjvpWtcZ98,19367
|
|
10
10
|
meridian/analysis/summary_text.py,sha256=I_smDkZJYp2j77ea-9AIbgeraDa7-qUYyb-IthP2qO4,12438
|
|
11
11
|
meridian/analysis/test_utils.py,sha256=z5NBjcOzvM7xwwTFI_26sfLyyGLYCd21j52eygQHBRs,77911
|
|
12
|
-
meridian/analysis/visualizer.py,sha256=
|
|
12
|
+
meridian/analysis/visualizer.py,sha256=RgrqIBRFG_HJBlz_IcOVaB3jSeXpD5PHLSkkGy2rWJs,94537
|
|
13
13
|
meridian/analysis/templates/card.html.jinja,sha256=pv4MVbQ25CcvtZY-LH7bFW0OSeHobkeEkAleB1sfQ14,1284
|
|
14
14
|
meridian/analysis/templates/chart.html.jinja,sha256=87i0xnXHRBoLLxBpKv2i960TLToWq4r1aVQZqaXIeMQ,1086
|
|
15
15
|
meridian/analysis/templates/chips.html.jinja,sha256=Az0tQwF_-b03JDLyOzpeH-8fb-6jgJgbNfnUUSm-q6E,645
|
|
@@ -19,34 +19,34 @@ meridian/analysis/templates/style.css,sha256=RODTWc2pXcG9zW3q9SEJpVXgeD-WwQgzLpm
|
|
|
19
19
|
meridian/analysis/templates/style.scss,sha256=nSrZOpcIrVyiL4eC9jLUlxIZtAKZ0Rt8pwfk4H1nMrs,5076
|
|
20
20
|
meridian/analysis/templates/summary.html.jinja,sha256=LuENVDHYIpNo4pzloYaCR2K9XN1Ow6_9oQOcOwD9nGg,1707
|
|
21
21
|
meridian/analysis/templates/table.html.jinja,sha256=mvLMZx92RcD2JAS2w2eZtfYG-6WdfwYVo7pM8TbHp4g,1176
|
|
22
|
-
meridian/backend/__init__.py,sha256=
|
|
23
|
-
meridian/backend/config.py,sha256=
|
|
24
|
-
meridian/backend/test_utils.py,sha256=
|
|
22
|
+
meridian/backend/__init__.py,sha256=9DCcwp-9hIr66vciMhdkROndO40AAlJXjtrAbFihero,28454
|
|
23
|
+
meridian/backend/config.py,sha256=B9VQnhBfg9RW04GNbt7F5uCugByenoJzt-keFLLYEp8,3561
|
|
24
|
+
meridian/backend/test_utils.py,sha256=jmlFdo3mQrDG-gmxd8GqYAhi_GdAXRUjRkHxRY0z_1A,6410
|
|
25
25
|
meridian/data/__init__.py,sha256=StIe-wfYnnbfUbKtZHwnAQcRQUS8XCZk_PCaEzw90Ww,929
|
|
26
26
|
meridian/data/arg_builder.py,sha256=Kqlt88bOqFj6D3xNwvWo4MBwNwcDFHzd-wMfEOmLoPU,3741
|
|
27
27
|
meridian/data/data_frame_input_data_builder.py,sha256=_hexZMFAuAowgo6FaOGElHSFHqhGnHQwEEBcwnT3zUE,27295
|
|
28
|
-
meridian/data/input_data.py,sha256=
|
|
28
|
+
meridian/data/input_data.py,sha256=Qlxm4El6h1SRPsWDqZoKkOcMtrjiRWr3z8sU2mtghRA,43151
|
|
29
29
|
meridian/data/input_data_builder.py,sha256=tbZjVXPDfmtndVyJA0fmzGzZwZb0RCEjXOTXb-ga8Nc,25648
|
|
30
30
|
meridian/data/load.py,sha256=X2nmYCC-7A0RUgmdolTqCt0TD3NEZabQ5oGv-TugE00,40129
|
|
31
31
|
meridian/data/nd_array_input_data_builder.py,sha256=lfpmnENGuSGKyUd7bDGAwoLqHqteOKmHdKl0VI2wCQA,16341
|
|
32
|
-
meridian/data/test_utils.py,sha256
|
|
32
|
+
meridian/data/test_utils.py,sha256=mw-QPTP15oXf32I7cxMe8iSFBLB3seqEiITZMTz_Eg8,59838
|
|
33
33
|
meridian/data/time_coordinates.py,sha256=C5A5fscSLjPH6G9YT8OspgIlCrkMY7y8dMFEt3tNSnE,9874
|
|
34
34
|
meridian/mlflow/__init__.py,sha256=elwXUqPQYi7VF9PYjelU1tydfcUrmtuoq6eJCOnV9bk,693
|
|
35
|
-
meridian/mlflow/autolog.py,sha256=
|
|
35
|
+
meridian/mlflow/autolog.py,sha256=SZsrynLjozcyrAFCNWiqchSa2yOszVnwFBGz23BmWUU,6379
|
|
36
36
|
meridian/model/__init__.py,sha256=9NFfqUE5WgFc-9lQMkbfkwwV-bQIz0tsQ_3Jyq0A4SU,982
|
|
37
|
-
meridian/model/adstock_hill.py,sha256=
|
|
38
|
-
meridian/model/knots.py,sha256=
|
|
37
|
+
meridian/model/adstock_hill.py,sha256=HoRKjyL03pCTBz6Utof9wEvlQCFM43BvrEW_oupj7NU,17688
|
|
38
|
+
meridian/model/knots.py,sha256=1geYCcWHjXy1Uzwi5bxIuHaIY2rfSYVfneEdPetcMA8,25978
|
|
39
39
|
meridian/model/media.py,sha256=ZWYLN2iHLYWYrSRyR03L8DgFdVtgRs37JfTVjbzynBU,14364
|
|
40
40
|
meridian/model/model.py,sha256=D6pQOD0A7ZE7MhDd2tLMSB7sVmDwyzJ82DuKaF_auVs,66516
|
|
41
|
-
meridian/model/model_test_data.py,sha256=
|
|
42
|
-
meridian/model/posterior_sampler.py,sha256=
|
|
43
|
-
meridian/model/prior_distribution.py,sha256=
|
|
41
|
+
meridian/model/model_test_data.py,sha256=cG_8vBMRJJ3O63uVDz4x1tdJRaVQXsYQtQvfScBoXV4,21878
|
|
42
|
+
meridian/model/posterior_sampler.py,sha256=xFnvRw-Arz8j6a2oj5ywOCN1r5JcbZRADBWOrdVPFE8,26910
|
|
43
|
+
meridian/model/prior_distribution.py,sha256=xHNysn9sGjQL4xUOyoeMbTJwYyCmTbXykvEA9rNkkXY,57081
|
|
44
44
|
meridian/model/prior_sampler.py,sha256=IKkVF-TUN3tFvnHKRrXI3A5slKq1vPcUn5e3u9UsfPU,23422
|
|
45
45
|
meridian/model/spec.py,sha256=6ioI_wU6E2c-i7oltJUjBYHb3FxhRCyhWtuCx8GqkFA,19206
|
|
46
|
-
meridian/model/transformers.py,sha256=
|
|
46
|
+
meridian/model/transformers.py,sha256=68pf6-6nG2eAgrE-ZM30S-cWCmNTftrRQZKjIoVHRO4,8230
|
|
47
47
|
meridian/model/eda/__init__.py,sha256=MrGW1NER0JNsnWJRO5aeFEmMTDVYi4HgMmLXZaw_bbk,685
|
|
48
|
-
meridian/model/eda/eda_engine.py,sha256=
|
|
49
|
-
google_meridian-1.2.
|
|
50
|
-
google_meridian-1.2.
|
|
51
|
-
google_meridian-1.2.
|
|
52
|
-
google_meridian-1.2.
|
|
48
|
+
meridian/model/eda/eda_engine.py,sha256=QjOFril0NTonBg9mqx6nrBUfK5F_A53UcX-l6QSqgo8,25462
|
|
49
|
+
google_meridian-1.2.1.dist-info/METADATA,sha256=zfGooQwkjN_mFUPDu7Y09SZ6euAEo_zaG4V_RAUt0T4,22462
|
|
50
|
+
google_meridian-1.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
51
|
+
google_meridian-1.2.1.dist-info/top_level.txt,sha256=nwaCebZvvU34EopTKZsjK0OMTFjVnkf4FfnBN_TAc0g,9
|
|
52
|
+
google_meridian-1.2.1.dist-info/RECORD,,
|
meridian/analysis/analyzer.py
CHANGED
|
@@ -675,43 +675,66 @@ def _validate_flexible_selected_times(
|
|
|
675
675
|
selected_times: Sequence[str] | Sequence[bool] | None,
|
|
676
676
|
media_selected_times: Sequence[str] | Sequence[bool] | None,
|
|
677
677
|
new_n_media_times: int,
|
|
678
|
+
new_time: Sequence[str] | None = None,
|
|
678
679
|
):
|
|
679
680
|
"""Raises an error if selected times or media selected times is invalid.
|
|
680
681
|
|
|
681
|
-
This checks that the `selected_times` and `media_selected_times` arguments
|
|
682
|
-
are lists of booleans with the same number of elements as `new_n_media_times
|
|
683
|
-
|
|
684
|
-
`
|
|
682
|
+
This checks that (1) the `selected_times` and `media_selected_times` arguments
|
|
683
|
+
are lists of booleans with the same number of elements as `new_n_media_times`,
|
|
684
|
+
or (2) the `selected_times` and `media_selected_times` arguments are lists of
|
|
685
|
+
strings and the `new_time` list is provided and `selected_times` and
|
|
686
|
+
`media_selected_times` are subsets of `new_time`. This is only relevant if the
|
|
687
|
+
time dimension of any of the variables in `new_data` used in the analysis is
|
|
688
|
+
modified.
|
|
685
689
|
|
|
686
690
|
Args:
|
|
687
691
|
selected_times: Optional list of times to validate.
|
|
688
692
|
media_selected_times: Optional list of media times to validate.
|
|
689
693
|
new_n_media_times: The number of time periods in the new data.
|
|
694
|
+
new_time: The optional time dimension of the new data.
|
|
690
695
|
"""
|
|
691
696
|
if selected_times and (
|
|
692
|
-
not
|
|
693
|
-
|
|
697
|
+
not (
|
|
698
|
+
_is_bool_list(selected_times)
|
|
699
|
+
and len(selected_times) == new_n_media_times
|
|
700
|
+
)
|
|
701
|
+
and not (
|
|
702
|
+
_is_str_list(selected_times)
|
|
703
|
+
and new_time is not None
|
|
704
|
+
and set(selected_times) <= set(new_time)
|
|
705
|
+
)
|
|
694
706
|
):
|
|
695
707
|
raise ValueError(
|
|
696
708
|
"If `media`, `reach`, `frequency`, `organic_media`,"
|
|
697
709
|
" `organic_reach`, `organic_frequency`, `non_media_treatments`, or"
|
|
698
710
|
" `revenue_per_kpi` is provided with a different number of time"
|
|
699
|
-
" periods than in `InputData`, then `selected_times` must be a list"
|
|
711
|
+
" periods than in `InputData`, then (1) `selected_times` must be a list"
|
|
700
712
|
" of booleans with length equal to the number of time periods in"
|
|
701
|
-
" the new data
|
|
713
|
+
" the new data, or (2) `selected_times` must be a list of strings and"
|
|
714
|
+
" `new_time` must be provided and `selected_times` must be a subset of"
|
|
715
|
+
" `new_time`."
|
|
702
716
|
)
|
|
703
717
|
|
|
704
718
|
if media_selected_times and (
|
|
705
|
-
not
|
|
706
|
-
|
|
719
|
+
not (
|
|
720
|
+
_is_bool_list(media_selected_times)
|
|
721
|
+
and len(media_selected_times) == new_n_media_times
|
|
722
|
+
)
|
|
723
|
+
and not (
|
|
724
|
+
_is_str_list(media_selected_times)
|
|
725
|
+
and new_time is not None
|
|
726
|
+
and set(media_selected_times) <= set(new_time)
|
|
727
|
+
)
|
|
707
728
|
):
|
|
708
729
|
raise ValueError(
|
|
709
730
|
"If `media`, `reach`, `frequency`, `organic_media`,"
|
|
710
731
|
" `organic_reach`, `organic_frequency`, `non_media_treatments`, or"
|
|
711
732
|
" `revenue_per_kpi` is provided with a different number of time"
|
|
712
|
-
" periods than in `InputData`, then `media_selected_times` must be"
|
|
733
|
+
" periods than in `InputData`, then (1) `media_selected_times` must be"
|
|
713
734
|
" a list of booleans with length equal to the number of time"
|
|
714
|
-
" periods in the new data
|
|
735
|
+
" periods in the new data, or (2) `media_selected_times` must be a list"
|
|
736
|
+
" of strings and `new_time` must be provided and"
|
|
737
|
+
" `media_selected_times` must be a subset of `new_time`."
|
|
715
738
|
)
|
|
716
739
|
|
|
717
740
|
|
|
@@ -4056,6 +4079,7 @@ class Analyzer:
|
|
|
4056
4079
|
|
|
4057
4080
|
def response_curves(
|
|
4058
4081
|
self,
|
|
4082
|
+
new_data: DataTensors | None = None,
|
|
4059
4083
|
spend_multipliers: list[float] | None = None,
|
|
4060
4084
|
use_posterior: bool = True,
|
|
4061
4085
|
selected_geos: Sequence[str] | None = None,
|
|
@@ -4081,6 +4105,15 @@ class Analyzer:
|
|
|
4081
4105
|
`selected_times` are also scaled by the multiplier.)
|
|
4082
4106
|
|
|
4083
4107
|
Args:
|
|
4108
|
+
new_data: Optional `DataTensors` object with optional new tensors:
|
|
4109
|
+
`media`, `reach`, `frequency`, `media_spend`, `rf_spend`,
|
|
4110
|
+
`revenue_per_kpi`, `times`. If provided, the response curves are
|
|
4111
|
+
calculated using the values of the tensors passed in `new_data` and the
|
|
4112
|
+
original values of all the remaining tensors. If `None`, the response
|
|
4113
|
+
curves are calculated using the original values of all the tensors. If
|
|
4114
|
+
any of the tensors in `new_data` is provided with a different number of
|
|
4115
|
+
time periods than in `InputData`, then all tensors must be provided with
|
|
4116
|
+
the same number of time periods and the `time` tensor must be provided.
|
|
4084
4117
|
spend_multipliers: List of multipliers. Each channel's total spend is
|
|
4085
4118
|
multiplied by these factors to obtain the values at which the curve is
|
|
4086
4119
|
calculated for that channel.
|
|
@@ -4088,8 +4121,11 @@ class Analyzer:
|
|
|
4088
4121
|
generated. If `False`, prior response curves are generated.
|
|
4089
4122
|
selected_geos: Optional list containing a subset of geos to include. By
|
|
4090
4123
|
default, all geos are included.
|
|
4091
|
-
selected_times: Optional list containing a subset of dates to include.
|
|
4092
|
-
|
|
4124
|
+
selected_times: Optional list containing a subset of dates to include. If
|
|
4125
|
+
`new_data` is provided with modified time periods, then `selected_times`
|
|
4126
|
+
must be a subset of `new_data.times`. Otherwise, `selected_times` must
|
|
4127
|
+
be a subset of `self._meridian.input_data.time`. By default, all time
|
|
4128
|
+
periods are included.
|
|
4093
4129
|
by_reach: Boolean. For channels with reach and frequency. If `True`, plots
|
|
4094
4130
|
the response curve by reach. If `False`, plots the response curve by
|
|
4095
4131
|
frequency.
|
|
@@ -4118,11 +4154,49 @@ class Analyzer:
|
|
|
4118
4154
|
"aggregate_geos": True,
|
|
4119
4155
|
"aggregate_times": True,
|
|
4120
4156
|
}
|
|
4157
|
+
if new_data is None:
|
|
4158
|
+
new_data = DataTensors()
|
|
4159
|
+
# TODO: b/442920356 - Support flexible time without providing exact dates.
|
|
4160
|
+
required_tensors_names = constants.PERFORMANCE_DATA + (constants.TIME,)
|
|
4161
|
+
filled_data = new_data.validate_and_fill_missing_data(
|
|
4162
|
+
required_tensors_names=required_tensors_names,
|
|
4163
|
+
meridian=self._meridian,
|
|
4164
|
+
allow_modified_times=True,
|
|
4165
|
+
)
|
|
4166
|
+
new_n_media_times = filled_data.get_modified_times(self._meridian)
|
|
4167
|
+
|
|
4168
|
+
if new_n_media_times is None:
|
|
4169
|
+
_validate_selected_times(
|
|
4170
|
+
selected_times=selected_times,
|
|
4171
|
+
input_times=self._meridian.input_data.time,
|
|
4172
|
+
n_times=self._meridian.n_times,
|
|
4173
|
+
arg_name="selected_times",
|
|
4174
|
+
comparison_arg_name="the input data",
|
|
4175
|
+
)
|
|
4176
|
+
else:
|
|
4177
|
+
new_time = np.asarray(filled_data.time).astype(str).tolist()
|
|
4178
|
+
_validate_flexible_selected_times(
|
|
4179
|
+
selected_times=selected_times,
|
|
4180
|
+
media_selected_times=None,
|
|
4181
|
+
new_n_media_times=new_n_media_times,
|
|
4182
|
+
new_time=new_time,
|
|
4183
|
+
)
|
|
4184
|
+
# TODO: b/407847021 - Switch to Sequence[str] once it is supported.
|
|
4185
|
+
if selected_times is not None:
|
|
4186
|
+
selected_times = [x in selected_times for x in new_time]
|
|
4187
|
+
dim_kwargs["selected_times"] = selected_times
|
|
4188
|
+
|
|
4121
4189
|
if self._meridian.n_rf_channels > 0 and use_optimal_frequency:
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4190
|
+
opt_freq_data = DataTensors(
|
|
4191
|
+
media=filled_data.media,
|
|
4192
|
+
rf_impressions=filled_data.reach * filled_data.frequency,
|
|
4193
|
+
media_spend=filled_data.media_spend,
|
|
4194
|
+
rf_spend=filled_data.rf_spend,
|
|
4195
|
+
revenue_per_kpi=filled_data.revenue_per_kpi,
|
|
4196
|
+
)
|
|
4197
|
+
frequency = backend.ones_like(filled_data.frequency) * backend.to_tensor(
|
|
4125
4198
|
self.optimal_freq(
|
|
4199
|
+
new_data=opt_freq_data,
|
|
4126
4200
|
selected_geos=selected_geos,
|
|
4127
4201
|
selected_times=selected_times,
|
|
4128
4202
|
use_kpi=use_kpi,
|
|
@@ -4130,12 +4204,12 @@ class Analyzer:
|
|
|
4130
4204
|
dtype=backend.float32,
|
|
4131
4205
|
)
|
|
4132
4206
|
reach = backend.divide_no_nan(
|
|
4133
|
-
|
|
4207
|
+
filled_data.reach * filled_data.frequency,
|
|
4134
4208
|
frequency,
|
|
4135
4209
|
)
|
|
4136
4210
|
else:
|
|
4137
|
-
frequency =
|
|
4138
|
-
reach =
|
|
4211
|
+
frequency = filled_data.frequency
|
|
4212
|
+
reach = filled_data.reach
|
|
4139
4213
|
if spend_multipliers is None:
|
|
4140
4214
|
spend_multipliers = list(np.arange(0, 2.2, 0.2))
|
|
4141
4215
|
incremental_outcome = np.zeros((
|
|
@@ -4149,18 +4223,19 @@ class Analyzer:
|
|
|
4149
4223
|
(len(self._meridian.input_data.get_all_paid_channels()), 3)
|
|
4150
4224
|
) # Last dimension = 3 for the mean, ci_lo and ci_hi.
|
|
4151
4225
|
continue
|
|
4152
|
-
|
|
4226
|
+
scaled_data = _scale_tensors_by_multiplier(
|
|
4153
4227
|
data=DataTensors(
|
|
4154
|
-
media=
|
|
4228
|
+
media=filled_data.media,
|
|
4155
4229
|
reach=reach,
|
|
4156
4230
|
frequency=frequency,
|
|
4231
|
+
revenue_per_kpi=filled_data.revenue_per_kpi,
|
|
4157
4232
|
),
|
|
4158
4233
|
multiplier=multiplier,
|
|
4159
4234
|
by_reach=by_reach,
|
|
4160
4235
|
)
|
|
4161
4236
|
inc_outcome_temp = self.incremental_outcome(
|
|
4162
4237
|
use_posterior=use_posterior,
|
|
4163
|
-
new_data=
|
|
4238
|
+
new_data=scaled_data.filter_fields(constants.PAID_DATA),
|
|
4164
4239
|
inverse_transform_outcome=True,
|
|
4165
4240
|
batch_size=batch_size,
|
|
4166
4241
|
use_kpi=use_kpi,
|
|
@@ -4171,22 +4246,11 @@ class Analyzer:
|
|
|
4171
4246
|
inc_outcome_temp, confidence_level
|
|
4172
4247
|
)
|
|
4173
4248
|
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
[
|
|
4177
|
-
self._meridian.media_tensors.media_spend,
|
|
4178
|
-
self._meridian.rf_tensors.rf_spend,
|
|
4179
|
-
],
|
|
4180
|
-
axis=-1,
|
|
4181
|
-
)
|
|
4182
|
-
elif self._meridian.n_media_channels > 0:
|
|
4183
|
-
spend = self._meridian.media_tensors.media_spend
|
|
4184
|
-
else:
|
|
4185
|
-
spend = self._meridian.rf_tensors.rf_spend
|
|
4186
|
-
|
|
4187
|
-
if backend.rank(spend) == 3:
|
|
4249
|
+
spend = filled_data.total_spend()
|
|
4250
|
+
if spend is not None and spend.ndim == 3:
|
|
4188
4251
|
spend = self.filter_and_aggregate_geos_and_times(
|
|
4189
4252
|
tensor=spend,
|
|
4253
|
+
flexible_time_dim=True,
|
|
4190
4254
|
**dim_kwargs,
|
|
4191
4255
|
)
|
|
4192
4256
|
spend_einsum = backend.einsum("k,m->km", np.array(spend_multipliers), spend)
|