Python Intermédiaire

Python pour la Data Science : De la logique aux systèmes intelligents

Python est aujourd’hui l’un des piliers incontournables de la data science et de l’intelligence artificielle. Mais derrière sa simplicité apparente se cache une puissance redoutable lorsqu’il est utilisé avec méthode. Ce cours te permettra de comprendre en profondeur comment manipuler les données, structurer ta logique et construire des bases solides pour des systèmes intelligents. Tu ne vas pas seulement écrire du code : tu vas apprendre à penser comme un ingénieur data. À la fin, tu seras capable de concevoir des traitements réels, exploitables et efficaces.

Preparetoi.academy 50 min

Python pour la Data Science : De la logique aux systèmes intelligents

Introduction

Python est aujourd’hui l’un des piliers incontournables de la data science et de l’intelligence artificielle. Mais derrière sa simplicité apparente se cache une puissance redoutable lorsqu’il est utilisé avec méthode. Ce cours te permettra de comprendre en profondeur comment manipuler les données, structurer ta logique et construire des bases solides pour des systèmes intelligents. Tu ne vas pas seulement écrire du code : tu vas apprendre à penser comme un ingénieur data. À la fin, tu seras capable de concevoir des traitements réels, exploitables et efficaces.


Sommaire

  1. Manipulation avancée des variables et structures
  2. Logique conditionnelle appliquée aux données
  3. Boucles intelligentes et optimisation
  4. Fonctions modulaires et réutilisables
  5. Structures de données complexes
  6. Introduction aux fichiers et flux de données
  7. Manipulation avancée de listes et dictionnaires
  8. Compréhension profonde de NumPy
  9. Pandas pour la manipulation de données
  10. Nettoyage et transformation de données
  11. Visualisation avec Matplotlib et Seaborn
  12. Introduction aux statistiques pour la data
  13. Probabilités appliquées
  14. Introduction au Machine Learning
  15. Préparation des données pour ML
  16. Modèles supervisés
  17. Évaluation des modèles
  18. Introduction au Deep Learning
  19. Automatisation et pipelines data
  20. Projet réel complet

1. Manipulation avancée des variables et structures

Définition approfondie

Une variable en Python est une référence vers une donnée stockée en mémoire. Contrairement à des langages plus rigides, Python utilise un typage dynamique, ce qui signifie que le type d’une variable est déterminé à l’exécution. Mais en data science, comprendre comment les données sont stockées et manipulées est crucial. Une mauvaise gestion des variables peut entraîner des erreurs invisibles ou des performances médiocres.

Les structures comme les listes, tuples et dictionnaires permettent d’organiser ces données. Elles sont les fondations sur lesquelles reposent toutes les opérations data : transformation, filtrage, agrégation.


Explication avec analogie

Imagine une cuisine professionnelle :

  • Une variable = un ingrédient
  • Une liste = une étagère avec plusieurs ingrédients
  • Un dictionnaire = une recette avec des clés (nom) et valeurs (quantité)

Si tu ranges mal tes ingrédients, tu perds du temps. En data science, c’est pareil : une mauvaise structure ralentit tout ton système.


Bloc code commenté ligne par ligne

# On stocke une température brute issue d'un capteur
temperature = 23.5  

# Une liste de mesures collectées dans la journée
mesures = [22.1, 23.5, 24.0, 22.8]

# Un dictionnaire associant une ville à sa température
donnees_ville = {
    "Paris": 23.5,
    "Lyon": 25.2,
    "Marseille": 27.1
}

# Accéder à une valeur dans la liste (index 1 = deuxième élément)
valeur = mesures[1]

# Modifier une valeur (corriger une erreur capteur)
mesures[2] = 23.8

# Ajouter une nouvelle mesure
mesures.append(24.2)

# Accéder à une donnée spécifique dans le dictionnaire
temp_paris = donnees_ville["Paris"]

# Ajouter une nouvelle ville
donnees_ville["Toulouse"] = 26.3

Cas d’usage réel

Dans un système IoT (capteurs météo), tu reçois des flux de données en continu. Ces données sont stockées dans des listes ou dictionnaires avant traitement.

Exemple réel :

  • Liste = historique des mesures
  • Dictionnaire = mapping ville → température

Ces structures permettent ensuite :

  • calcul de moyenne
  • détection d’anomalies
  • prédiction météo

Tableau comparatif

Structure Mutable Usage principal Performance
Liste Oui Données ordonnées Rapide
Tuple Non Données fixes Très rapide
Dictionnaire Oui Accès clé → valeur Optimal

Astuce

Utilise toujours un dictionnaire quand tu dois faire des recherches rapides. Accéder à une clé est beaucoup plus rapide que parcourir une liste.


Attention

Modifier une liste pendant que tu la parcours peut créer des bugs difficiles à détecter. Toujours travailler sur une copie si nécessaire.


2. Logique conditionnelle appliquée aux données

Définition approfondie

La logique conditionnelle permet de contrôler le flux d’exécution d’un programme en fonction de conditions spécifiques. En Python, elle repose principalement sur les structures if, elif et else. En data science, ces structures ne servent pas uniquement à prendre des décisions simples : elles permettent de filtrer, classifier, nettoyer et transformer des données en fonction de règles métier précises.

Une condition repose sur une expression booléenne, c’est-à-dire une expression qui renvoie True ou False. Ces expressions peuvent être simples (comparaison de valeurs) ou complexes (combinaison de plusieurs conditions avec and, or, not).

Dans un contexte réel, la logique conditionnelle agit comme un système de tri intelligent : elle permet de distinguer les données pertinentes des données inutiles ou erronées.


Explication avec analogie

Imagine un agent de sécurité à l’entrée d’un événement :

  • Si tu as un billet valide → tu entres
  • Si tu es VIP → accès spécial
  • Sinon → refus

Ce système fonctionne avec des règles précises. En Python, les conditions jouent exactement ce rôle : elles filtrent les informations selon des critères définis.

En data science, c’est comme filtrer une base de données :

  • garder les clients actifs
  • exclure les valeurs aberrantes
  • classer des observations

Bloc code commenté ligne par ligne

# Température mesurée
temperature = 38.5

# Vérifier si la température indique une anomalie
if temperature > 37.5:
    print("Alerte : température élevée")  # Message si condition vraie

# Cas plus complexe avec plusieurs conditions
humidite = 80

if temperature > 37.5 and humidite > 70:
    print("Risque critique détecté")  # Deux conditions doivent être vraies

# Classification d'une donnée
score = 72

if score >= 85:
    niveau = "Excellent"
elif score >= 70:
    niveau = "Bon"
elif score >= 50:
    niveau = "Moyen"
else:
    niveau = "Faible"

# Affichage du résultat
print(niveau)

# Vérifier une valeur manquante (cas fréquent en data)
valeur = None

if valeur is None:
    print("Donnée manquante détectée")

Cas d’usage réel

Dans un système de détection de fraude bancaire :

  • Si montant > 10 000 ET pays inhabituel → alerte
  • Si plusieurs transactions rapides → suspicion
  • Sinon → transaction valide

Les conditions permettent de créer des règles métier dynamiques qui s’adaptent aux données.

Autre exemple concret :
Nettoyage de dataset :

  • supprimer les valeurs négatives
  • remplacer les valeurs nulles
  • corriger les incohérences

Tableau comparatif

Opérateur Description Exemple
== Égalité x == 10
!= Différent x != 5
> Supérieur x > 3
< Inférieur x < 8
and Les deux conditions doivent être vraies x > 5 and x < 10
or Une seule condition suffit x < 0 or x > 100
not Inverse une condition not(x > 10)

Astuce

Combine les conditions avec des parenthèses pour améliorer la lisibilité :

if (temperature > 37.5) and (humidite > 70):

Cela évite les erreurs logiques dans des systèmes complexes.


Attention

Confondre = et == est une erreur classique :

  • = → affectation
  • == → comparaison

Cette erreur peut casser toute la logique sans générer d’erreur visible.


3. Boucles intelligentes et optimisation

Définition approfondie

Les boucles en Python permettent de répéter une série d’instructions sur un ensemble de données. Les deux principales structures sont for et while. En data science, les boucles sont omniprésentes car elles permettent de traiter des volumes importants de données ligne par ligne ou élément par élément.

Cependant, une utilisation naïve des boucles peut rapidement devenir inefficace, surtout lorsqu’on manipule des datasets volumineux. L’enjeu n’est donc pas seulement de boucler, mais de boucler intelligemment, en réduisant le nombre d’opérations inutiles et en optimisant les performances.

Une boucle bien conçue doit :

  • minimiser les calculs répétés
  • éviter les accès mémoire coûteux
  • exploiter les structures adaptées

Explication avec analogie

