luvv to helpDiscover the Best Free Online Tools
Topic 1 of 8

Metric Decomposition

Learn Metric Decomposition for free with explanations, exercises, and a quick test (for Product Analyst).

Published: December 22, 2025 | Updated: December 22, 2025

Why this matters

Metric decomposition shows exactly why a KPI moved. As a Product Analyst, you will use it to:

  • Explain revenue swings as volume, price, and mix effects.
  • Break down conversion rate change into rate vs audience mix (segment/channel).
  • Attribute DAU/MAU growth to channels, geos, or product features.
  • Build clear waterfall charts for stakeholders and plan actions based on drivers.

Concept explained simply

Decomposition splits the change of a metric into additive contributions from drivers. Examples:

  • Revenue R = Σ(price × units). ΔR can be split into effects of units change, price change, and an interaction/mix remainder.
  • Conversion rate r = Σ(segment share × segment rate). Δr can be split into a rate effect and a mix effect using midpoint weights (Kitagawa/Das Gupta).
  • DAU = Σ(channel DAU). ΔDAU is the sum of per-channel changes.

Mental model

Hold one thing constant while changing another, then swap. Midpoint weights average both periods so the split is symmetric and fair. Always verify: sum of contributions equals total change.

Key terms
  • Additive change: Absolute difference (e.g., +2,300 DAU, +3.2 percentage points).
  • Rate vs percentage points: Rate changes should be expressed in percentage points to avoid confusion.
  • Mix/interaction: The part of change due to simultaneous shifts in multiple factors; keep it explicit or allocate proportionally.

Set up: sample data

Run these snippets to create small datasets for practice.

Python setup
import pandas as pd

# Transactions by week, product
sales = pd.DataFrame({
    'week': ['2024-01-07','2024-01-07','2024-01-14','2024-01-14'],
    'product': ['A','B','A','B'],
    'price': [10.0, 20.0, 11.0, 19.0],
    'units': [100, 50, 120, 45]
})

# Sessions and signups by segment for conversion
conv = pd.DataFrame({
    'period': ['P0','P0','P1','P1'],
    'segment': ['Web','App','Web','App'],
    'sessions': [8000, 2000, 7000, 4000],
    'signups':  [720,  260,  630,  520]
})

# DAU by channel
usage = pd.DataFrame({
    'date': ['2024-01-07','2024-01-07','2024-01-14','2024-01-14'],
    'channel': ['SEO','Paid','SEO','Paid'],
    'dau': [12000, 8000, 13500, 7600]
})

Worked examples

1) Revenue: price, volume, interaction

We’ll compare week 2024-01-07 (P0) to 2024-01-14 (P1). Revenue R = Σ p × q.

Code
p0 = sales[sales['week']=='2024-01-07'].groupby('product').agg(price0=('price','mean'), q0=('units','sum'))
p1 = sales[sales['week']=='2024-01-14'].groupby('product').agg(price1=('price','mean'), q1=('units','sum'))

m = p0.join(p1, how='outer').fillna(0)

m['R0'] = m['price0']*m['q0']
m['R1'] = m['price1']*m['q1']

dR_total = m['R1'].sum() - m['R0'].sum()

# Baseline-weight decomposition
vol_eff = (m['price0'] * (m['q1']-m['q0'])).sum()
price_eff = (m['q0'] * (m['price1']-m['price0'])).sum()
interaction = dR_total - vol_eff - price_eff

summary = pd.DataFrame({
    'component': ['Volume effect','Price effect','Interaction/Mix','Total ΔR'],
    'value': [vol_eff, price_eff, interaction, dR_total]
})
print(summary)
Why include interaction?

When both price and units change, part of the change is due to both moving together. Keeping an explicit interaction term avoids over-attributing.

2) Conversion rate: rate vs mix (Kitagawa)

Overall conversion r = Σ p_s × r_s where p_s is segment share of sessions, r_s = signups/sessions.

Code
def prep(df, period):
    t = df[df['period']==period].copy()
    t['rate'] = t['signups']/t['sessions']
    t['share'] = t['sessions']/t['sessions'].sum()
    return t[['segment','rate','share']].set_index('segment')

p0 = prep(conv,'P0')
p1 = prep(conv,'P1')

all_seg = p0.index.union(p1.index)
P0 = p0.reindex(all_seg).fillna(0)
P1 = p1.reindex(all_seg).fillna(0)

r0 = (P0['share']*P0['rate']).sum()
r1 = (P1['share']*P1['rate']).sum()

# Midpoint weights (symmetric)
rate_eff = ((P1['rate']-P0['rate']) * 0.5*(P0['share']+P1['share'])).sum()
mix_eff  = ((P1['share']-P0['share']) * 0.5*(P0['rate']+P1['rate'])).sum()

