Skip to content

Commit

Permalink
Make compute_incremental_outcome_aggregate public.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 721507893
  • Loading branch information
viktoriias authored and The Meridian Authors committed Jan 30, 2025
1 parent 5b8d3c4 commit 8f1b9cc
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ To release a new version (e.g. from `1.0.0` -> `2.0.0`):

## [Unreleased]

* Make `compute_incremental_outcome_aggregate` public.
* Add `new_data` argument to `Analyzer.summary_metrics` method.
* Add `use_kpi` argument to the `optimize()` method.

Expand Down
55 changes: 47 additions & 8 deletions meridian/analysis/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2735,24 +2735,63 @@ def _calculate_baseline_expected_outcome(
)
return self.expected_outcome(new_data=new_data, **expected_outcome_kwargs)

def _compute_incremental_outcome_aggregate(
def compute_incremental_outcome_aggregate(
self,
use_posterior: bool,
new_data: DataTensors | None = None,
use_kpi: bool | None = None,
include_non_paid_channels: bool = True,
non_media_baseline_values: Sequence[str | float] | None = None,
**roi_kwargs,
**kwargs,
):
"""Aggregates incremental outcomes for MediaSummary metrics."""
"""Aggregates the incremental outcome of the media channels.
Args:
use_posterior: Boolean. If `True` then the posterior distribution is
calculated. Otherwise, the prior distribution is calculated.
new_data: Optional `DataTensors` object with optional new tensors:
`media`, `reach`, `frequency`, `organic_media`, `organic_reach`,
`organic_frequency`, `non_media_treatments`, `controls`,
`revenue_per_kpi`. If provided, the summary metrics are calculated using
the values of the tensors passed in `new_data` and the original values
of all the remaining tensors. The new tensors' dimensions must match the
dimensions of the corresponding original tensors from
`meridian.input_data`. If `None`, the summary metrics are calculated
using the original values of all the tensors.
use_kpi: Boolean. If `True`, the summary metrics are calculated using KPI.
If `False`, the metrics are calculated using revenue.
include_non_paid_channels: Boolean. If `True`, non-paid channels (organic
media, organic reach and frequency, and non-media treatments) are
included in the summary but only the metrics independent of spend are
reported. If `False`, only the paid channels (media, reach and
frequency) are included but the summary contains also the metrics
dependent on spend. Default: `False`.
non_media_baseline_values: Optional list of shape (n_non_media_channels,).
Each element is either a float (which means that the fixed value will be
used as baseline for the given channel) or one of the strings "min" or
"max" (which mean that the global minimum or maximum value will be used
as baseline for the values of the given non_media treatment channel). If
None, the minimum value is used as baseline for each non_media treatment
channel.
**kwargs: kwargs to pass to `incremental_outcome`, which could contain
selected_geos, selected_times, aggregate_geos, aggregate_times,
batch_size.
Returns:
A tensor with the shape `(n_selected_geos, n_selected_times, n_channels,
2)` (or `(n_channels, 2)` if geos and times are aggregated) with
incremental outcome per channel. The last dimension corresponds to the
incremental outcome of the individual channel and the total incremental
outcome of all channels.
"""
use_kpi = use_kpi or self._meridian.input_data.revenue_per_kpi is None
incremental_outcome_m = self.incremental_outcome(
use_posterior=use_posterior,
new_data=new_data,
use_kpi=use_kpi,
include_non_paid_channels=include_non_paid_channels,
non_media_baseline_values=non_media_baseline_values,
**roi_kwargs,
**kwargs,
)
incremental_outcome_total = tf.reduce_sum(
incremental_outcome_m, axis=-1, keepdims=True
Expand Down Expand Up @@ -2882,15 +2921,15 @@ def summary_metrics(
axis=-1,
)

incremental_outcome_prior = self._compute_incremental_outcome_aggregate(
incremental_outcome_prior = self.compute_incremental_outcome_aggregate(
use_posterior=False,
new_data=new_data,
use_kpi=use_kpi,
include_non_paid_channels=include_non_paid_channels,
**dim_kwargs,
**batched_kwargs,
)
incremental_outcome_posterior = self._compute_incremental_outcome_aggregate(
incremental_outcome_posterior = self.compute_incremental_outcome_aggregate(
use_posterior=True,
new_data=new_data,
use_kpi=use_kpi,
Expand Down Expand Up @@ -3084,15 +3123,15 @@ def summary_metrics(
# have much practical usefulness, anyway.
).where(lambda ds: ds.channel != constants.ALL_CHANNELS)
cpik = self._compute_cpik_aggregate(
incremental_kpi_prior=self._compute_incremental_outcome_aggregate(
incremental_kpi_prior=self.compute_incremental_outcome_aggregate(
use_posterior=False,
new_data=new_data,
use_kpi=True,
include_non_paid_channels=False,
**dim_kwargs,
**batched_kwargs,
),
incremental_kpi_posterior=self._compute_incremental_outcome_aggregate(
incremental_kpi_posterior=self.compute_incremental_outcome_aggregate(
use_posterior=True,
new_data=new_data,
use_kpi=True,
Expand Down

0 comments on commit 8f1b9cc

Please sign in to comment.