Imagine que tu dois vérifier 10 000 dossiers dans une administration :

  • Méthode lente : tu ouvres chaque dossier un par un sans organisation
  • Méthode intelligente : tu classes les dossiers et tu appliques une règle rapide

La boucle simple = vérifier un par un
La boucle optimisée = vérifier efficacement avec stratégie

En data science, la différence peut passer de minutes à millisecondes.


Bloc code commenté ligne par ligne

# Liste de températures collectées
temperatures = [22.1, 25.3, 19.8, 30.2, 28.5]

# Initialiser une variable pour stocker la somme
somme = 0

# Parcourir chaque élément de la liste
for temp in temperatures:
    somme += temp  # Ajouter chaque valeur à la somme

# Calcul de la moyenne
moyenne = somme / len(temperatures)

print("Moyenne:", moyenne)

# Exemple d'optimisation avec compréhension de liste
# Filtrer uniquement les températures élevées
temp_elevees = [t for t in temperatures if t > 25]

print(temp_elevees)

# Boucle avec index (utile pour modification)
for i in range(len(temperatures)):
    temperatures[i] += 1  # Correction capteur (+1 degré)

print(temperatures)

Cas d’usage réel

Dans un système de monitoring industriel :

  • Des capteurs envoient des milliers de valeurs par seconde
  • Une boucle analyse chaque valeur
  • Si anomalie → déclencher alerte

Exemple concret :

  • filtrer les valeurs hors seuil
  • calculer des moyennes glissantes
  • détecter des pics anormaux

Sans optimisation, le système devient lent et inutilisable en temps réel.


Tableau comparatif

Type de boucle Usage principal Performance Lisibilité
for classique Parcours simple Bonne Élevée
while Condition dynamique Variable Moyenne
Compréhension liste Transformation rapide Très élevée Élevée
Boucle imbriquée Données complexes Faible si mal gérée Faible

Astuce

Utilise les compréhensions de liste dès que possible :

resultat = [x * 2 for x in data if x > 10]

C’est plus rapide et plus lisible qu’une boucle classique.


Attention

Les boucles imbriquées (for dans for) peuvent exploser le temps de calcul :

  • 1000 × 1000 = 1 000 000 opérations

Toujours réfléchir à une alternative (indexation, dictionnaire, vectorisation).


4. Fonctions modulaires et réutilisables

Définition approfondie

Une fonction en Python est un bloc de code réutilisable qui encapsule une logique spécifique. Elle prend éventuellement des entrées (paramètres), effectue un traitement, puis retourne un résultat. En data science, les fonctions sont essentielles pour structurer un projet, éviter la duplication de code et garantir la maintenabilité.

Une bonne fonction doit être :

  • claire : elle fait une seule chose
  • réutilisable : utilisable dans plusieurs contextes
  • testable : facile à vérifier indépendamment

Dans des projets réels (analyse de données, machine learning), les fonctions permettent de transformer un script désorganisé en pipeline structuré.


Explication avec analogie

Imagine une usine :

  • Une fonction = une machine spécialisée
  • Entrée = matière première
  • Sortie = produit fini

Si chaque machine fait une seule tâche correctement, toute la chaîne devient efficace.

Sans fonctions :
👉 chaos, répétition, erreurs

Avec fonctions :
👉 organisation, rapidité, évolutivité


Bloc code commenté ligne par ligne

# Définir une fonction pour nettoyer une donnée
def nettoyer_temperature(valeur):
    # Vérifier si la valeur est invalide
    if valeur is None:
        return None  # Retourne une valeur vide
    
    # Corriger les valeurs aberrantes
    if valeur < -50 or valeur > 60:
        return None
    
    # Arrondir la valeur
    return round(valeur, 1)

# Liste de données brutes
donnees = [22.345, None, 100, 25.678, -80]

# Appliquer la fonction sur chaque élément
donnees_nettoyees = []

for d in donnees:
    resultat = nettoyer_temperature(d)  # Appel de la fonction
    donnees_nettoyees.append(resultat)

print(donnees_nettoyees)

# Fonction plus avancée avec plusieurs paramètres
def calcul_moyenne(data):
    # Filtrer les valeurs valides
    valeurs_valides = [x for x in data if x is not None]
    
    # Vérifier si la liste est vide
    if len(valeurs_valides) == 0:
        return None
    
    # Calcul de la moyenne
    return sum(valeurs_valides) / len(valeurs_valides)

print(calcul_moyenne(donnees_nettoyees))

Cas d’usage réel

Dans un pipeline de traitement de données :

  1. Fonction de nettoyage
  2. Fonction de transformation
  3. Fonction de calcul
  4. Fonction de visualisation

Chaque étape est indépendante.

Exemple concret :

  • nettoyage de données clients
  • calcul de score de crédit
  • classification automatique

Sans fonctions, ce système devient impossible à maintenir.


Tableau comparatif

Approche Avantages Inconvénients
Code sans fonction Rapide à écrire Illisible, non maintenable
Fonction simple Réutilisable Nécessite organisation
Fonction modulaire Très structuré Demande conception initiale
Pipeline fonctionnel Scalable et professionnel Plus complexe

Astuce

Nommer clairement les fonctions améliore énormément la lisibilité :

nettoyer_temperature()
calcul_moyenne()
detecter_anomalie()

Un bon nom remplace un commentaire.


Attention

Une fonction ne doit pas faire trop de choses à la fois.
Sinon :

  • difficile à comprendre
  • difficile à tester
  • source de bugs

👉 Une fonction = une responsabilité


5. Structures de données complexes

Définition approfondie

Les structures de données complexes en Python permettent d’organiser des informations multidimensionnelles et hétérogènes. Contrairement aux structures simples (liste, tuple), elles combinent plusieurs types pour représenter des systèmes plus proches du réel.

Les plus utilisées en data science sont :

  • listes de dictionnaires
  • dictionnaires de listes
  • dictionnaires imbriqués
  • combinaisons hybrides

Ces structures permettent de représenter :

  • des bases de données
  • des API JSON
  • des datasets multi-variables

Comprendre ces structures est fondamental, car la majorité des données réelles ne sont ni propres ni plates.


Explication avec analogie

Imagine une entreprise :

  • Une liste = liste des employés
  • Un dictionnaire = fiche d’un employé
  • Une structure complexe = toute l’entreprise

Exemple :
Chaque employé a :

  • un nom
  • un âge
  • un département
  • des performances

Une simple liste ne suffit pas. Il faut une structure imbriquée pour refléter la réalité.


Bloc code commenté ligne par ligne

# Liste de dictionnaires représentant des employés
employes = [
    {"nom": "Ali", "age": 30, "salaire": 5000},
    {"nom": "Sara", "age": 25, "salaire": 6000},
    {"nom": "Youssef", "age": 35, "salaire": 5500}
]

# Accéder au salaire du deuxième employé
salaire_sara = employes[1]["salaire"]

# Ajouter un nouvel employé
employes.append({"nom": "Lina", "age": 28, "salaire": 6200})

# Calculer le salaire moyen
total = 0

for emp in employes:
    total += emp["salaire"]

moyenne = total / len(employes)

print("Salaire moyen:", moyenne)

# Exemple de dictionnaire imbriqué
entreprise = {
    "IT": [
        {"nom": "Ali", "score": 90},
        {"nom": "Sara", "score": 85}
    ],
    "RH": [
        {"nom": "Lina", "score": 88}
    ]
}

# Accéder à un score spécifique
score_ali = entreprise["IT"][0]["score"]

print(score_ali)

Cas d’usage réel

Les API modernes (comme celles des réseaux sociaux ou des systèmes financiers) retournent des données en format JSON, qui est essentiellement une structure imbriquée.

Exemple réel :
Un système e-commerce :

  • clients → commandes → produits

Structure typique :

client → liste commandes → chaque commande → liste produits

Pour analyser ces données (revenu, comportement client), il faut manipuler des structures complexes efficacement.


Tableau comparatif

Structure Complexité Usage principal Lisibilité
Liste simple Faible Données homogènes Élevée
Dictionnaire simple Moyenne Accès clé-valeur Élevée
Liste de dictionnaires Élevée Données structurées Moyenne
Dictionnaire imbriqué Très élevée Modèles complexes (JSON, API) Faible

Astuce

Utilise .get() pour éviter les erreurs :

emp.get("salaire", 0)

Cela évite un crash si la clé n’existe pas.


Attention

Les structures imbriquées deviennent vite illisibles.
Si tu ne structures pas bien :

  • bugs difficiles
  • maintenance compliquée

👉 Solution : bien nommer les clés et structurer proprement.


6. Introduction aux fichiers et flux de données

Définition approfondie

