📚 Introduction
Ce guide vous accompagne pas à pas dans l'analyse du dataset Advertising pour prédire les ventes en fonction des budgets publicitaires (TV, radio, journaux).
Télécharger le fichier CSVObjectif : Comprendre comment construire un modèle de régression linéaire, l'évaluer, et l'améliorer avec des techniques simples.
Comprendre les données
Le dataset Advertising
200 observations avec 4 variables :
| Variable | Description | Type |
|---|---|---|
| tv | Budget pub TV (milliers €) | Variable prédictive |
| radio | Budget pub radio (milliers €) | Variable prédictive |
| journaux | Budget pub journaux (milliers €) | Variable prédictive |
| ventes | Volume de ventes | Variable cible (ce qu'on veut prédire) |
Première exploration
import pandas as pd
df = pd.read_csv("advertising.csv")
print(df.head())
print(df.describe())
Ce qu'on observe :
- Moyenne TV : ~147, Radio : ~23, Journaux : ~31
- Ventes moyennes : ~14
- Aucune valeur manquante ✅
Visualiser les relations
Pourquoi visualiser ?
Avant de construire un modèle, il faut voir si les variables sont liées aux ventes.
Les graphiques avec trendline (ligne de régression)
import plotly.express as px
fig = px.scatter(df, x="tv", y="ventes",
trendline="ols", # Ordinary Least Squares
title="TV vs Ventes")
fig.show()
Ce que montre le paramètre trendline="ols" :
- Trace automatiquement la meilleure droite qui passe au plus près des points
- OLS = méthode mathématique pour trouver cette droite
- Si les points sont proches de la ligne → forte relation 💪
- Si les points sont dispersés → faible relation 😐
Les corrélations
| Variables | Corrélation avec ventes |
|---|---|
| tv | 0.78 🔥 (très forte) |
| radio | 0.58 👍 (forte) |
| journaux | 0.23 😐 (faible) |
Interprétation simple :
- 0.78 : Quand le budget TV augmente, les ventes augmentent beaucoup
- 0.23 : Les journaux ont peu d'impact sur les ventes
Construire le modèle de régression linéaire
Qu'est-ce qu'une régression linéaire ?
C'est trouver la formule mathématique qui relie les variables :
ventes = a × tv + b × radio + c × journaux + d
Le modèle va chercher les meilleurs coefficients a, b, c, d pour prédire au mieux les ventes.
Le code
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
# 1. Préparer les données
X = df[["tv", "radio", "journaux"]] # Variables prédictives
y = df.ventes # Variable cible
# 2. Séparer en train (80%) et test (20%)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.20, random_state=42
)
# 3. Créer et entraîner le modèle
reg = LinearRegression()
reg.fit(X_train, y_train) # Le modèle "apprend"
# 4. Faire des prédictions
y_pred_test = reg.predict(X_test)
🧠 Comprendre train_test_split
Pourquoi séparer les données ?
Imaginez que vous préparez un examen :
- Train (80%) = Les exercices que vous faites pour apprendre
- Test (20%) = L'examen final avec des questions que vous n'avez jamais vues
Si vous testez sur les mêmes données que l'entraînement, vous trichez ! Le modèle connaît déjà les réponses.
Le paramètre random_state=42 :
- Assure que la séparation est toujours la même
- Permet de reproduire les résultats
- Sans ça, chaque exécution donnerait des résultats différents
Évaluer le modèle
Les métriques d'évaluation
from sklearn.metrics import mean_squared_error, mean_absolute_percentage_error
rmse = mean_squared_error(y_test, y_pred_test)
mape = mean_absolute_percentage_error(y_test, y_pred_test)
print(f"RMSE : {rmse}")
print(f"MAPE : {mape}")
📏 RMSE (Root Mean Square Error)
C'est quoi ? L'erreur moyenne de vos prédictions.
Exemple concret :
- Si RMSE = 3.17
- En moyenne, vos prédictions se trompent de ±3.17 unités de ventes
- Si les vraies ventes sont 15, vous prédisez entre 11.83 et 18.17
Caractéristique : Pénalise fortement les grosses erreurs
- Se tromper de 10 compte plus que se tromper de 1 dix fois
🎯 MAPE (Mean Absolute Percentage Error)
C'est quoi ? L'erreur en pourcentage.
Exemple concret :
- Si MAPE = 0.15 (soit 15%)
- En moyenne, vos prédictions ont 15% d'erreur
- Si les vraies ventes sont 100, vous prédisez entre 85 et 115
Avantage : Plus intuitif et comparable entre différents projets
Est-ce bon ou mauvais ?
Pour le modèle simple :
- RMSE ≈ 3.17 → Pas mal 👍
- MAPE ≈ 0.15 (15%) → Correct mais peut mieux faire 🤔
Amélioration : La régression polynomiale
Le problème détecté
En regardant le graphique TV vs Ventes, on remarque que les points forment une courbe plutôt qu'une ligne droite.
Exemple visuel :
Budget TV faible (0-50) → Les ventes augmentent lentement
Budget TV moyen (100-150) → Les ventes augmentent normalement
Budget TV élevé (200-300) → Les ventes augmentent rapidement
C'est une accélération = relation non-linéaire !
La solution : ajouter tv²
Au lieu de :
ventes = a × tv + ...
On fait :
ventes = a × tv + b × tv² + ...
Pourquoi tv² capture la courbure ?
Exemple simple :
| tv | tv² | Rapport |
|---|---|---|
| 10 | 100 | - |
| 20 | 400 | ×4 (pas ×2 !) |
| 30 | 900 | ×9 (pas ×3 !) |
Le terme tv² augmente beaucoup plus vite que tv, ce qui crée l'effet de courbure/accélération.
Normalisation : Pourquoi et comment ?
Le problème d'échelle
Après avoir créé tv², on a :
tv: entre 0 et 300tv²: entre 0 et 90 000 ! 😱
Le modèle va penser que tv² est beaucoup plus important juste parce que les chiffres sont gros.
La solution : MinMaxScaler
Ce que ça fait : Ramène toutes les variables entre 0 et 1.
Exemple :
Avant :
tv = [0, 100, 200, 300]
Après normalisation :
tv = [0, 0.33, 0.66, 1.0]
Le code
from sklearn.preprocessing import MinMaxScaler
# 1. Créer tv²
df['tv2'] = df.tv ** 2
# 2. Normaliser
scaler = MinMaxScaler()
data_normalized = scaler.fit_transform(df)
df_normalized = pd.DataFrame(data_normalized,
columns=['tv', 'radio', 'journaux', 'ventes', 'tv2'])
# 3. Entraîner avec tv²
X_poly = df_normalized[['tv', 'radio', 'journaux', 'tv2']]
y_poly = df_normalized.ventes
X_train, X_test, y_train, y_test = train_test_split(
X_poly, y_poly, test_size=0.20, random_state=42
)
reg_poly = LinearRegression()
reg_poly.fit(X_train, y_train)
y_pred_poly = reg_poly.predict(X_test)
Comprendre fit_transform
Les 4 étapes du scaler :
fit(): Le scaler regarde les données et calcule :- Le minimum de chaque colonne
- Le maximum de chaque colonne
transform(): Le scaler applique la formule :valeur_normalisée = (valeur - min) / (max - min)fit_transform(): Fait les 2 étapes d'un coup (plus rapide)
Exemple concret :
tv = [0, 100, 200, 300]
# Le scaler calcule :
min = 0
max = 300
# Puis transforme :
0 → (0 - 0) / 300 = 0
100 → (100 - 0) / 300 = 0.33
200 → (200 - 0) / 300 = 0.66
300 → (300 - 0) / 300 = 1.0
Comparaison des résultats
Tableau récapitulatif
| Modèle | Variables utilisées | RMSE | MAPE | Amélioration |
|---|---|---|---|---|
| Linéaire simple | tv, radio, journaux | ~3.17 | ~0.15 | - |
| Polynomiale | tv, radio, journaux, tv² | Plus petit | Plus petit | ✅ Meilleur |
Pourquoi c'est mieux ?
Le terme quadratique tv² permet de capturer la vraie relation entre TV et ventes :
- Pas juste une ligne droite
- Mais une courbe qui représente l'accélération des ventes avec le budget
Convention de nommage importante
La notation _pred
En machine learning, on utilise cette convention :
| Variable | Signification |
|---|---|
y_test |
Les vraies valeurs de ventes |
y_pred_test |
Les valeurs prédites par le modèle |
Pourquoi c'est important ?
- Distingue clairement la réalité des prédictions
- Évite les confusions dans le code
- Standard dans toute la communauté ML
Analogie :
y_test= Les bonnes réponses de l'exameny_pred_test= Vos réponses (ce que le modèle pense)- Les métriques (RMSE, MAPE) = La note de l'examen (comparaison des deux)
🎓 Concepts clés à retenir
1. Train/Test Split
✅ Toujours séparer les données
✅ Typiquement 80/20 ou 70/30
✅ Le modèle n'a jamais vu les données de test
2. Corrélation
✅ Entre -1 et +1
✅ Plus proche de ±1 = plus forte relation
✅ Proche de 0 = pas de relation
3. Régression polynomiale
✅ Ajouter des puissances (x²) capture les courbes
✅ Plus flexible que la régression linéaire simple
✅ Attention à ne pas "sur-complexifier" (overfitting)
4. Normalisation
✅ Met toutes les variables sur la même échelle
✅ Permet de comparer l'importance des coefficients
✅ Évite que les grandes valeurs dominent
5. Métriques d'évaluation
✅ RMSE : Erreur absolue, pénalise les grosses erreurs
✅ MAPE : Erreur en %, facile à interpréter
✅ Plus petit = meilleur modèle
🚀 Pour aller plus loin
Idées d'améliorations
Ajouter des termes croisés :
tv × radio- Capture l'effet combiné de campagnes multi-canal
Retirer la variable
journaux- Corrélation faible (0.23), peut simplifier le modèle
Tester d'autres modèles
- Random Forest, Gradient Boosting
- Comparer les performances
Analyser les résidus
- Différence entre prédiction et réalité
- Identifier les patterns d'erreurs
📝 Résumé du workflow complet
1. Charger les données
↓
2. Explorer (head, describe, visualisations)
↓
3. Analyser les corrélations
↓
4. Préparer X (variables) et y (cible)
↓
5. Split train/test
↓
6. Entraîner le modèle (fit)
↓
7. Prédire (predict)
↓
8. Évaluer (RMSE, MAPE)
↓
9. Améliorer (ajouter tv², normaliser)
↓
10. Comparer les résultats
💡 Analogies pour bien comprendre
Le modèle = Un étudiant
- fit() = Réviser avec les exercices du livre
- predict() = Passer l'examen
- Train set = Les exercices du livre
- Test set = L'examen avec de nouvelles questions
- RMSE/MAPE = La note de l'examen
La régression linéaire = Tracer une droite
- On a des points sur un graphique
- On cherche la meilleure droite qui passe près de tous les points
- Les coefficients = La pente et la hauteur de la droite
- L'erreur = La distance moyenne entre les points et la droite
La normalisation = Mettre tout en euros
- Sans normalisation : comparer des pommes (2€) et des voitures (20 000€)
- Avec normalisation : tout entre 0 et 1, on compare des proportions
- Comme mettre toutes les valeurs en "pourcentage du maximum"