📊 Problématique Business

Contexte : L'entreprise dépense sur Google, Facebook, email sans savoir ce qui convertit.

Objectif : Modèle d'attribution pour optimiser le budget et +20% ROAS.

🗂️ Dataset

🎯 Modèles d'Attribution

1. First Click

100% du crédit au premier touchpoint

2. Last Click

100% du crédit au dernier touchpoint

3. Linear

Crédit égal à tous les touchpoints

4. Time Decay

Plus de crédit aux touchpoints récents

5. U-Shaped

40% premier, 40% dernier, 20% aux autres

🛠️ Stack Technique

Python Pandas Scipy Power BI Optimization

💻 Code de Démarrage

"""
PROJET 3 : Attribution Marketing Multi-Touch
Modèles d"attribution et optimisation budget
"""

import pandas as pd
import numpy as np
from scipy.optimize import minimize

# Modèle First Click
def first_click_attribution(group):
    group["attribution"] = 0
    group.loc[group["touchpoint"] == 1, "attribution"] = group["conversion_value"].iloc[0]
    return group

# Modèle Last Click
def last_click_attribution(group):
    group["attribution"] = 0
    last_idx = group["touchpoint"].max()
    group.loc[group["touchpoint"] == last_idx, "attribution"] = group["conversion_value"].iloc[0]
    return group

# Modèle Linear
def linear_attribution(group):
    n_touchpoints = len(group)
    group["attribution"] = group["conversion_value"].iloc[0] / n_touchpoints
    return group

# Calculer le ROAS
def calculate_roas(attribution_values, budget_per_channel):
    roas = {}
    for channel in attribution_values.index:
        revenue = attribution_values[channel]
        cost = budget_per_channel[channel]
        roas[channel] = revenue / cost if cost > 0 else 0
    return pd.Series(roas)

# Optimisation du budget
def optimize_budget(total_budget, roas_by_channel):
    channels = list(roas_by_channel.index)
    roas_values = roas_by_channel.values
    
    def objective(budget_allocation):
        return -sum(budget_allocation * roas_values)
    
    constraints = [
        {"type": "eq", "fun": lambda x: sum(x) - total_budget}
    ]
    
    bounds = [(total_budget * 0.05, total_budget) for _ in channels]
    x0 = np.array([total_budget / len(channels)] * len(channels))
    
    result = minimize(objective, x0, method="SLSQP", 
                     bounds=bounds, constraints=constraints)
    
    return pd.Series(result.x, index=channels)

📁 Fichier complet : projets/code/projet3_attribution_starter.py