En data science, les données ne vivent pas uniquement en mémoire : elles proviennent de fichiers externes ou de flux continus. Python permet de lire, écrire et manipuler ces données via des opérations sur les fichiers (open, read, write) ainsi que via des flux (streams).

Un fichier est une source persistante de données stockée sur disque. Il peut être :

  • texte (.txt)
  • structuré (.csv, .json)
  • binaire (images, modèles)

Un flux de données, quant à lui, représente un flux continu d’informations (logs, capteurs, API). La différence est importante :

  • fichier = statique
  • flux = dynamique

La maîtrise de ces concepts est essentielle pour passer de scripts simples à des systèmes capables de traiter des données réelles en production.


Explication avec analogie

Imagine une rivière :

  • Un fichier = une bouteille d’eau stockée
  • Un flux = une rivière qui coule en continu

Tu peux :

  • analyser une bouteille (fichier) tranquillement
  • ou analyser la rivière (flux) en temps réel

En data science, travailler avec des flux permet de construire des systèmes intelligents en direct (monitoring, IA temps réel).


Bloc code commenté ligne par ligne

# Écriture dans un fichier texte
with open("donnees.txt", "w") as fichier:
    # Écrire une ligne dans le fichier
    fichier.write("Température: 23.5\n")
    fichier.write("Humidité: 70\n")

# Lecture du fichier
with open("donnees.txt", "r") as fichier:
    contenu = fichier.read()  # Lire tout le contenu

print(contenu)

# Lecture ligne par ligne (plus efficace pour gros fichiers)
with open("donnees.txt", "r") as fichier:
    for ligne in fichier:
        print(ligne.strip())  # Supprimer les retours à la ligne

# Simulation d’un flux de données
import time

donnees_flux = [22.1, 23.5, 24.0, 25.2]

for valeur in donnees_flux:
    print("Nouvelle donnée:", valeur)
    time.sleep(1)  # Pause pour simuler un flux temps réel

Cas d’usage réel

Dans un système de surveillance industrielle :

  • Les capteurs écrivent dans des fichiers logs
  • Un programme lit ces fichiers
  • Analyse les données
  • Détecte anomalies

Autre exemple :
Analyse de fichiers CSV contenant :

  • ventes
  • clients
  • transactions

Ces fichiers sont ensuite transformés pour :

  • créer des dashboards
  • entraîner des modèles IA

Tableau comparatif

Type de données Nature Usage principal Performance
Fichier texte Statique Logs simples Moyenne
CSV Structuré Données tabulaires Élevée
JSON Semi-structuré API, données imbriquées Flexible
Flux temps réel Dynamique IoT, streaming Critique

Astuce

Toujours utiliser with open(...) :

👉 Cela ferme automatiquement le fichier, même en cas d’erreur.


Attention

Lire un fichier volumineux d’un seul coup (read()) peut saturer la mémoire.

👉 Solution :

  • lire ligne par ligne
  • ou utiliser des chunks

7. Manipulation avancée de listes et dictionnaires

Définition approfondie

Les listes et dictionnaires sont des structures fondamentales en Python, mais en data science, la simple utilisation de append() ou dict[key] = value n’est souvent pas suffisante. Les manipulations avancées incluent :

  • filtres conditionnels
  • transformations via comprehensions
  • tri complexe
  • fusion et regroupement de dictionnaires
  • accès optimisé à des données imbriquées

Ces techniques permettent de gérer des datasets volumineux et hétérogènes avec efficacité et lisibilité.


Explication avec analogie

Imagine une bibliothèque moderne :

  • Une liste simple = les livres sur une étagère
  • Une liste avancée = trier les livres par auteur, genre, année
  • Un dictionnaire simple = fiche de livre (titre → auteur)
  • Un dictionnaire avancé = catalogue complet avec sections, sous-sections, tags

Sans ces techniques, retrouver un livre précis dans une énorme bibliothèque devient impossible. En data science, c’est exactement la même logique pour les datasets.


Bloc code commenté ligne par ligne

# Liste de dictionnaires représentant des capteurs
capteurs = [
    {"id": 1, "temperature": 22.3, "status": "ok"},
    {"id": 2, "temperature": 30.1, "status": "alerte"},
    {"id": 3, "temperature": 25.0, "status": "ok"}
]

# Filtrer uniquement les capteurs en alerte
capteurs_alerte = [c for c in capteurs if c["status"] == "alerte"]
print(capteurs_alerte)

# Extraire toutes les températures dans une liste
temperatures = [c["temperature"] for c in capteurs]
print(temperatures)

# Trier les capteurs par température décroissante
capteurs_sorted = sorted(capteurs, key=lambda x: x["temperature"], reverse=True)
print(capteurs_sorted)

# Fusionner deux dictionnaires pour un rapport complet
rapport = {"total": 3, "alerte": len(capteurs_alerte)}
details = {"capteurs": capteurs}
rapport_complet = {**rapport, **details}
print(rapport_complet)

# Modification conditionnelle des dictionnaires
for c in capteurs:
    if c["temperature"] > 28:
        c["status"] = "critique"
print(capteurs)

Cas d’usage réel

Dans un projet de monitoring IoT, on reçoit des flux de capteurs :

  • Liste = toutes les mesures d’un type de capteur

  • Dictionnaire = mapping capteur → données temporelles

  • Manipulations avancées permettent :

    • détecter anomalies
    • calculer statistiques par catégorie
    • générer alertes en temps réel

Autre exemple : analyse de ventes e-commerce

  • Filtrer produits vendus > 100 unités
  • Calculer revenu moyen par catégorie
  • Grouper les données par région

Tableau comparatif

Technique Usage principal Performance Lisibilité
Comprehension liste Filtrage et transformation rapide Très élevée Élevée
Tri avec sorted() Ordre spécifique Élevée Moyenne
Fusion dictionnaires Combiner plusieurs sources Moyenne Élevée
Boucle + condition Modification ciblée Moyenne Moyenne

Astuce

Préférer comprehensions pour les transformations simples :

temperatures_ok = [t for t in temperatures if t < 28]

C’est plus lisible et souvent plus rapide qu’une boucle classique.


Attention

Modifier une liste ou dictionnaire pendant un parcours peut créer des bugs difficiles à détecter.
✅ Astuce : travailler sur une copie avec list() ou dict.copy().


8. Compréhension profonde de NumPy

Définition approfondie

NumPy (Numerical Python) est la bibliothèque fondamentale pour le calcul scientifique en Python. Elle fournit :

  • des tableaux multidimensionnels (ndarray)
  • des opérations vectorisées ultra-rapides
  • des fonctions mathématiques avancées
  • des outils d’algèbre linéaire, statistiques et transformations

Contrairement aux listes Python, les ndarrays sont stockés contiguës en mémoire, ce qui permet des calculs très rapides sur des datasets volumineux.

En data science, NumPy est la base de tout pipeline performant, servant souvent de socle à pandas, scikit-learn et TensorFlow.


Explication avec analogie

Imagine que tu dois additionner les températures de 1 million de capteurs :

  • Avec une liste Python, tu additionnes un par un → lent
  • Avec un ndarray NumPy, tu additionnes tout en un seul calcul → rapide comme une usine automatisée

NumPy transforme les listes Python en machines vectorisées capables de traiter de grandes quantités de données sans boucle explicite.


Bloc code commenté ligne par ligne

import numpy as np

# Créer un tableau NumPy à partir d'une liste Python
temperatures = [22.3, 25.0, 30.1, 28.5]
arr = np.array(temperatures)  # Conversion en ndarray
print(arr)

# Opérations vectorisées (aucune boucle explicite)
moyenne = arr.mean()  # Moyenne des températures
maximum = arr.max()   # Valeur maximale
minimum = arr.min()   # Valeur minimale

print("Moyenne:", moyenne, "Max:", maximum, "Min:", minimum)

# Transformation élément par élément
arr_celsius_to_f = arr * 9/5 + 32  # Conversion Celsius → Fahrenheit
print(arr_celsius_to_f)

# Sélection conditionnelle (filtrage)
arr_froid = arr[arr < 25]  # Températures inférieures à 25°C
print(arr_froid)

# Création d'un tableau 2D
matrice = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(matrice)

# Accès à un élément spécifique
elem = matrice[1, 2]  # Ligne 1, colonne 2
print(elem)

Cas d’usage réel

Dans un projet de prévision météo :

  • Stockage des températures de milliers de capteurs dans un ndarray
  • Calcul de moyennes et écarts types par région
  • Filtrage des anomalies avec conditions vectorisées
  • Transformation rapide pour visualisation ou modèle ML

Autre exemple :

  • Analyse d’images : chaque image = tableau 2D ou 3D
  • Traitement vectorisé pour appliquer un filtre ou normaliser les pixels

