Articles

    Marketing Mix Modeling Data Readiness: A Preflight Assessment

    Published
    9 min read
    By Kasper Brindovik
    Updated

    A clean extract can still be useless for MMM. Before anyone argues about adstock curves or priors, someone has to answer a duller question: did the business ever move its budget in ways a model could learn from? Many marketing mix modeling projects that disappoint fail right there, weeks before the first coefficient appears. Nothing in the extract itself warns you.

    What a readiness preflight actually tests

    The fastest way to waste an MMM project is to treat a clean spreadsheet as proof that data can answer a budget question. A file may contain two years of revenue, media spend, and campaign names yet provide no credible signal about a channel’s incremental effect.

    A marketing mix modeling data readiness assessment asks before fitting: does available history contain enough consistent, decision-relevant variation to support expected decisions? The dashboard, the vendor, and the statistical method are questions for later.

    Instead of asking whether platforms can export data, ask whether paid social changed independently enough from search, whether revenue survived a tracking migration, and whether regional cuts reflect real market differences or just the way each region reports. The output is a documented go, conditional go, or no-go decision with named repair work.

    MMM learns from budget movement

    MMM estimates how an outcome moved alongside media and non-media drivers over time or geographies. It needs periods in which plausible causes move differently. A channel with the same weekly budget throughout the window contributes a total-spend figure but little evidence about how budget changes relate to the outcome.

    The relevant unit is the analysis grain: the row at which observations are compared. A national weekly model has one row per week; a weekly geographic model has one row per week and market. Grain should follow the planning decision. If a team reallocates monthly budgets by country, national daily data can create false volume through calendar noise, missing-market rows, and long zero-spend runs. If local teams set market budgets, national totals can erase needed variation.

    Time span and row count are not interchangeable. Seven hundred daily rows cover about a hundred weeks, and they can hold fewer meaningful marketing decisions than one hundred weekly observations. Daily observations share serial dependence: Tuesday is not independent from Monday. Conversely, splitting a modest national budget across twenty regions can make every regional channel series sparse. Granularity helps only when reporting definitions, outcome capture, and media delivery remain comparable at that level.

    Start with one written decision statement: “We need to estimate the likely effect of shifting budget between these named channels, at this cadence, for these markets, against this outcome.” Requirements follow from it. Without it, teams collect every metric and miss fields needed to judge whether the design can work.

    Complete tables can still hide weak evidence

    Missing values are obvious; more damaging failures can look complete because every week has a number.

    Insufficient variation. A brand that held paid search near the same weekly spend throughout its history, adjusting it only during two holiday weeks, gives a model little basis to separate channel effect from baseline demand trend. A coefficient may appear in fitted output, but that does not make it decision-ready. Rather than add an elaborate algorithm, extend history, combine the channel with a related tactic when the decision is combined, or create measured future variation through planned budget changes.

    Structural breaks. Suppose an outcome changes from gross checkout value to net recognized revenue after a finance-system migration. The column remains revenue, passing a completeness check, while the shift may be mistaken for media effect, seasonality, or baseline-demand change. The same issue arises when an ad platform changes attribution settings, an agency switches from net to gross media cost, product price changes, or a major distribution partner enters a market. A preflight needs a dated change log with old and new definitions, affected markets, and whether history was restated. A blank log does not prove continuity; it shows continuity was not verified.

    Sparse channels. An affiliate program spending in six isolated weeks, with zeros through the rest of two years, is not equivalent to an always-on channel with the same cumulative spend. Activity may coincide with promotions, launches, or commercial events that affect sales. Exclude it from first scope, group it with genuinely similar activity, or track it longer. A separate column does not mean separately estimable evidence.

    A fourth pattern is channels that always move together. If brand video, paid social, and influencer activity launch and pause as one integrated burst, time-series movement cannot cleanly separate them. A combined “brand campaign” decision can be a legitimate modeling unit; claiming to rank each tactic independently is sharper than the design warrants.

    Audit the planned grain before fitting

    The most useful audit is reproducible. Put required grain, source tables, thresholds, and pass logic under version control, and rerun it whenever an extract changes. A manually colored spreadsheet cannot reliably reveal a late market, duplicated load, or channel-taxonomy change.

    The PostgreSQL template assumes prepared tables: outcomes(week_start, geo, outcome_value), media(week_start, geo, channel, spend, exposure), and planned_channels(geo, channel). It returns every passed or failed mechanical check. The settings are triage defaults for a 104-week weekly study; change them for decision cadence, markets, and scope.

    WITH settings AS (
      SELECT DATE '2024-01-01' AS start_week,
             DATE '2025-12-22' AS end_week,
             26::int AS min_active_weeks,
             0.70::numeric AS max_zero_or_missing_share,
             0.15::numeric AS min_spend_cv
    ), calendar AS (
      SELECT pc.geo, d::date AS week_start
      FROM (SELECT DISTINCT geo FROM planned_channels) pc
      CROSS JOIN settings s
      CROSS JOIN LATERAL generate_series(s.start_week, s.end_week, interval '7 days') d
    ), outcome_gaps AS (
      SELECT c.geo, count(*) FILTER (WHERE o.outcome_value IS NULL)::numeric AS observed
      FROM calendar c LEFT JOIN outcomes o USING (week_start, geo)
      GROUP BY c.geo
    ), media_grid AS (
      SELECT c.week_start, c.geo, pc.channel, m.spend, m.exposure
      FROM calendar c JOIN planned_channels pc USING (geo)
      LEFT JOIN media m ON m.week_start = c.week_start
                       AND m.geo = c.geo AND m.channel = pc.channel
    ), channel_stats AS (
      SELECT geo, channel,
             count(*) FILTER (WHERE spend > 0)::numeric AS active_weeks,
             avg(CASE WHEN coalesce(spend, 0) = 0 THEN 1.0 ELSE 0.0 END) AS zero_or_missing_share,
             stddev_samp(spend) / nullif(avg(spend), 0) AS spend_cv,
             count(*) FILTER (WHERE exposure IS NULL)::numeric AS missing_exposure_rows
      FROM media_grid GROUP BY geo, channel
    ), duplicate_keys AS (
      SELECT (count(*) - count(DISTINCT (week_start, geo, channel)))::numeric AS observed
      FROM media
    )
    SELECT 'outcome_missing_weeks' AS check_id, geo AS scope, observed, 0::numeric AS threshold,
           observed = 0 AS pass
    FROM outcome_gaps
    UNION ALL
    SELECT 'active_weeks', geo || '/' || channel, active_weeks, s.min_active_weeks,
           active_weeks >= s.min_active_weeks
    FROM channel_stats CROSS JOIN settings s
    UNION ALL
    SELECT 'zero_or_missing_share', geo || '/' || channel, zero_or_missing_share,
           s.max_zero_or_missing_share, zero_or_missing_share <= s.max_zero_or_missing_share
    FROM channel_stats CROSS JOIN settings s
    UNION ALL
    SELECT 'spend_coefficient_of_variation', geo || '/' || channel, coalesce(spend_cv, 0),
           s.min_spend_cv, coalesce(spend_cv, 0) >= s.min_spend_cv
    FROM channel_stats CROSS JOIN settings s
    UNION ALL
    SELECT 'duplicate_media_keys', 'all_rows', observed, 0::numeric, observed = 0
    FROM duplicate_keys;
    

    The coefficient of variation is standard deviation of spend / average spend: a compact flag for a nearly flat series and nothing more. A passing value can still mislead. Say a paid search line ran at $40,000 a week for 100 of 104 weeks and at $90,000 in four holiday weeks. The mean is about $41,900, the standard deviation about $9,700, so the CV comes out near 0.23 and clears the 0.15 setting. Yet almost all of that movement sits in the four weeks when demand peaked anyway. The flag passes; the evidence for a search effect does not.

    High variation can also come from one erroneous invoice, a currency-conversion fault, or a short promotion. So treat a striking spike as a data problem until someone shows otherwise: an invoice posted twice looks exactly like a bold budget test in a weekly series. Pair each flag with a chart of spend, exposure, and outcome at the planned grain.

    The audit cannot inspect business meaning. It will not know that “Meta prospecting” became “Paid social,” TV used estimated ratings for one quarter, or revenue excluded returns only after a date. Maintain a provenance register beside the query: source owner, extraction rule, currency, tax treatment, campaign taxonomy, known breaks, and restatement status. Mechanical checks catch shape; provenance checks catch meaning.

    Data sufficiency is not causal certainty

    Preflight results need three labels often collapsed into one verdict.

    Data sufficiency means records meet agreed design requirements: complete calendar, unique keys, variation, known channel coverage, and documented definition changes. The SQL audit addresses this layer. A conditional result identifies weakness without claiming a model will fail.

    Model validity is assessed after fitting and depends on choices beyond preflight: transformations for lagged and decaying media effects, baseline controls, prior assumptions where relevant, outlier treatment, residual diagnostics, and stability across sensible specifications. Sufficient data can still yield an invalid model if these choices are poor.

    Causal certainty is the strongest claim. It depends on assumptions about confounding, simultaneous budget decisions, measurement error, and unobserved demand shocks. If a company raises search spend whenever demand rises, historical correlation may overstate effect. Logged promotions, price, distribution, inventory constraints, competitor events, and planned experiments improve evidence, but none turns an extract into proof.

    Separating the layers prevents two opposite mistakes. One rejects usable data for failing to deliver a certainty no observational model can promise. The other treats a model that ran as a model that proved something. For marketing leads who need to judge evidence themselves, a credible growth assessment framework offers a companion lens.

    Readiness bands turn findings into action

    A readiness assessment should end in an operational band; “data needs cleaning” gives nobody a task. The band specifies the next work item and its owner.

    Readiness band Evidence state Action before fitting
    Blocked Outcome definitions are unresolved, required rows absent, keys duplicate, or planned grain cannot be reconstructed. Rebuild the extract, reconcile definitions, or reduce the decision question. Do not fit a model to create a deadline artifact.
    Conditional Core outcome and media data are usable, but sparse channels, weak variation, missing controls, or documented breaks limit first scope. Freeze limits in writing, extend history where possible, combine only decision-aligned channels, and prepare a break register.
    Ready for model evaluation The data contract passes, provenance is signed off, material breaks are represented, and selected channels have meaningful movement at chosen grain. Lock the input version and proceed to specification and diagnostic review. This is not a causal guarantee.

    No score overrides written rationale. A national series may be ready while market-level cuts are blocked; paid search may be ready while affiliate is too sparse. Report readiness by decision scope, outcome, geography, and channel group; a single grade for “the data” hides exactly these splits.

    Scale changes the failure mode

    As MMM expands across markets, brands, currencies, agencies, and product lines, risk shifts from an obvious missing column to silent inconsistency. One market may report local-currency media and another billing currency; one team may tag brand search by campaign objective and another by keyword intent; one revenue series may use order date and another shipment date. Each can be locally defensible while making cross-market comparison unreliable.

    The remedy is a data contract jointly owned by marketing operations, finance, analytics, and source-system teams. Define a canonical week boundary, outcome timing, currency-conversion rule, gross or net spend treatment, channel taxonomy, restatement policy, and change-recording procedure. Analysts cannot infer a finance definition from a label, and marketers cannot repair an API backfill afterward.

    Do not expand scope because volume increased. Expand when each market or channel preserves decision meaning and has enough variation for its own estimate. A smaller documented scope is more useful than a global model smoothing incompatible inputs into one answer.

    A go/no-go review needs plain language

    The decision memo should be brief enough for a budget meeting and specific enough to reproduce. Example conditional-go statement:

    Decision: Conditional go for national weekly revenue and four always-on media groups. The 104-week outcome calendar is complete and media keys are unique. Search, paid social, display, and television meet the chosen activity and variation flags. Affiliate activity appears in isolated promotional weeks, so it will not receive a standalone estimate. Revenue changed from gross checkout value to net revenue in week 61; finance has supplied a restated historical series, pending a spot check against the ledger. Price changes and stock-out periods are available as dated controls. The first model must not claim channel-level findings for affiliate or causal certainty for search during demand-led budget changes. Owner: marketing analytics. Finance sign-off due before input lock.

    The memo records the decision boundary: what the project can answer, cannot yet answer, and which unresolved item changes go/no-go status. It also lets future reviewers understand why scope was chosen.

    Build the evidence before the model

    An MMM preflight is a design review disguised as a data audit. Its job is to stop teams from asking a model to distinguish effects that operating history never separated.

    Run the mechanical audit, inspect flagged series, reconcile definitions with source owners, and write the decision memo before fitting. A conditional or blocked result still earns its keep, because it names the next data-collection period, taxonomy repair, or measurement design. Each of those outcomes points to the same fix: a channel whose budget never moved apart from demand cannot be measured until someone moves it on purpose.

    Related Articles