Retail and consumer goodsBI, AI and ML for the business
Campaigns measured against the baseline
During a campaign sales go up, but part of that would have come anyway. In Muvia a Python function compares orders and revenue hour by hour with a typical week without campaigns, and every channel shows its net effect and when it pays back its spend.
Illustrative scenario: it describes a typical case, not a customer project.
Sales rise during the campaign. How much would they have risen anyway?
Every ad platform reports its own conversions, and adding them up gives more than revenue. Comparing with the week before does not help: there is the season, the August holidays, two campaigns overlapping. So the budget is split out of habit.
To know what a campaign brings you need a baseline: how much the store would have sold in those same hours without campaigns. Only the difference, net of spend and returns, says whether a channel pays back.
- Who it's for
- Marketing and sales management, e-commerce managers, management accounting.
In Muvia, step by step
Real product screens, recorded on a project with sample data.
The video · During a campaign sales go up, but part of that would have come anyway. In Muvia a Python function compares orders and revenue hour by hour with a typical week without campaigns, and every channel shows its net effect and when it pays back its spend.
What you get
- Net effect, not reported conversions
- Every campaign is measured against what the store would have sold anyway.
- Channels you can compare
- Email, social, search and TV sit on the same scale, aligned on the moment of launch.
- You know when spend pays back
- The hour-by-hour balance says whether and when a campaign pays back, returns included.
- The budget follows the numbers
- Every morning the balance updates, and the decision on what to cut starts from the same data for everyone.
For the technical team
How it is built in Muvia
- 1
Put spend and orders on the same hour
The sources bring spend per campaign, the store's orders and the calendar; a query aligns them hour by hour in a dataset.
- 2
Compute the baseline in Python
A Python function builds, for every hour, the typical week without campaigns from the clean hours, corrected for season and holidays. The gap between actual and expected is the campaign's effect; margin and return lag are parameters.
- 3
Schedule the recomputation
A flow runs it every morning and writes to managed tables the hour-by-hour effect and each campaign's balance: spend, extra orders, extra margin and days to pay back.
- 4
Align the campaigns in Analysis
The Layers view overlays the campaigns on their launch moment: you see which channel responds within hours and which stays flat. The balance since launch shows when each one pays back its spend.
- 5
Ask Athena what to cut
Athena reads the campaign balance, saves the ranking in the Lab and writes in a notebook which campaign to cut and which to double.
Python function
import numpy as np
import pandas as pd
def transform(inputs, params, ctx):
d = inputs["rows"].copy()
d["hour"] = pd.to_datetime(d["hour"], utc=True).dt.tz_convert("Europe/Rome")
d["hour_of_week"] = d["hour"].dt.weekday * 24 + d["hour"].dt.hour
clean = d["campaign"].isna()
# the typical week: the mean of each hour of the week over hours with no campaign
typical = d[clean].groupby("hour_of_week")["orders"].mean()
d["expected_orders"] = d["hour_of_week"].map(typical)
d["extra_orders"] = np.where(clean, 0.0, d["orders"] - d["expected_orders"])
basket = d["revenue"].sum() / d["orders"].sum()
margin = d["extra_orders"] * basket * params["gross_margin_pct"] / 100
d["campaign_balance"] = (margin - d["spend"]).groupby(d["campaign"]).cumsum()
columns = ["hour", "campaign", "orders", "expected_orders", "extra_orders", "campaign_balance"]
return {"rows": d[columns]}- The data it needs
- Hourly spend per campaign and channel (email, social, search, TV), read through a REST API
- Online store sessions, orders, revenue and returns, hour by hour, from the database on PostgreSQL
- Campaign calendar with channel, start and end, from Google Sheets
- Parts of Muvia used
More cases in this line
All use cases- Every store's sales on one pageTill sales, orders and store master data sit in different systems, and the picture of the network arrives after month end. In Muvia revenue, growth, units and customers for every store sit in one dashboard, week by week, from the grand total down to a single department.
- Bought together: market basket analysisReceipts show which products are bought together, but they stay in the till system. In Muvia a Python function computes the support, confidence and lift of every pair each night, and the dashboard says what to do with them: bundled promotions, neighbours on the shelf, suggestions at the till.
- Price elasticity and the price-list proposalA price rise can cost a third of the units or almost nothing, and you find out after the fact. In Muvia a model your team writes estimates every item's elasticity each week and prepares the price-list proposal: what to raise, what to cut and how much margin it brings.
Bring us a question you can't answer today.
We start from a real question your business has and walk the path from source to dashboard with your systems, not a demo dataset.