NumPy est donc la clé pour passer de prototypes lents à des traitements industriels.


Tableau comparatif

Type de structure Mutable Vitesse Usage principal
Liste Python Oui Faible Petits datasets
Tuple Python Non Moyenne Données fixes
ndarray NumPy Oui Très élevée Calcul scientifique et vectorisé
Pandas DataFrame Oui Moyenne-élevée Analyse tabulaire complexe

Astuce

Préférer les opérations vectorisées plutôt que les boucles Python :

arr += 1  # ajoute 1 à tous les éléments

C’est instantané même pour des millions d’éléments.


Attention

NumPy ne gère pas automatiquement les valeurs manquantes (None) :

  • Utiliser np.nan pour représenter les données manquantes
  • Fonctions comme np.isnan() pour filtrer ces valeurs

9. Pandas pour la manipulation de données

Définition approfondie

Pandas est la bibliothèque incontournable pour la manipulation et l’analyse de données tabulaires en Python. Elle fournit :

  • DataFrame : structure 2D, équivalent d’une table SQL ou d’une feuille Excel
  • Series : vecteur 1D avec index
  • Fonctions pour filtrer, transformer, agréger et joindre des données

Pandas est construit sur NumPy, ce qui permet des opérations vectorisées rapides, tout en offrant une interface intuitive pour les datasets hétérogènes ou manquants. En data science, Pandas est l’outil central pour préparer et analyser des données avant d’alimenter des modèles statistiques ou ML.


Explication avec analogie

Imagine un tableau Excel :

  • Chaque colonne = un attribut (nom, âge, salaire…)
  • Chaque ligne = un enregistrement (un employé, une transaction…)

Pandas transforme Python en bureau de données intelligent : tu peux filtrer, calculer des moyennes, détecter des anomalies et fusionner plusieurs tableaux avec quelques lignes seulement. C’est comme passer d’une calculatrice manuelle à un logiciel de gestion complet.


Bloc code commenté ligne par ligne

import pandas as pd

# Création d'un DataFrame à partir d'un dictionnaire
data = {
    "Nom": ["Ali", "Sara", "Youssef", "Lina"],
    "Age": [30, 25, 35, 28],
    "Salaire": [5000, 6000, 5500, 6200]
}

df = pd.DataFrame(data)
print(df)

# Filtrer les employés avec un salaire > 5500
df_haut_salaire = df[df["Salaire"] > 5500]
print(df_haut_salaire)

# Ajouter une nouvelle colonne calculée
df["Salaire_annuel"] = df["Salaire"] * 12
print(df)

# Trier les données par âge décroissant
df_sorted = df.sort_values(by="Age", ascending=False)
print(df_sorted)

# Agréger les données : salaire moyen
salaire_moyen = df["Salaire"].mean()
print("Salaire moyen:", salaire_moyen)

# Fusionner deux DataFrames
data_bonus = pd.DataFrame({
    "Nom": ["Ali", "Sara", "Lina"],
    "Bonus": [500, 700, 600]
})

df_complet = pd.merge(df, data_bonus, on="Nom", how="left")
print(df_complet)

Cas d’usage réel

Dans une analyse commerciale :

  • Dataset = ventes par client et produit

  • Pandas permet de :

    • filtrer les clients actifs
    • calculer le revenu moyen par catégorie
    • détecter les anomalies ou valeurs manquantes
    • fusionner plusieurs sources (clients + ventes + produits)

Autre exemple : préparation des données pour ML

  • Nettoyage des valeurs nulles
  • Transformation de colonnes catégorielles en numériques
  • Agrégation et normalisation

Sans Pandas, ces opérations demanderaient des centaines de lignes de code Python pur.


Tableau comparatif

Structure Mutable Performance Usage principal
Liste / dictionnaire Oui Moyenne Petits datasets
NumPy ndarray Oui Très élevée Calcul scientifique
Pandas DataFrame Oui Élevée Données tabulaires complexes
SQL / Excel Oui Variable Gestion externe / rapports

Astuce

Toujours vérifier les valeurs manquantes avant tout traitement :

df.isna().sum()  # compte les NaN par colonne

Attention

Les opérations sur de très gros DataFrames peuvent consommer beaucoup de mémoire.
✅ Astuce : utiliser chunksize pour lire des fichiers volumineux par morceaux.


10. Nettoyage et transformation de données

Définition approfondie

Le nettoyage et la transformation des données sont des étapes essentielles en data science pour préparer des datasets bruts en données fiables et exploitables. Ces étapes incluent :

  • Détection et traitement des valeurs manquantes (NaN)
  • Correction des valeurs aberrantes
  • Conversion de types (string → numérique, date → datetime)
  • Normalisation ou standardisation des données
  • Encodage des variables catégorielles

Un dataset non nettoyé peut générer des modèles biaisés ou des analyses incorrectes. Le nettoyage est donc souvent la partie la plus critique et la plus longue du workflow data.


Explication avec analogie

Imagine un chef cuisinier recevant des ingrédients pour un plat complexe :

  • Certains légumes sont pourris → il les retire
  • Certains ingrédients sont mal étiquetés → il corrige l’étiquette
  • Certains sont dans le mauvais format → il les coupe ou les mixe

Sans ce travail de préparation, le plat final sera raté. De la même manière, un modèle IA ou une analyse data nécessite des données propres et uniformes.


Bloc code commenté ligne par ligne

import pandas as pd
import numpy as np

# Création d'un DataFrame avec des valeurs manquantes et aberrantes
data = {
    "Nom": ["Ali", "Sara", "Youssef", "Lina", "Omar"],
    "Age": [30, 25, None, 28, 150],  # 150 est aberrant
    "Salaire": [5000, None, 5500, 6200, 5800]
}
df = pd.DataFrame(data)
print("Dataset brut:")
print(df)

# Détecter les valeurs manquantes
print("Valeurs manquantes par colonne:")
print(df.isna().sum())

# Remplacer les valeurs manquantes par la moyenne
df["Age"].fillna(df["Age"].mean(), inplace=True)
df["Salaire"].fillna(df["Salaire"].mean(), inplace=True)

# Détecter les valeurs aberrantes
df.loc[df["Age"] > 100, "Age"] = df["Age"].mean()  # Correction

# Conversion de types (exemple simple)
df["Salaire"] = df["Salaire"].astype(int)

# Normalisation du salaire (0-1)
df["Salaire_norm"] = (df["Salaire"] - df["Salaire"].min()) / (df["Salaire"].max() - df["Salaire"].min())

print("Dataset nettoyé et transformé:")
print(df)

Cas d’usage réel

Dans un projet de prédiction du churn client :

  • Dataset brut = logs d’activité, informations personnelles

  • Nettoyage :

    • valeurs manquantes dans les emails ou téléphones
    • suppression ou correction des dates incohérentes
    • encodage des catégories (ex: abonnement “Premium”, “Basique”)
  • Transformation :

    • création d’indicateurs comme nombre_visites_mois
    • normalisation pour ML

Résultat : dataset fiable et prêt pour l’entraînement de modèles prédictifs.


Tableau comparatif

Technique Usage principal Exemple concret
Détection NaN Identifier données manquantes df.isna().sum()
Remplacement NaN Remplir valeurs manquantes fillna(df.mean())
Détection valeurs aberrantes Supprimer ou corriger anomalies df.loc[df["Age"]>100] = mean
Normalisation / Standardisation Uniformiser les données pour ML (x-min)/(max-min)
Encodage catégoriel Transformer texte en numérique pd.get_dummies()

Astuce

Toujours visualiser les données après nettoyage pour vérifier les transformations :

print(df.describe())

Attention

Ne jamais supprimer aveuglément les valeurs manquantes :

  • Risque de perte d’information importante
  • Vérifier si l’imputation ou la correction est plus appropriée

11. Visualisation avec Matplotlib et Seaborn

Définition approfondie

La visualisation des données est une étape essentielle pour comprendre, analyser et communiquer les informations contenues dans un dataset. En Python, les deux bibliothèques les plus utilisées sont :

  • Matplotlib : bibliothèque de base pour tracer graphiques 2D (courbes, histogrammes, barres, scatter)
  • Seaborn : construite sur Matplotlib, offre des graphiques plus esthétiques et des fonctions pour explorer des relations complexes (corrélations, distributions, catégories)

La visualisation permet d’identifier :

  • tendances
  • anomalies
  • relations entre variables
  • patterns cachés

C’est une étape critique avant toute analyse statistique ou construction de modèle ML.


Explication avec analogie

Imagine que tu reçois une feuille Excel avec 1000 lignes de ventes :

  • Lire les chiffres à la main = inefficace
  • Tracer un graphique = tu vois immédiatement les pics, tendances, anomalies

