Loading...
Loading...
Expert marketing analytics covering campaign analysis, attribution modeling, marketing mix modeling, ROI measurement, and performance reporting. Use when analyzing campaign ROI, comparing attribution models, optimizing marketing budget allocation, building executive dashboards, or running A/B test statistical analysis.
npx skill4agent add borghei/claude-skills marketing-analyst| Metric | Formula | Benchmark |
|---|---|---|
| CPL | Spend / Leads | Varies by industry |
| CAC | S&M Spend / New Customers | LTV/CAC > 3:1 |
| CPA | Spend / Acquisitions | Target specific |
| ROAS | Revenue / Ad Spend | > 4:1 |
| Metric | Formula | Benchmark |
|---|---|---|
| Engagement Rate | Engagements / Impressions | 1-5% |
| CTR | Clicks / Impressions | 0.5-2% |
| Conversion Rate | Conversions / Visitors | 2-5% |
| Bounce Rate | Single-page sessions / Total | < 50% |
| Metric | Formula | Benchmark |
|---|---|---|
| Churn Rate | Lost Customers / Total | < 5% monthly |
| NRR | (MRR - Churn + Expansion) / MRR | > 100% |
| LTV | ARPU x Gross Margin x Lifetime | 3x+ CAC |
| Model | Logic | Best For |
|---|---|---|
| First-touch | 100% credit to first interaction | Measuring awareness channels |
| Last-touch | 100% credit to final interaction | Measuring conversion channels |
| Linear | Equal credit across all touches | Balanced view of full journey |
| Time-decay | More credit to recent touches | Short sales cycles |
| Position-based | 40% first, 40% last, 20% middle | Most B2B scenarios |
def calculate_attribution(touchpoints, model='position'):
"""Calculate attribution credit for a conversion journey.
Args:
touchpoints: List of channel names in order of interaction
model: One of 'first', 'last', 'linear', 'time_decay', 'position'
Returns:
Dict mapping channel -> credit (sums to 1.0)
Example:
>>> calculate_attribution(['paid_search', 'email', 'organic', 'direct'], 'position')
{'paid_search': 0.4, 'email': 0.1, 'organic': 0.1, 'direct': 0.4}
"""
n = len(touchpoints)
credits = {}
if model == 'first':
credits[touchpoints[0]] = 1.0
elif model == 'last':
credits[touchpoints[-1]] = 1.0
elif model == 'linear':
for tp in touchpoints:
credits[tp] = credits.get(tp, 0) + 1.0 / n
elif model == 'time_decay':
decay = 0.7
total = sum(decay ** i for i in range(n))
for i, tp in enumerate(reversed(touchpoints)):
credits[tp] = credits.get(tp, 0) + (decay ** i) / total
elif model == 'position':
if n == 1:
credits[touchpoints[0]] = 1.0
elif n == 2:
credits[touchpoints[0]] = 0.5
credits[touchpoints[-1]] = credits.get(touchpoints[-1], 0) + 0.5
else:
credits[touchpoints[0]] = 0.4
credits[touchpoints[-1]] = credits.get(touchpoints[-1], 0) + 0.4
for tp in touchpoints[1:-1]:
credits[tp] = credits.get(tp, 0) + 0.2 / (n - 2)
return credits# Campaign Analysis: Q1 2026 Product Launch
## Performance Summary
| Metric | Target | Actual | vs Target |
|--------------|---------|---------|-----------|
| Impressions | 500K | 612K | +22% |
| Clicks | 25K | 28.4K | +14% |
| Leads | 1,200 | 1,350 | +13% |
| MQLs | 360 | 410 | +14% |
| Pipeline | $1.2M | $1.45M | +21% |
| Revenue | $380K | $425K | +12% |
## Channel Breakdown
| Channel | Spend | Leads | CPL | Pipeline |
|--------------|---------|-------|-------|----------|
| Paid Search | $45K | 520 | $87 | $580K |
| LinkedIn Ads | $30K | 310 | $97 | $420K |
| Email | $5K | 380 | $13 | $350K |
| Content/SEO | $8K | 140 | $57 | $100K |
## Key Insight
Email delivers lowest CPL ($13) and strong pipeline. Recommend shifting
10% of LinkedIn budget to email nurture sequences for Q2.Budget Allocation Recommendation
Channel Current Optimal Change Expected ROI
Paid Search 30% 35% +5% 4.2x
Social Paid 25% 20% -5% 2.8x
Display 15% 10% -5% 1.5x
Email 10% 15% +5% 8.5x
Content 10% 12% +2% 5.2x
Events 10% 8% -2% 2.2x
Projected Impact: +15% pipeline with same budgetfrom scipy import stats
import numpy as np
def analyze_ab_test(control_conv, control_total, treatment_conv, treatment_total, alpha=0.05):
"""Analyze A/B test for statistical significance.
Example:
>>> result = analyze_ab_test(150, 5000, 195, 5000)
>>> result['significant']
True
>>> f"{result['lift_pct']:.1f}%"
'30.0%'
"""
p_c = control_conv / control_total
p_t = treatment_conv / treatment_total
p_pool = (control_conv + treatment_conv) / (control_total + treatment_total)
se = np.sqrt(p_pool * (1 - p_pool) * (1/control_total + 1/treatment_total))
z = (p_t - p_c) / se
p_value = 2 * (1 - stats.norm.cdf(abs(z)))
return {
'control_rate': p_c,
'treatment_rate': p_t,
'lift_pct': ((p_t - p_c) / p_c) * 100,
'p_value': p_value,
'significant': p_value < alpha,
}# Campaign analyzer
python scripts/campaign_analyzer.py --data campaigns.csv --output report.html
# Attribution calculator
python scripts/attribution.py --touchpoints journeys.csv --model position
# ROI calculator
python scripts/roi_calculator.py --spend spend.csv --revenue revenue.csv
# Forecast generator
python scripts/forecast.py --historical data.csv --periods 6references/metrics.mdreferences/attribution.mdreferences/reporting.mdreferences/forecasting.md