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.
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
- Manipulation avancée des variables et structures
- Logique conditionnelle appliquée aux données
- Boucles intelligentes et optimisation
- Fonctions modulaires et réutilisables
- Structures de données complexes
- Introduction aux fichiers et flux de données
- Manipulation avancée de listes et dictionnaires
- Compréhension profonde de NumPy
- Pandas pour la manipulation de données
- Nettoyage et transformation de données
- Visualisation avec Matplotlib et Seaborn
- Introduction aux statistiques pour la data
- Probabilités appliquées
- Introduction au Machine Learning
- Préparation des données pour ML
- Modèles supervisés
- Évaluation des modèles
- Introduction au Deep Learning
- Automatisation et pipelines data
- 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 :
- Fonction de nettoyage
- Fonction de transformation
- Fonction de calcul
- 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.nanpour 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
- création d’indicateurs comme
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
NaNpar 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
- R² : 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 €) |
| R² | 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 :
- Choisir (k) centres initiaux (centroids)
- Assigner chaque point au centre le plus proche
- Recalculer les centroids en fonction des points attribués
- 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.