En data science, la visualisation transforme des données brutes illisibles en informations immédiatement compréhensibles.


Bloc code commenté ligne par ligne

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# Création d'un DataFrame exemple
data = {
    "Produit": ["A", "B", "C", "D", "E"],
    "Ventes": [150, 200, 50, 400, 300],
    "Marge": [20, 25, 10, 30, 28]
}
df = pd.DataFrame(data)

# Graphique simple avec Matplotlib
plt.figure(figsize=(8,5))
plt.bar(df["Produit"], df["Ventes"], color='skyblue')
plt.title("Ventes par produit")
plt.xlabel("Produit")
plt.ylabel("Ventes")
plt.show()

# Histogramme pour distribution des marges
plt.figure(figsize=(6,4))
plt.hist(df["Marge"], bins=5, color='orange', edgecolor='black')
plt.title("Distribution des marges")
plt.show()

# Scatter plot avec Seaborn pour relation Ventes vs Marge
plt.figure(figsize=(7,5))
sns.scatterplot(data=df, x="Ventes", y="Marge", hue="Produit", s=100)
plt.title("Relation Ventes vs Marge")
plt.show()

# Boxplot pour détecter outliers
plt.figure(figsize=(6,4))
sns.boxplot(y=df["Ventes"], color="lightgreen")
plt.title("Boxplot des ventes")
plt.show()

Cas d’usage réel

Dans un projet de suivi commercial :

  • Visualiser les ventes par produit pour détecter les best-sellers
  • Analyser la corrélation entre nombre de ventes et marge
  • Détecter des anomalies (ex : ventes soudainement très basses ou très hautes)
  • Communiquer des résultats à des managers avec des graphiques clairs

Autre exemple :

  • Analyse d’un dataset de capteurs IoT
  • Tracer l’évolution de la température au fil du temps
  • Détecter des pics anormaux ou des tendances saisonnières

Tableau comparatif

Bibliothèque Usage principal Points forts Limites
Matplotlib Graphiques basiques et personnalisés Flexible, contrôle complet Code un peu verbeux
Seaborn Exploration statistique et esthétique Graphiques rapides et attrayants Moins flexible que Matplotlib
Plotly Graphiques interactifs Interactif, zoomable Installation supplémentaire

Astuce

Toujours ajouter titres, labels et légendes pour rendre le graphique compréhensible pour un tiers :

plt.title("Titre explicite")
plt.xlabel("Axe X")
plt.ylabel("Axe Y")
plt.legend()

Attention

Ne jamais tracer des données brutes sans nettoyage :

  • Les outliers ou valeurs manquantes faussent les graphiques
  • Toujours vérifier et transformer les données avant visualisation

12. Introduction aux statistiques pour la data

Définition approfondie

La statistique est la science qui permet d’analyser, résumer et interpréter les données. En data science, elle est essentielle pour comprendre les tendances et patterns avant d’appliquer des modèles. Les concepts clés incluent :

  • Moyenne, médiane, mode : mesure de tendance centrale
  • Variance et écart-type : mesure de dispersion
  • Corrélation et covariance : relations entre variables
  • Distribution : forme des données (normale, uniforme, skewed)

Les statistiques permettent non seulement d’explorer des datasets mais aussi de préparer des modèles prédictifs fiables.


Explication avec analogie

Imagine un professeur qui veut analyser les notes de sa classe :

  • Moyenne → “score typique”
  • Médiane → “score du milieu”
  • Écart-type → “dispersion des élèves”
  • Corrélation entre heures d’étude et notes → “relation cause-effet”

De la même manière, en data science, ces concepts aident à prendre des décisions basées sur les données et à détecter les anomalies.


Bloc code commenté ligne par ligne

import pandas as pd
import numpy as np

# Création d'un DataFrame d'exemple
data = {
    "Eleve": ["Ali", "Sara", "Youssef", "Lina", "Omar"],
    "Note": [12, 15, 9, 18, 14],
    "Heures_etude": [5, 8, 3, 10, 6]
}
df = pd.DataFrame(data)

# Moyenne et médiane
moyenne_note = df["Note"].mean()
mediane_note = df["Note"].median()
print("Moyenne:", moyenne_note, "Médiane:", mediane_note)

# Écart-type et variance
ecart_type = df["Note"].std()
variance = df["Note"].var()
print("Écart-type:", ecart_type, "Variance:", variance)

# Corrélation entre Note et Heures d'étude
correlation = df["Note"].corr(df["Heures_etude"])
print("Corrélation Note-Heures:", correlation)

# Histogramme pour visualiser distribution
import matplotlib.pyplot as plt
plt.hist(df["Note"], bins=5, color='skyblue', edgecolor='black')
plt.title("Distribution des notes")
plt.show()

Cas d’usage réel

Dans un projet de prédiction de performance commerciale :

  • Moyenne et écart-type pour comprendre les ventes typiques et la variabilité
  • Corrélation entre budget marketing et ventes pour détecter l’impact
  • Histogrammes et boxplots pour identifier anomalies et outliers

Autre exemple : analyse de capteurs industriels

  • Moyenne et écart-type pour chaque capteur
  • Détection de valeurs anormales (ex : vibration trop élevée)
  • Préparation de features statistiques pour ML

Tableau comparatif

Mesure Usage principal Exemple concret
Moyenne Valeur centrale Moyenne des ventes par jour
Médiane Valeur du milieu Salaire médian des employés
Mode Valeur la plus fréquente Produit le plus vendu
Écart-type Dispersion Variabilité de la température
Corrélation Relation entre variables Heures d'étude vs note

Astuce

Toujours vérifier la distribution des données avant d’interpréter la moyenne :

  • Moyenne trompeuse si distribution très asymétrique
  • Dans ce cas, privilégier médiane ou quantiles

Attention

La corrélation n’implique pas la causalité.
Une forte corrélation peut être due à un facteur externe non mesuré.


13. Introduction au Machine Learning avec scikit-learn

Définition approfondie

Le Machine Learning (ML) est une branche de l’intelligence artificielle qui permet à un ordinateur d’apprendre des données et de faire des prédictions sans être explicitement programmé pour chaque tâche. En Python, la bibliothèque scikit-learn est l’outil standard pour :

  • Préparer les données (normalisation, encodage)
  • Séparer train/test
  • Entraîner des modèles supervisés et non supervisés
  • Évaluer les performances via métriques standards

Les modèles supervisés apprennent à partir d’exemples étiquetés (entrée → sortie), tandis que les modèles non supervisés identifient des patterns dans des données sans étiquette (ex : clustering).


Explication avec analogie

Imagine un étudiant qui apprend à reconnaître les fruits :

  • On lui montre des pommes et des oranges avec leurs couleurs et tailles (données étiquetées)
  • Après quelques exemples, il peut prédire le type d’un nouveau fruit inconnu

Le ML fonctionne de manière similaire : il apprend des données historiques pour généraliser sur de nouvelles données.


Bloc code commenté ligne par ligne

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error

# Création d'un dataset exemple
data = {
    "Heures_etude": [2, 4, 6, 8, 10],
    "Note": [10, 12, 14, 16, 18]
}
df = pd.DataFrame(data)

# Séparation des features (X) et target (y)
X = df[["Heures_etude"]]  # variable indépendante
y = df["Note"]             # variable dépendante

# Division train/test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Création et entraînement du modèle
model = LinearRegression()
model.fit(X_train, y_train)

# Prédiction sur le jeu test
y_pred = model.predict(X_test)
print("Prédictions:", y_pred)

# Évaluation du modèle
mse = mean_squared_error(y_test, y_pred)
print("Mean Squared Error:", mse)

# Coefficient et intercept
print("Coefficient:", model.coef_)
print("Intercept:", model.intercept_)

Cas d’usage réel

Projet de prédiction de ventes :

  • Features : budget marketing, nombre de publicités, saison
  • Target : nombre de ventes prévues
  • Étapes : nettoyage, normalisation, séparation train/test, entraînement modèle, prédiction et évaluation

Autre exemple : détection de fraude bancaire

  • Features : montant transaction, fréquence, localisation
  • Target : frauduleux ou non
  • Résultat : modèle capable d’alerter automatiquement sur des transactions suspectes

Tableau comparatif

Modèle ML Type Usage principal Limite
Linear Regression Supervisé Prédiction continue Non adapté aux relations non linéaires
Decision Tree Supervisé Classification et régression Overfitting possible
K-Means Non supervisé Regroupement / clustering Nécessite choix du nombre de clusters
Random Forest Supervisé Prédiction robuste Plus lent, complexe

Astuce

Toujours scinder les données en train/test pour éviter le surapprentissage (overfitting) :

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

Attention