print({'Δr_total': r1-r0, 'rate_effect': rate_eff, 'mix_effect': mix_eff})
Interpretation
  • Rate effect: conversion change within segments.
  • Mix effect: traffic shifting across segments with different conversion.

3) DAU by channel: additive contributions

DAU is a sum. Per-channel contributions are straightforward.

Code
u0 = usage[usage['date']=='2024-01-07'].set_index('channel')['dau']
u1 = usage[usage['date']=='2024-01-14'].set_index('channel')['dau']

ch = u0.index.union(u1.index)
U0 = u0.reindex(ch).fillna(0)
U1 = u1.reindex(ch).fillna(0)

contrib = (U1 - U0).rename('ΔDAU').reset_index()
contrib.loc[len(contrib)] = ['Total', contrib['ΔDAU'].sum()]
print(contrib)

How to do it step-by-step in pandas

  1. Define periods or cohorts clearly (same length, same inclusion rules).
  2. Aggregate to comparable segments (e.g., by product, channel, or user segment).
  3. Align indices and fill missing segments with zeros for both periods.
  4. Choose a decomposition formula: baseline-weight, midpoint-weight, or simple additive by group.
  5. Compute contributions and verify they sum to the total change.
  6. Format results for a waterfall chart: rows as components with signed values.
Mini step card: Waterfall-friendly frame
waterfall = pd.DataFrame([
    {'label':'Start','value': m['R0'].sum()},
    {'label':'Volume effect','value': vol_eff},
    {'label':'Price effect','value': price_eff},
    {'label':'Interaction/Mix','value': interaction},
    {'label':'End','value': m['R1'].sum()}
])

Common mistakes and self-check

  • Mixing percent and percentage points for rates. Fix: report Δrate in pp.
  • Not aligning periods or segments. Fix: outer-join indices and fill missing with 0.
  • Ignoring interaction term and over-attributing. Fix: keep an explicit remainder or split proportionally.
  • Using different user inclusion rules across periods. Fix: consistent filters (e.g., country, platform).
  • Comparing unequal windows (e.g., 7 vs 8 days). Fix: normalize or use equal windows.
Self-check checklist
  • Do contributions sum to the exact total change?
  • Are segment lists aligned and filled?
  • Are rates shown in percentage points?
  • Is the timeframe identical?

Exercises (practice)

These mirror the tasks below. Try them before opening solutions.

  • Exercise 1: Decompose revenue change into volume, price, and interaction and list top contributing products.
  • Exercise 2: Decompose conversion rate change into rate vs mix using midpoint weights.
Practice checklist
  • Create clean period-level frames.
  • Compute total change first.
  • Calculate component effects.
  • Verify sum equals total change.
  • Interpret signs and magnitudes.

Practical projects

  • Weekly revenue bridge: per-category price/volume/interaction with a waterfall chart.
  • Signup conversion bridge: traffic mix vs within-segment rate changes for two marketing pushes.
  • DAU growth attribution: channel contributions plus a “new feature” cohort segment.

Mini challenge

Pick one product category with the largest positive contribution. Propose two actions to amplify it and one to mitigate the largest negative contributor. Keep reasoning tied to the decomposition.

Who this is for

Product Analysts and aspiring analysts who need to explain KPI changes and recommend actions.

Prerequisites

  • Comfort with pandas: groupby, join/merge, indexing.
  • Basic statistics: rates, weighted averages, and percentage points.
  • Foundations of product metrics (DAU, conversion, revenue).

Learning path

  • Start: Aggregations and joins in pandas.
  • Then: Simple additive attributions (by channel or segment).
  • Next: Rate decompositions (Kitagawa) and price–volume–mix bridges.
  • Advanced: Multi-period bridges and cohort-based decompositions.

Next steps

  • Turn outputs into clear waterfall visuals.
  • Automate weekly decomposition jobs.
  • Extend to retention and funnel step attributions.

Quick Test is available to everyone; only logged-in users get saved progress.

Practice Exercises

2 exercises to complete

Instructions

Using the sales DataFrame provided in the lesson, compare weeks 2024-01-07 (P0) and 2024-01-14 (P1). Compute:

  • Total revenue change ΔR
  • Volume effect: Σ p0 × (q1 − q0)
  • Price effect: Σ q0 × (p1 − p0)
  • Interaction: ΔR − volume − price

Then list product-level contributions (R1_i − R0_i) and identify the top positive and negative contributors.

Expected Output
A small table with four rows: Volume effect, Price effect, Interaction/Mix, Total ΔR that sums correctly; plus a product-level table with A and B contributions and the top contributor identified.

Metric Decomposition — Quick Test

Test your knowledge with 7 questions. Pass with 70% or higher.

7 questions70% to pass

Have questions about Metric Decomposition?

AI Assistant

Ask questions about this tool