Ne jamais utiliser les mêmes données pour entraîner et tester le modèle :

  • Risque d’obtenir des performances irréalistes
  • Toujours vérifier la séparation et le shuffle

14. Prétraitement avancé pour le Machine Learning

Définition approfondie

Le prétraitement des données est une étape clé avant d’entraîner un modèle de Machine Learning. Il consiste à préparer les données brutes en un format adapté aux algorithmes, car la plupart des modèles ML n’acceptent pas directement les données hétérogènes ou manquantes. Les principales techniques incluent :

  • Normalisation / Standardisation : mise à l’échelle des variables pour que les valeurs soient comparables
  • Encodage des variables catégorielles : transformation de texte en nombres (One-Hot Encoding, Label Encoding)
  • Imputation des valeurs manquantes : remplacer NaN par la moyenne, la médiane ou une valeur spécifique
  • Détection et traitement des outliers : éviter que des valeurs extrêmes biaisent le modèle

Un prétraitement soigné augmente la précision et la robustesse du modèle.


Explication avec analogie

Imagine que tu dois préparer les ingrédients pour une recette complexe :

  • Certains légumes sont trop gros ou petits → découpage et normalisation
  • Certains ingrédients sont sous forme de texte (ex : “oui”, “non”) → conversion en chiffres
  • Certains ingrédients manquent → substitution avec équivalent disponible

De même, les modèles ML fonctionnent mieux avec des données standardisées et homogènes.


Bloc code commenté ligne par ligne

import pandas as pd
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline

# Dataset exemple
data = {
    "Age": [25, 30, None, 22, 28],
    "Salaire": [5000, 6000, 5500, None, 6200],
    "Département": ["IT", "RH", "IT", "Finance", "RH"]
}
df = pd.DataFrame(data)

# Séparer les colonnes numériques et catégorielles
numerical_features = ["Age", "Salaire"]
categorical_features = ["Département"]

# Imputation et normalisation pour les colonnes numériques
numeric_transformer = Pipeline(steps=[
    ("imputer", SimpleImputer(strategy="mean")),  # remplacer NaN par la moyenne
    ("scaler", StandardScaler())                  # standardiser (mean=0, std=1)
])

# Encodage pour les colonnes catégorielles
categorical_transformer = Pipeline(steps=[
    ("encoder", OneHotEncoder(handle_unknown="ignore"))  # transforme texte en colonnes binaires
])

# Combiner les transformations
preprocessor = ColumnTransformer(
    transformers=[
        ("num", numeric_transformer, numerical_features),
        ("cat", categorical_transformer, categorical_features)
    ]
)

# Appliquer le prétraitement
df_preprocessed = preprocessor.fit_transform(df)
print(df_preprocessed)

Cas d’usage réel

Dans un projet de prédiction du churn client :

  • Age, revenu, nombre de visites → variables numériques → standardisation
  • Abonnement, région → variables catégorielles → encodage One-Hot
  • Valeurs manquantes dans Age ou revenu → imputation par moyenne ou médiane

Résultat : dataset prêt pour l’entraînement ML, sans erreur de type ni biais dû aux valeurs manquantes.

Autre exemple : analyse de capteurs IoT

  • Mesures avec différentes unités → normalisation
  • Capteurs actifs/inactifs → encodage binaire
  • Valeurs manquantes → imputation par moyenne glissante

Tableau comparatif

Technique Usage principal Exemple concret
StandardScaler Standardiser variables numériques Age et Salaire
MinMaxScaler Normaliser entre 0 et 1 Température capteurs
OneHotEncoder Variables catégorielles en colonnes Département, Région
SimpleImputer Remplacer valeurs manquantes NaN → moyenne/mediane
Détection outliers Identifier valeurs extrêmes Salaire > 3 écarts-types

Astuce

Toujours inclure le prétraitement dans un pipeline scikit-learn pour éviter les erreurs lors de la mise en production :

from sklearn.pipeline import Pipeline
model_pipeline = Pipeline([
    ("preprocessor", preprocessor),
    ("model", LinearRegression())
])

Attention

Ne pas mélanger train/test pour le calcul de la moyenne ou de la standardisation :

  • Appliquer fit() seulement sur le jeu d’entraînement
  • Utiliser transform() sur le jeu test pour éviter les fuites de données

15. Régression linéaire et évaluation des modèles

Définition approfondie

La régression linéaire est un algorithme de machine learning supervisé utilisé pour prédire une variable continue à partir d’une ou plusieurs variables explicatives. Le modèle cherche la meilleure droite (ou hyperplan en dimensions supérieures) qui minimise l’erreur entre les prédictions et les valeurs réelles.

En parallèle, l’évaluation du modèle permet de mesurer sa performance à l’aide de métriques comme :

  • Mean Squared Error (MSE) : moyenne des carrés des erreurs
  • Root Mean Squared Error (RMSE) : racine carrée du MSE
  • : proportion de variance expliquée par le modèle

Ces mesures permettent de détecter un surapprentissage (overfitting) ou un sous-apprentissage (underfitting).


Explication avec analogie

Imagine que tu essaies de prévoir le prix d’une maison en fonction de sa surface :

  • Chaque maison = point sur un graphique
  • La régression linéaire = droite qui passe au mieux au milieu de tous les points
  • Plus la droite correspond bien aux points → meilleure précision

C’est comme tracer une tendance pour deviner ce qui se passera ensuite.


Bloc code commenté ligne par ligne

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score

# Dataset exemple : prédiction du prix selon la surface
data = {
    "Surface_m2": [50, 60, 70, 80, 90],
    "Prix": [150000, 180000, 210000, 240000, 270000]
}
df = pd.DataFrame(data)

# Séparer features (X) et target (y)
X = df[["Surface_m2"]]  # variable indépendante
y = df["Prix"]           # variable dépendante

# Split train/test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Créer et entraîner le modèle
model = LinearRegression()
model.fit(X_train, y_train)

# Prédiction
y_pred = model.predict(X_test)

# Évaluation du modèle
mse = mean_squared_error(y_test, y_pred)
rmse = mse ** 0.5
r2 = r2_score(y_test, y_pred)

print("MSE:", mse)
print("RMSE:", rmse)
print("R²:", r2)

# Coefficient et intercept
print("Coefficient:", model.coef_)
print("Intercept:", model.intercept_)

Cas d’usage réel

Projet immobilier :

  • Features : surface, nombre de chambres, localisation
  • Target : prix de vente
  • Étapes : nettoyage, transformation, entraînement modèle
  • Évaluation : RMSE pour mesurer précision, R² pour expliquer la variance

Autre exemple : prédiction de la consommation énergétique :

  • Features : température, nombre d’occupants
  • Target : consommation en kWh
  • Résultat : optimisation de la production et réduction de coûts

Tableau comparatif

Métrique Usage principal Exemple concret
Mean Squared Error (MSE) Erreur moyenne quadratique Évaluer différence entre prix prédit et réel
Root MSE (RMSE) Interprétation plus intuitive Conversion en unités réelles (ex €)
Proportion variance expliquée 0.9 → modèle explique 90% variance
Coefficient Influence d’une feature 5000 €/m² pour chaque m² supplémentaire

Astuce

Toujours visualiser la droite de régression avec les points réels pour comprendre le modèle :

import matplotlib.pyplot as plt
plt.scatter(X, y, color='blue')
plt.plot(X, model.predict(X), color='red')
plt.xlabel("Surface (m²)")
plt.ylabel("Prix (€)")
plt.show()

Attention

Ne jamais extrapoler trop loin en dehors des données utilisées pour l’entraînement :

  • Le modèle prédit mal pour des surfaces ou valeurs extrêmes
  • Toujours vérifier la cohérence des prédictions

16. Régression multiple et sélection de variables

Définition approfondie

La régression multiple est une extension de la régression linéaire simple qui permet de prédire une variable continue à partir de plusieurs variables explicatives simultanément. Elle s’écrit sous la forme :

[
y = \beta_0 + \beta_1 X_1 + \beta_2 X_2 + ... + \beta_n X_n + \epsilon
]

Où :

  • (y) = variable cible
  • (X_i) = variables indépendantes
  • (\beta_i) = coefficients à apprendre
  • (\epsilon) = erreur aléatoire

La sélection de variables consiste à choisir les features les plus pertinentes pour améliorer la performance et éviter le surapprentissage. Techniques courantes :

  • Sélection manuelle basée sur la connaissance métier
  • Méthodes statistiques : p-value, R² ajusté
  • Méthodes automatiques : RFE (Recursive Feature Elimination), Lasso

Explication avec analogie

Imagine que tu veux prédire le prix d’une maison :

  • Surface seule → régression simple
  • Surface + nombre de chambres + localisation + âge du bâtiment → régression multiple

C’est comme préparer une recette : ajouter plus d’ingrédients pertinents améliore le goût final, mais ajouter trop d’ingrédients inutiles peut gâcher le plat.


Bloc code commenté ligne par ligne

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.feature_selection import RFE
from sklearn.metrics import mean_squared_error, r2_score

# Dataset exemple
data = {
    "Surface_m2": [50, 60, 70, 80, 90],
    "Chambres": [1, 2, 2, 3, 3],
    "Age_maison": [10, 5, 8, 2, 1],
    "Prix": [150000, 180000, 210000, 240000, 270000]
}
df = pd.DataFrame(data)

# Séparer features et target
X = df[["Surface_m2", "Chambres", "Age_maison"]]
y = df["Prix"]

# Split train/test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Créer et entraîner le modèle
model = LinearRegression()
model.fit(X_train, y_train)

# Prédiction
y_pred = model.predict(X_test)

# Évaluation du modèle
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print("MSE:", mse)
print("R²:", r2)

# Coefficients
print("Coefficients:", model.coef_)
print("Intercept:", model.intercept_)

# Sélection de variables avec RFE (top 2 features)
selector = RFE(model, n_features_to_select=2)
selector.fit(X_train, y_train)
print("Support sélectionné:", selector.support_)
print("Ranking:", selector.ranking_)

Cas d’usage réel

Projet immobilier avancé :

  • Features : surface, chambres, localisation, âge, proximité école, jardin

  • Objectif : prédiction précise du prix de vente

  • Étapes :

    • Nettoyage et standardisation
    • Sélection de variables pertinentes avec RFE ou Lasso
    • Régression multiple pour prédire le prix

Autre exemple : prédiction de consommation énergétique d’un bâtiment :

  • Features : température extérieure, humidité, occupation, surface, isolation
  • Résultat : modèle précis pour optimiser chauffage et climatisation

Tableau comparatif

Méthode / Outil Usage principal Limite
Régression linéaire simple Une seule variable Trop simpliste si données multivariées
Régression multiple Plusieurs variables explicatives Sensible aux colinéarités
RFE Sélection automatique des features Peut être coûteux pour très grand dataset
Lasso Sélection + régularisation Peut éliminer certaines variables utiles si mal paramétré

Astuce

Toujours vérifier la colinéarité entre variables (corrélation > 0.8) pour éviter que deux features très liées faussent le modèle.


Attention

Ne pas ajouter toutes les variables possibles :

  • Risque de surapprentissage
  • Complexité inutile du modèle

17. Régression logistique et classification binaire

Définition approfondie

La régression logistique est un algorithme de machine learning supervisé utilisé pour prédire une variable catégorielle binaire (oui/non, 0/1). Contrairement à la régression linéaire, elle utilise la fonction sigmoïde pour contraindre les prédictions entre 0 et 1 :

[
\sigma(z) = \frac{1}{1 + e^{-z}}
]

Où (z = \beta_0 + \beta_1 X_1 + ... + \beta_n X_n). Le résultat est interprété comme une probabilité que l’événement se produise.

En évaluation, les métriques courantes incluent :

  • Accuracy : proportion de prédictions correctes
  • Precision : proportion de vrais positifs parmi les positifs prédits
  • Recall : proportion de vrais positifs détectés
  • F1-score : moyenne harmonique de precision et recall

Explication avec analogie

Imagine un médecin qui prédit si un patient est malade ou non :

  • Il observe plusieurs facteurs (symptômes, âge, analyses) → variables explicatives
  • La régression logistique combine ces facteurs pour produire une probabilité de maladie
  • Si probabilité > 0.5 → prédiction “malade”, sinon “non malade”

C’est comme utiliser une balance pour estimer si le résultat dépasse un seuil critique.


Bloc code commenté ligne par ligne

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

# Dataset exemple : prédiction de succès d’un étudiant
data = {
    "Heures_etude": [2, 4, 6, 8, 10],
    "Participation": [0, 1, 1, 1, 0],
    "Reussite": [0, 0, 1, 1, 1]  # 0 = échec, 1 = réussite
}
df = pd.DataFrame(data)

# Séparer features et target
X = df[["Heures_etude", "Participation"]]
y = df["Reussite"]

# Split train/test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Créer et entraîner le modèle
model = LogisticRegression()
model.fit(X_train, y_train)

# Prédiction
y_pred = model.predict(X_test)

# Évaluation du modèle
acc = accuracy_score(y_test, y_pred)
prec = precision_score(y_test, y_pred)
rec = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)

print("Accuracy:", acc)
print("Precision:", prec)
print("Recall:", rec)
print("F1-score:", f1)

Cas d’usage réel

Projet de détection de fraude bancaire :

  • Features : montant, localisation, heure, type transaction
  • Target : frauduleuse (1) ou non (0)
  • Étapes : prétraitement, encodage, entraînement logistique
  • Résultat : modèle capable de détecter les transactions suspectes avec un seuil de probabilité ajustable

Autre exemple : prédiction de churn client

  • Features : nombre visites, satisfaction, durée abonnement
  • Target : churn = 1 ou 0
  • Résultat : alertes préventives pour réduire la perte de clients

Tableau comparatif

Métrique / Outil Usage principal Limite
Accuracy Précision globale Trompeuse si classes déséquilibrées
Precision Vrais positifs parmi positifs prédits Ne considère pas les faux négatifs
Recall Vrais positifs détectés Ne considère pas les faux positifs
F1-score Moyenne harmonique Precision/Recall Sensible aux déséquilibres
Logistic Regression Classification binaire Limité aux relations linéaires

Astuce

Pour des classes déséquilibrées, privilégier Precision, Recall ou F1-score plutôt que l’accuracy.


Attention

Ne pas interpréter la sortie brute comme 0 ou 1 avant le seuil :

  • Utiliser la probabilité predict_proba() pour ajuster le seuil selon le contexte.

18. Évaluation avancée des modèles et courbes ROC

Définition approfondie

L’évaluation avancée des modèles de classification permet de mesurer la qualité des prédictions au-delà de l’accuracy, en particulier pour des datasets déséquilibrés. Les outils principaux incluent :

  • Matrice de confusion : tableau montrant vrais positifs (TP), vrais négatifs (TN), faux positifs (FP) et faux négatifs (FN)
  • Precision / Recall / F1-score : mesures détaillées pour chaque classe
  • Courbe ROC (Receiver Operating Characteristic) : trace le taux de vrais positifs vs taux de faux positifs pour différents seuils
  • AUC (Area Under Curve) : surface sous la courbe ROC, indicateur global de performance

Ces outils permettent de comparer et sélectionner le meilleur modèle pour des problèmes critiques.


Explication avec analogie

Imagine un système de détection de feu :

  • TP : alarme déclenchée quand il y a un vrai incendie → bon signal
  • FP : alarme déclenchée alors qu’il n’y a pas de feu → fausse alerte
  • FN : feu non détecté → catastrophe
  • TN : pas d’alarme et pas de feu → normal

La courbe ROC permet de choisir un seuil d’alerte optimal pour maximiser les TP tout en limitant les FP.


Bloc code commenté ligne par ligne

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix, classification_report, roc_curve, roc_auc_score
import matplotlib.pyplot as plt

# Dataset exemple
data = {
    "Heures_etude": [2, 4, 6, 8, 10, 1, 3, 5],
    "Participation": [0, 1, 1, 1, 0, 0, 1, 0],
    "Reussite": [0, 0, 1, 1, 1, 0, 0, 1]
}
df = pd.DataFrame(data)

# Séparation features et target
X = df[["Heures_etude", "Participation"]]
y = df["Reussite"]

# Split train/test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)

# Création et entraînement du modèle
model = LogisticRegression()
model.fit(X_train, y_train)

# Prédictions et probabilités
y_pred = model.predict(X_test)
y_prob = model.predict_proba(X_test)[:,1]  # probabilité de classe 1

# Matrice de confusion
cm = confusion_matrix(y_test, y_pred)
print("Matrice de confusion:\n", cm)

# Rapport de classification
print("Rapport de classification:\n", classification_report(y_test, y_pred))

# Courbe ROC
fpr, tpr, thresholds = roc_curve(y_test, y_prob)
auc_score = roc_auc_score(y_test, y_prob)
print("AUC:", auc_score)

plt.figure(figsize=(6,5))
plt.plot(fpr, tpr, color='blue', label=f'ROC curve (AUC = {auc_score:.2f})')
plt.plot([0,1], [0,1], color='red', linestyle='--')
plt.xlabel("Taux de faux positifs")
plt.ylabel("Taux de vrais positifs")
plt.title("Courbe ROC")
plt.legend()
plt.show()

Cas d’usage réel

Projet de détection de fraude bancaire :

  • Dataset très déséquilibré (fraudes rares)
  • L’accuracy est trompeuse → 99% correcte si on prédit toujours “non frauduleux”
  • Matrice de confusion et AUC permettent de choisir le meilleur seuil et d’optimiser la détection

Autre exemple : diagnostic médical

  • Patients malades / sains
  • Objectif : maximiser détection des vrais malades (Recall) tout en limitant fausses alertes (Precision)

Tableau comparatif

Métrique / Outil Usage principal Limite
Matrice de confusion Visualiser TP, TN, FP, FN Ne résume pas la performance globale
Precision Exactitude des positifs prédits Ne montre pas les faux négatifs
Recall Couverture des vrais positifs Ne montre pas les faux positifs
F1-score Moyenne harmonique Precision/Recall Sensible au déséquilibre
Courbe ROC / AUC Évaluer performance sur tous les seuils Ne distingue pas l’importance des classes

Astuce

Pour les datasets déséquilibrés, prioriser AUC, Recall et F1-score plutôt que l’accuracy brute.


Attention

Ne jamais se baser sur une seule métrique :

  • Accuracy peut masquer des problèmes sur des classes rares
  • Toujours combiner matrice de confusion, F1 et AUC pour une évaluation fiable

19. Clustering non supervisé avec K-Means

Définition approfondie

Le clustering est une technique de machine learning non supervisé visant à regrouper des observations similaires sans utiliser de labels. K-Means est l’algorithme le plus populaire pour cela. Son objectif est de minimiser la distance intra-cluster et maximiser la distance inter-cluster.

Fonctionnement de K-Means :

  1. Choisir (k) centres initiaux (centroids)
  2. Assigner chaque point au centre le plus proche
  3. Recalculer les centroids en fonction des points attribués
  4. Répéter jusqu’à convergence

K-Means est utilisé pour segmenter clients, détecter anomalies ou réduire la complexité des données.


Explication avec analogie

Imagine un jardinier qui doit planter des fleurs selon leur couleur :

  • Il choisit 3 zones pour regrouper les fleurs rouges, jaunes et bleues
  • Chaque fleur est placée dans la zone la plus proche
  • Les zones sont ajustées pour que chaque fleur soit bien centrée dans son groupe

De la même manière, K-Means organise les données en clusters cohérents.


Bloc code commenté ligne par ligne

import pandas as pd
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt

# Dataset exemple : clients avec Age et Dépense mensuelle
data = {
    "Age": [25, 30, 22, 40, 35, 28, 50, 48, 33, 26],
    "Depense": [200, 220, 180, 400, 360, 250, 500, 480, 300, 210]
}
df = pd.DataFrame(data)

# Création du modèle K-Means avec 3 clusters
kmeans = KMeans(n_clusters=3, random_state=42)
kmeans.fit(df)

# Récupérer les labels et centroids
labels = kmeans.labels_
centroids = kmeans.cluster_centers_

df["Cluster"] = labels
print("Dataset avec clusters:\n", df)
print("Centroids:\n", centroids)

# Visualisation
plt.scatter(df["Age"], df["Depense"], c=df["Cluster"], cmap='viridis', s=100)
plt.scatter(centroids[:,0], centroids[:,1], color='red', marker='X', s=200)
plt.xlabel("Age")
plt.ylabel("Dépense mensuelle")
plt.title("Clustering K-Means des clients")
plt.show()

Cas d’usage réel

Projet de segmentation clients pour marketing :

  • Dataset : âge, revenu, historique d’achat
  • Objectif : créer des groupes de clients homogènes pour campagnes ciblées
  • Étapes : nettoyage, normalisation, application de K-Means
  • Résultat : 3 segments distincts → messages marketing personnalisés

Autre exemple : détection d’anomalies dans un capteur industriel

  • Les points éloignés des clusters principaux sont considérés comme anomalies
  • Permet d’alerter sur dysfonctionnements sans avoir d’étiquettes

Tableau comparatif

Méthode / Outil Usage principal Limite
K-Means Regroupement de points similaires Sensible aux valeurs extrêmes et k fixe
DBSCAN Clustering basé densité Paramètres sensibles (eps, min_samples)
Agglomerative Clustering Clustering hiérarchique Coûteux en calcul pour grands datasets

Astuce

Toujours normaliser les données avant K-Means pour que toutes les variables aient la même importance :

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
df_scaled = scaler.fit_transform(df[["Age", "Depense"]])

Attention

Ne pas choisir (k) arbitrairement :

  • Utiliser méthode du coude (elbow) ou silhouette score
  • K trop petit → clusters larges et peu précis
  • K trop grand → clusters artificiellement fragmentés

20. Introduction au traitement des séries temporelles en Python

Définition approfondie

Les séries temporelles sont des séquences de données ordonnées dans le temps, souvent utilisées pour la prévision ou l’analyse de tendances. Elles apparaissent dans de nombreux domaines : finance, météo, capteurs IoT, ventes quotidiennes.

Les concepts clés incluent :

  • Trend : tendance générale à long terme
  • Seasonality : variations régulières à intervalle fixe
  • Noise : fluctuations aléatoires
  • Stationarity : propriété des données dont les statistiques ne changent pas dans le temps

Python offre des bibliothèques puissantes comme pandas, statsmodels et Prophet pour manipuler, analyser et prédire les séries temporelles.


Explication avec analogie

Imagine que tu observes la température quotidienne :

  • Trend : globalement, l’été est plus chaud que l’hiver
  • Seasonality : les jours de week-end sont souvent plus frais ou plus chauds selon l’activité
  • Noise : une journée exceptionnellement pluvieuse qui dévie de la tendance

Analyser ces séries te permet de prévoir demain ou le mois prochain, comme un météorologue ou un analyste financier.


Bloc code commenté ligne par ligne

import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.seasonal import seasonal_decompose

# Création d'un dataset exemple : ventes quotidiennes
data = {
    "Date": pd.date_range(start="2023-01-01", periods=30, freq='D'),
    "Ventes": [100, 120, 115, 130, 125, 140, 135, 150, 145, 160,
               155, 170, 165, 180, 175, 190, 185, 200, 195, 210,
               205, 220, 215, 230, 225, 240, 235, 250, 245, 260]
}
df = pd.DataFrame(data)
df.set_index("Date", inplace=True)

# Visualisation de la série
plt.figure(figsize=(10,5))
plt.plot(df.index, df["Ventes"], marker='o')
plt.title("Ventes quotidiennes")
plt.xlabel("Date")
plt.ylabel("Ventes")
plt.show()

# Décomposition en tendance, saisonnalité et résidu
result = seasonal_decompose(df["Ventes"], model='additive', period=7)
result.plot()
plt.show()

Cas d’usage réel

Projet de prévision de ventes pour un e-commerce :

  • Dataset : ventes journalières par produit
  • Objectif : anticiper le stock nécessaire
  • Étapes : nettoyage, analyse de tendance et saisonnalité, prévision avec ARIMA ou Prophet
  • Résultat : optimisation des stocks et réduction des ruptures

Autre exemple : analyse énergétique

  • Dataset : consommation horaire d’électricité
  • Objectif : identifier pics et prévoir consommation future
  • Utilisation : ajustement du système de production pour éviter pénuries

Tableau comparatif

Méthode / Outil Usage principal Limite
pandas (resample, rolling) Manipulation et visualisation séries Analyse limitée de saisonnalité
statsmodels (ARIMA) Modélisation et prévision Complexe pour séries très longues
Prophet Prévision automatique avec saisonnalité Moins flexible pour séries très bruyantes

Astuce

Toujours visualiser la série avant de modéliser pour détecter :

  • Tendances linéaires ou non linéaires
  • Saisonnalité hebdomadaire ou mensuelle
  • Anomalies ou valeurs manquantes

Attention

Les modèles de séries temporelles supposent souvent la stationnarité :

  • Si la série a un trend ou une saisonnalité forte, utiliser différenciation ou décomposition avant prédiction
  • Ne jamais mélanger données futures dans le train/test → fuite de données

Conclusion

Tu as maintenant maitrise :

  • OK Visualisation avancée avec Matplotlib et Seaborn
  • OK Statistiques descriptives et corrélations
  • OK Machine Learning supervisé et non supervisé
  • OK Prétraitement et pipelines de données
  • OK Régression simple et multiple
  • OK Régression logistique et évaluation des modèles
  • OK Clustering K-Means et segmentation
  • OK Séries temporelles et décomposition

Etape suivante recommandée : Explorer les modèles avancés de Machine Learning et Deep Learning avec scikit-learn et PyTorch pour construire des prédictions plus complexes et des réseaux neuronaux adaptés aux séries temporelles et images.

Accédez à des centaines d'examens QCM — Découvrir les offres Premium