documentation available both in english and french
This commit is contained in:
parent
20f4f1652b
commit
f074ebb4f4
13 changed files with 672 additions and 170 deletions
62
README.fr.md
Normal file
62
README.fr.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# Projet Air Paradis – Analyse de sentiments
|
||||
|
||||
📘 Ce projet est également disponible en [anglais 🇬🇧](./README.md)
|
||||
|
||||
Ce dépôt contient les notebooks et le code source du projet d’analyse de sentiments sur des tweets, réalisé dans le cadre du programme OpenClassrooms **"Air Paradis"**.
|
||||
|
||||
---
|
||||
|
||||
## Contexte métier
|
||||
|
||||
L’objectif est de prédire si un tweet (ou une courte expression écrite) est perçu comme **positif ou négatif**, dans le contexte d’une compagnie aérienne.
|
||||
Le projet repose sur le jeu de données public **Sentiment140**.
|
||||
|
||||
---
|
||||
|
||||
## Description du projet
|
||||
|
||||
Le projet vise à développer un système complet d’analyse de sentiments, comprenant :
|
||||
|
||||
- Une analyse exploratoire des données textuelles,
|
||||
- Une comparaison de plusieurs modèles de classification (classiques, avancés et à l’état de l’art),
|
||||
- Le déploiement d’une API REST exposant un modèle avancé (embeddings + LSTM),
|
||||
- La mise en place d’un pipeline CI/CD pour automatiser les tests et le déploiement,
|
||||
- Un hébergement local sur un serveur NAS pour garantir la souveraineté des données.
|
||||
|
||||
---
|
||||
|
||||
## Structure du dépôt
|
||||
|
||||
- `notebooks/` : notebooks d’analyse et de modélisation,
|
||||
- `deployment/` : code de l’API, tests, Dockerfile et fichiers liés au déploiement,
|
||||
- `docs/` : documentation et ressources associées,
|
||||
- `../.github/workflows/` : pipelines CI/CD.
|
||||
|
||||
---
|
||||
|
||||
## Entraînement des modèles
|
||||
|
||||
Les phases d’entraînement ont principalement été réalisées sur **Google Colab**, afin de bénéficier de ressources GPU nécessaires aux modèles de deep learning.
|
||||
|
||||
---
|
||||
|
||||
## Utilisation
|
||||
|
||||
Les notebooks détaillent les étapes d’analyse et d’entraînement.
|
||||
L’API est disponible dans le dossier `deployment/api`.
|
||||
|
||||
---
|
||||
|
||||
## Remarques
|
||||
|
||||
- Les fichiers `requirements.txt` dans `notebooks/` proviennent des environnements Google Colab et peuvent contenir des dépendances peu optimisées pour un usage local.
|
||||
- Le fichier `.env`, exclu du dépôt, contient les variables d’environnement nécessaires.
|
||||
|
||||
---
|
||||
|
||||
Ce README sera mis à jour progressivement au fur et à mesure de l’avancement du projet.
|
||||
Certains commentaires de code peuvent rester en français (ainsi que les cellules Markdown des notebooks). Tout sera traduit en anglais ultérieurement.
|
||||
|
||||
---
|
||||
|
||||
**Projet réalisé dans le cadre du parcours "Data Scientist – Projet 7" d’OpenClassrooms**
|
||||
11
README.md
11
README.md
|
|
@ -1,4 +1,6 @@
|
|||
# Air Paradis Project - Sentiment Analysis
|
||||
# Air Paradis Project – Sentiment Analysis
|
||||
|
||||
📘 This project is also available in [French 🇫🇷](./README.fr.md)
|
||||
|
||||
This repository contains the notebooks and source code for the sentiment analysis project on tweets, carried out as part of the OpenClassrooms "Air Paradis" program.
|
||||
|
||||
|
|
@ -6,7 +8,8 @@ This repository contains the notebooks and source code for the sentiment analysi
|
|||
|
||||
## Business Context
|
||||
|
||||
The goal is to predict whether a tweet, or a short written expression, is perceived as positive or negative, in the context of an airline company. The project is based on the public **Sentiment140** dataset.
|
||||
The goal is to predict whether a tweet, or a short written expression, is perceived as **positive or negative**, in the context of an airline company.
|
||||
The project is based on the public **Sentiment140** dataset.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -51,8 +54,8 @@ The notebooks detail the analysis and training steps. The API is available in `d
|
|||
---
|
||||
|
||||
This README will be updated progressively as the project advances.
|
||||
Some code comments can remain in french language (as well as the notebooks markdowns etc.). All will be changed into english in the future.
|
||||
Some code comments can remain in French (as well as notebook markdowns). All will be translated into English later.
|
||||
|
||||
---
|
||||
|
||||
**Project completed as part of the OpenClassrooms "Data Scientist - Project 7" program**
|
||||
**Project completed as part of the OpenClassrooms "Data Scientist – Project 7" program**
|
||||
|
|
|
|||
128
deployment/README.fr.md
Normal file
128
deployment/README.fr.md
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
# Déploiement de l’API – Projet Air Paradis
|
||||
|
||||
📘 Cette documentation est aussi disponible en [anglais 🇬🇧](./README.md)
|
||||
|
||||
Ce dossier contient le code et la configuration nécessaires au déploiement de l’API de prédiction de sentiment.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Objectif
|
||||
|
||||
Déployer une API REST permettant de :
|
||||
|
||||
- Prédire le **sentiment d’un tweet** (positif ou négatif) à partir d’un modèle LSTM entraîné sur des embeddings (Word2Vec ou GloVe),
|
||||
- Signaler les erreurs de prédiction.
|
||||
|
||||
L’API utilise le **meilleur modèle enregistré** dans MLflow et le sert via **FastAPI**.
|
||||
|
||||
---
|
||||
|
||||
## 📦 Architecture globale
|
||||
|
||||
Schéma :
|
||||
|
||||
```
|
||||
┌──────────────────────────────┐
|
||||
│ Utilisateur final (UI) │
|
||||
│ (interface Streamlit) │
|
||||
└────────────┬─────────────────┘
|
||||
│
|
||||
[Appel HTTP vers /predict]
|
||||
│
|
||||
┌────────────▼─────────────┐
|
||||
│ API FastAPI │
|
||||
│ (serveur lancé via │
|
||||
│ Uvicorn) │
|
||||
└────────────┬─────────────┘
|
||||
│
|
||||
Chargement du modèle (MLflow)
|
||||
│
|
||||
Prétraitement du tweet
|
||||
│
|
||||
Prédiction (inférence)
|
||||
│
|
||||
Réponse JSON avec le sentiment
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Fonctionnement de l’API
|
||||
|
||||
1. **Chargement du modèle**
|
||||
- Le meilleur modèle est enregistré dans MLflow sous le nom `SentimentAnalysisLSTM`, avec le stage `Production`.
|
||||
- L’API le charge au démarrage via l’URI :
|
||||
|
||||
```
|
||||
models:/SentimentAnalysisLSTM/Production
|
||||
```
|
||||
|
||||
2. **Prétraitement du texte**
|
||||
- Nettoyage, tokenisation, lemmatisation, puis conversion en vecteurs d’embedding.
|
||||
|
||||
3. **Prédiction**
|
||||
- Le modèle LSTM prédit le sentiment.
|
||||
- Le résultat (`positive` ou `negative`) est retourné en JSON.
|
||||
|
||||
4. **Interface utilisateur (optionnelle)**
|
||||
- Une interface Streamlit permet une interaction visuelle avec l’API.
|
||||
|
||||
---
|
||||
|
||||
## 🐳 Déploiement via Docker
|
||||
|
||||
Un `Dockerfile` est fourni pour simplifier le déploiement sur tout hôte compatible Docker (NAS, cloud, etc.).
|
||||
|
||||
L’image Docker est poussée sur DockerHub à chaque version validée (voir CI/CD plus bas).
|
||||
|
||||
Par souci de **souveraineté des données**, le déploiement est préféré sur un **NAS équipé d’un processeur Intel N100** (peu énergivore et suffisant pour l’inférence LSTM).
|
||||
|
||||
Le redéploiement peut être automatisé via :
|
||||
- une tâche `cron` simple, ou
|
||||
- un conteneur **Watchtower** (dans docker-compose ou kubernetes).
|
||||
|
||||
**Commande pour test local :**
|
||||
|
||||
```bash
|
||||
docker build -t sentiment-api .
|
||||
docker run --rm --env-file ../../.env -p 8000:8000 -p 8080:8080 sentiment-api
|
||||
```
|
||||
|
||||
En production, les variables d’environnement doivent être définies dans le `docker-compose.yml` ou via un gestionnaire de secrets.
|
||||
|
||||
---
|
||||
|
||||
## 🛠 Problèmes AVX2 / Déploiement cloud
|
||||
|
||||
**Mise à jour :** au départ, le NAS ne supportait pas les instructions AVX2 nécessaires à TensorFlow.
|
||||
En réalité, les CPU N100 les prennent en charge, mais certains fabricants désactivent cette option dans le BIOS.
|
||||
|
||||
En attendant un accès physique au NAS, nous avons opté pour un déploiement sur **Google Cloud**.
|
||||
Problème : un seul port peut être exposé publiquement sur ces services.
|
||||
|
||||
Deux solutions possibles :
|
||||
- Séparer le backend (FastAPI) et le frontend (Streamlit) en deux conteneurs,
|
||||
- Utiliser un **reverse proxy** (ex. : nginx) pour rediriger les ports.
|
||||
|
||||
➡️ Nous avons choisi la **deuxième solution**, pour garder une **seule image Docker**.
|
||||
|
||||
**Mise à jour 2 :** AVX2 a été activé via le BIOS. Le déploiement est donc opérationnel **à la fois en local (NAS)** et **sur le cloud**, avec déploiement automatique pour le NAS (voir section suivante).
|
||||
|
||||
---
|
||||
|
||||
## 🔁 CI/CD – GitHub Actions
|
||||
|
||||
Un pipeline est défini dans `.github/workflows/` pour :
|
||||
|
||||
- Lancer les tests unitaires à chaque `push`,
|
||||
- Vérifier la stabilité de l’API avant déploiement (NAS ou cloud),
|
||||
- Construire et pousser l’image Docker sur DockerHub.
|
||||
|
||||
Les tests sont situés dans :
|
||||
|
||||
```
|
||||
deployment/api/tests/
|
||||
```
|
||||
|
||||
Le redéploiement automatique sur le NAS est géré via **Watchtower**, qui surveille les mises à jour de l’image Docker (fonctionne comme un `cron`, avec logs).
|
||||
|
||||
---
|
||||
|
|
@ -1,14 +1,19 @@
|
|||
# API Deployment - Air Paradis Project
|
||||
# API Deployment – Air Paradis Project
|
||||
|
||||
📘 This documentation is also available in [French 🇫🇷](./README.fr.md)
|
||||
|
||||
This folder contains the code and configuration necessary to deploy the sentiment prediction API.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Objective
|
||||
|
||||
Deploy a REST API that allows to:
|
||||
- predict the sentiment of a tweet (positive or negative) based on an LSTM model trained on embeddings (Word2Vec or GloVe).
|
||||
- report prediction errors
|
||||
|
||||
The API uses the best-performing model, registered on MLflow, and serves it via FastAPI.
|
||||
- Predict the sentiment of a tweet (positive or negative) using an LSTM model trained on embeddings (Word2Vec or GloVe),
|
||||
- Report prediction errors.
|
||||
|
||||
The API uses the best-performing model registered on MLflow and serves it via FastAPI.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -16,6 +21,7 @@ The API uses the best-performing model, registered on MLflow, and serves it via
|
|||
|
||||
Diagram:
|
||||
|
||||
```
|
||||
┌──────────────────────────────┐
|
||||
│ End user (UI) │
|
||||
│ (Streamlit interface) │
|
||||
|
|
@ -36,72 +42,85 @@ Diagram:
|
|||
Prediction (inference)
|
||||
│
|
||||
Sentiment response (JSON)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 API Workflow
|
||||
|
||||
1. Model loading
|
||||
- The best performing model is registered in MLflow under a fixed name (`SentimentAnalysisLSTM`) and a stage `Production`.
|
||||
- The API loads this model at startup using a stable URI:
|
||||
1. **Model loading**
|
||||
- The best performing model is registered in MLflow under a fixed name (`SentimentAnalysisLSTM`) and a `Production` stage.
|
||||
- The API loads this model at startup using the URI:
|
||||
|
||||
```
|
||||
models:/SentimentAnalysisLSTM/Production
|
||||
```
|
||||
|
||||
2. Text preprocessing
|
||||
- The text sent by the user is cleaned, tokenized, lemmatized, and transformed into vectors (embeddings).
|
||||
2. **Text preprocessing**
|
||||
- Text is cleaned, tokenized, lemmatized, and converted into vectors (embeddings).
|
||||
|
||||
3. Prediction
|
||||
- The LSTM model (loaded from MLflow) performs inference.
|
||||
- The result (`positive` or `negative`) is returned as a JSON response.
|
||||
3. **Prediction**
|
||||
- The LSTM model (loaded from MLflow) makes a prediction.
|
||||
- The result (`positive` or `negative`) is returned as JSON.
|
||||
|
||||
4. User interface (optional)
|
||||
4. **User interface (optional)**
|
||||
- A Streamlit interface allows visual interaction with the API.
|
||||
|
||||
---
|
||||
|
||||
## 🐳 Deployment with Docker
|
||||
|
||||
A Dockerfile is provided to facilitate deploying the API on any Docker-compatible host (NAS, cloud, etc.).
|
||||
A `Dockerfile` is provided for easy deployment on any Docker-compatible host (NAS, cloud, etc.).
|
||||
|
||||
This Docker image should be pushed to DockerHub at each validated versioning (see the CI/CD section below).
|
||||
This Docker image should be pushed to DockerHub with every validated version (see CI/CD below).
|
||||
|
||||
For data sovereignty reasons, deployment will preferably be done on a NAS equipped with an Intel N100 processor (energy efficient but probably sufficient for LSTM inference).
|
||||
Docker can be redeployed each time the docker image on DockerHub is updated. Man can use `cron` instruction (simple) or `Watchtower` docker (docker-compose / kubernetes context).
|
||||
For data sovereignty, deployment is preferably done on a **NAS with Intel N100** CPU (energy-efficient, sufficient for inference).
|
||||
Docker can be automatically redeployed using:
|
||||
- `cron` (simple), or
|
||||
- `Watchtower` in docker-compose/kubernetes setups.
|
||||
|
||||
For running the Docker image locally (development), it is important to provide the `.env` file containing environment variables and to open the FastAPI and Streamlit ports for testing the application.
|
||||
|
||||
Example commands to build and run:
|
||||
**Development command (local test):**
|
||||
|
||||
```bash
|
||||
docker build -t sentiment-api .
|
||||
docker run --env-file ../../.env -p 8000:8000 -p 8080:8080 sentiment-api
|
||||
docker run --rm --env-file ../../.env -p 8000:8000 -p 8080:8080 sentiment-api
|
||||
```
|
||||
|
||||
For deployment on a personal or public cloud (with docker-compose, Kubernetes), it is preferable to specify the necessary environment variables in `docker-compose.yml` or in secrets.
|
||||
|
||||
Add the `--rm` argument so that the container is removed after stopping.
|
||||
|
||||
**UPDATE** : in our case, we encountered some issues with the NAS which CPU is not able to run AVX2 instructions so we are obliged to deploy it on a "standard" public cloud service. To be precise, N100 CPU is normally able to run AXV2 instructions but some NAS/home server motherboard manufacturers sometimes disable this feature. Maybe is it possible to renable it on the BIOS, but I am away from my NAS so it will have to wait.
|
||||
|
||||
So, we decided to use Google Cloud. A common issue arises here: we cannot expose multiple ports (contrary to the instruction above) on a cloud service.
|
||||
|
||||
Two options are possible:
|
||||
|
||||
- Separate the service into two dockers (one for FastAPI backend and one for Streamlit frontend)
|
||||
- Configure a reverse proxy like nginx to redirect requests to different internal ports
|
||||
|
||||
We decided to keep the second solution to install the API from a single Docker container.
|
||||
|
||||
**UPDATE 2** : AVX2 instructions have been enabled by accessing the home server motherboard BIOS. So the deployment is also done here and complete continuous deployment will be done as well.
|
||||
In production (e.g. via docker-compose or cloud services), environment variables must be defined in the compose file or secret manager.
|
||||
|
||||
---
|
||||
|
||||
## 🔁 Continuous Integration / Continuous Deployment
|
||||
## 🛠 Notes on AVX2 / Cloud Deployment
|
||||
|
||||
A GitHub Actions pipeline (CI/CD) is planned at the very root of the repo to:
|
||||
**Update:** the NAS initially failed due to lack of AVX2 support. Some N100-based NAS motherboards disable AVX2 in BIOS.
|
||||
|
||||
- Automatically run unit tests at every push on the GitHub repository.
|
||||
- Ensure API stability before any deployment (NAS or cloud).
|
||||
- Update the Dockerfile and push it to DockerHub.
|
||||
When not accessible, fallback deployment is done on **Google Cloud**.
|
||||
Issue: public cloud services do **not allow multiple ports** to be exposed easily.
|
||||
|
||||
Unit tests will be defined in `./deployment/api/tests/`
|
||||
Two solutions:
|
||||
- Split into two containers: FastAPI + Streamlit,
|
||||
- Use a **reverse proxy** (e.g., Nginx) to map ports.
|
||||
|
||||
- API docker is automatically updated on home server docker using watchtower docker (= cron with logging options)
|
||||
➡️ We chose the second option to keep a **single Docker image**.
|
||||
|
||||
**Update 2:** AVX2 was enabled via BIOS. Deployment is now active **both locally (NAS)** and **on cloud**, with continuous deployment on NAS (see section below).
|
||||
|
||||
---
|
||||
|
||||
## 🔁 CI/CD – GitHub Actions
|
||||
|
||||
A pipeline is defined in `.github/workflows/` to:
|
||||
|
||||
- Run unit tests on every push,
|
||||
- Check API health before deployment (local/cloud),
|
||||
- Build and push Docker image to DockerHub.
|
||||
|
||||
Tests are defined in:
|
||||
|
||||
```
|
||||
deployment/api/tests/
|
||||
```
|
||||
|
||||
Docker image auto-redeployment on NAS is handled by **Watchtower**, which checks DockerHub updates (like a cron job, with logs).
|
||||
|
||||
---
|
||||
|
|
|
|||
235
docs/blog.fr.md
Normal file
235
docs/blog.fr.md
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
# ✨ Analyse de sentiments et déploiement MLOps : retour d’expérience complet
|
||||
|
||||
Dans le cadre du projet *Air Paradis*, nous avons mis en œuvre une chaîne complète d’analyse de sentiments à partir de tweets, depuis la modélisation jusqu’au déploiement MLOps. Ce billet de blog revient sur les étapes clés du projet : choix méthodologiques, comparaison des modèles, mise en production d’une API robuste, et déploiement sur deux environnements (local + cloud). 🧠🔧
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Trois approches de modélisation supervisée
|
||||
|
||||
Nous avons testé trois approches complémentaires pour prédire le sentiment d’un tweet. Chacune repose sur une représentation textuelle différente et un algorithme d’apprentissage adapté :
|
||||
|
||||
### 1. 🧱 Approche simple : Bag-of-Words (BoW) + modèles de machine learning
|
||||
|
||||
On vectorise les tweets via BoW ou BoW + TF-IDF, qui comptent la fréquence des mots.
|
||||
Contrairement à d'autres projets NLP, nous avons évité LDA (non supervisé, orienté topic modeling).
|
||||
|
||||
➡️ **Modèles testés** :
|
||||
- Régression Logistique
|
||||
- Naive Bayes
|
||||
- SVM
|
||||
- Random Forest
|
||||
|
||||
Ces modèles sont entraînés avec **GridSearchCV**, en optimisant la **précision (`precision`)**, notre KPI métier. Différents KPI ont été calculés sur l'ensemble de test.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
### 2. 🔥 Approche avancée : Word Embeddings + LSTM
|
||||
|
||||
Nous utilisons des vecteurs denses Word2Vec (entraînés) et GloVe 300d (préentraînés par Stanford), qui capturent les similarités sémantiques entre mots. Ces représentations ne prennent toutefois **pas en compte le contexte** exact (ex : "annulé" est probablement un mot très négatif pour un vol mais positif pour un procès contenant des charges contre vous).
|
||||
|
||||
La classification est réalisée par un **LSTM**, capable d'exploiter la séquentialité des mots.
|
||||
Le **modèle déployé est automatiquement sélectionné** entre Word2Vec + LSTM et GloVe + LSTM, selon la **précision maximale enregistrée dans MLFlow**.
|
||||
|
||||
Modèle `Word2Vec + LSTM` (`test_precision : 0.797 , val_precision : 0.795`):
|
||||

|
||||
Modèle `GloVe 300d + LSTM` (`test_precision : 0.792 , val_precision : 0.798`):
|
||||

|
||||
|
||||
Bien que GloVe 300d + LSTM présente un score de précision légèrement supérieur à Word2Vec + LSTM sur l'ensemble de validation, il reste inférieur pour l'ensemble de test (relativement négligeable dans l'absolu).
|
||||
|
||||
---
|
||||
|
||||
### 3. 🤖 Approche transformer : DistilBERT, embeddings contextuels allégés
|
||||
|
||||
Nous avons utilisé **DistilBERT**, une version plus légère et plus rapide de BERT (créée par Hugging Face).
|
||||
Il conserve **95 % de la performance de BERT** tout en étant **40 % plus petit** et **60 % plus rapide**, ce qui le rend particulièrement adapté à un **entraînement sur GPU limité** (Google Colab) et à une **inférence plus rapide**.
|
||||
|
||||
Comme BERT, DistilBERT produit des **embeddings contextuels**, c’est-à-dire que le sens des mots varie selon leur contexte. Par exemple, *"banque"* dans *"je vais à la banque"* et *"banque de données"* n’aura pas le même vecteur.
|
||||
|
||||
Il a été **fine-tuné** ici pour une classification binaire (positif/négatif), avec un tokenizer et un encodage spécifiques à son architecture.
|
||||
|
||||
> **Modèle `DistilBERT`** (`test_precision : 0.861 , val_precision : 0.858`)
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
⚠️ **Limites** : comme tous les modèles préentraînés, DistilBERT **n’est pas sensible à l’ironie, aux jeux de mots, ni aux références culturelles implicites**.
|
||||
Or, Twitter est un terrain de jeu idéal pour ce genre de contenus détournés. Ces limites s’appliquent aussi à Word2Vec, GloVe et aux modèles classiques.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Pourquoi optimiser la précision (et non l'accuracy) ?
|
||||
|
||||
**Accuracy** = proportion de bonnes prédictions globales.
|
||||
**Precision** = proportion de tweets *prévus positifs* qui sont *vraiment positifs*.
|
||||
|
||||
> Exemple : sur 100 tweets, si le modèle prédit 30 positifs, mais 15 sont des erreurs, la précision est de 50 %.
|
||||
|
||||
Nous avons préféré **minimiser les faux positifs**, car dans un contexte sensible, **annoncer un tweet positif alors qu’il est négatif peut être problématique**.
|
||||
|
||||
- Modèles classiques : **GridSearchCV optimisé sur la précision**
|
||||
- Modèles DL : **EarlyStopping sur val_loss**, mais **sélection finale sur la précision**
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Environnement MLOps souverain
|
||||
|
||||
### 🖥️ Serveur personnel NAS + OpenMediaVault
|
||||
|
||||
MLFlow est installé sur un **NAS personnel (Intel N100)**, sous **OpenMediaVault (Debian)**.
|
||||
Nous utilisons **MinIO** pour stocker artefacts et modèles, garantissant une gestion locale, souveraine et compatible S3.
|
||||
|
||||
> Les notebooks, exécutés sur Google Colab pour bénéficier de GPU, loggent dans MLFlow et envoient les modèles vers MinIO via des **variables d’environnement**.
|
||||
|
||||
Dashboard Expériences MLFlow :
|
||||

|
||||
|
||||
Modèles en production (registre de modèles):
|
||||

|
||||
|
||||
Meilleur modèle non BERT retenu :
|
||||

|
||||

|
||||
---
|
||||
|
||||
## 🧪 CI, tests et versioning
|
||||
|
||||
### ✅ Tests unitaires
|
||||
|
||||
- Vérifient le bon fonctionnement du prétraitement, des prédictions et de la gestion d’erreurs.
|
||||
- Intégrés à **GitHub Actions**, **ils bloquent le déploiement si les tests échouent.**
|
||||
|
||||
### 🐳 Conteneurisation & CI/CD
|
||||
|
||||
L’API FastAPI est packagée via Docker, puis poussée sur DockerHub.
|
||||
Un [pipeline CI/CD](https://github.com/GrgMdmn/OpenClassrooms_AI_Projects/blob/main/.github/workflows/p7_ci-cd.yml) complet garantit **un déploiement reproductible**. Il assure:
|
||||
- La validation de tests unitaires
|
||||
- La construction et le push de l'api conteneurisée sur dockerhub
|
||||
|
||||

|
||||
---
|
||||
|
||||
## 🚀 Déploiement de l’API FastAPI (double)
|
||||
|
||||
### 🔧 Backend : FastAPI
|
||||
|
||||
- Expose un endpoint `/predict`
|
||||
- Charge dynamiquement le **meilleur modèle Word Embedding + LSTM** via le *Model Registry* MLFlow
|
||||
- Applique les bons embeddings selon le tag `embedding_type`
|
||||
|
||||
### 💻 Interface Streamlit
|
||||
|
||||
Interface locale pour tester les requêtes, debug, démonstrations.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
### 🌐 Double déploiement (NAS + Google Cloud)
|
||||
|
||||
#### 🔧 Problème AVX2
|
||||
|
||||
Initialement, l’API ne fonctionnait pas sur le NAS (processeur Intel N100), car celui-ci ne prenait pas en charge les instructions **AVX2**, requises par TensorFlow.
|
||||
|
||||
> 🛠️ **Solution** : activation manuelle du support AVX2 dans le BIOS. Cette option est souvent désactivée par défaut sur les cartes mères orientées NAS pour des raisons de consommation énergétique ou de stabilité.
|
||||
|
||||
Depuis cette modification, le NAS peut exécuter l’API sans erreurs.
|
||||
|
||||
---
|
||||
|
||||
#### 🚀 API déployées
|
||||
|
||||
Le projet propose un **double déploiement** de l’API, en local et dans le cloud :
|
||||
|
||||
- 🏠 **NAS local** : [sentiment-api.greg-madman-nas.duckdns.org](https://sentiment-api.greg-madman-nas.duckdns.org)\
|
||||
Interface Docker Compose sur le NAS :
|
||||

|
||||
|
||||
- ☁️ **Google Cloud Run** : [sentiment-api-service-7772256003.europe-west1.run.app](https://sentiment-api-service-7772256003.europe-west1.run.app)\
|
||||
Interface de déploiement Google Cloud :
|
||||

|
||||
|
||||
---
|
||||
|
||||
#### 🔄 Déploiement continu automatisé (NAS uniquement)
|
||||
|
||||
Pour assurer un **déploiement continu** sur le NAS, il a été choisi d'installer [**Watchtower**](https://containrrr.dev/watchtower/arguments/) pour rester dans un logique d'environnement 100% `docker`. Cet outil surveille toutes les **10 minutes** l’image Docker de l’API (`sentiment_api`) et, en cas de nouvelle version disponible sur DockerHub, redémarre automatiquement le conteneur avec la dernière image.
|
||||

|
||||
|
||||
> Un **système d’alerte mail** notifie automatiquement toute mise à jour effectuée.
|
||||

|
||||
|
||||
Ce mécanisme garantit que la version déployée sur le NAS reste toujours synchronisée avec la dernière version validée par les tests sur GitHub Actions, **sans intervention manuelle**.
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 📊 Monitoring maison
|
||||
|
||||
Une logique d’alerte légère embarquée dans l’API :
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
Si **3 erreurs de prédiction** consécutives sont détectées sur une **fenêtre de 5 min**, un rapport est généré automatiquement.
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Schéma global du pipeline MLOps
|
||||
|
||||
### Schéma synthétique
|
||||
```
|
||||
┌────────────┐
|
||||
│ Données │
|
||||
│ (tweets) │
|
||||
└─────┬──────┘
|
||||
│
|
||||
Prétraitement (regex, tokenisation, lemmatisation, stopwords)
|
||||
│
|
||||
┌─────────▼──────────┐
|
||||
│ Entraînement ML │
|
||||
└─────────┬──────────┘
|
||||
│
|
||||
Log via MLFlow + artefacts MinIO
|
||||
│
|
||||
Sélection du meilleur modèle "avancé" (hors BERT) selon précision
|
||||
│
|
||||
┌─────────▼──────────┐
|
||||
│ API FastAPI │
|
||||
│ + Streamlit │
|
||||
└─────────┬──────────┘
|
||||
│
|
||||
Déploiement :
|
||||
├─ Google Cloud Run (manuel)
|
||||
└─ NAS local (automatisé via Watchtower)
|
||||
│
|
||||
┌──────────▼─────────────┐
|
||||
│ Monitoring léger maison│
|
||||
│ (alertes sur mauvaises │
|
||||
│ prédictions) │
|
||||
└────────────────────────┘
|
||||
```
|
||||
### Schéma détaillé
|
||||

|
||||
|
||||
---
|
||||
|
||||
## ✨ Conclusion
|
||||
|
||||
Ce projet démontre comment construire une chaîne MLOps complète, autonome et reproductible pour du NLP appliqué à Twitter.
|
||||
Il souligne les **forces et limites des modèles** (y compris BERT), la nécessité d’une métrique adaptée au contexte (précision vs accuracy), et l’importance d’un **déploiement maîtrisé**, même sur une infrastructure personnelle.
|
||||
|
||||
---
|
||||
|
||||
💬 Merci pour votre lecture !
|
||||
239
docs/blog.md
239
docs/blog.md
|
|
@ -1,235 +1,244 @@
|
|||
# ✨ Analyse de sentiments et déploiement MLOps : retour d’expérience complet
|
||||
# ✨ Sentiment Analysis and MLOps Deployment: A Complete Experience Report
|
||||
|
||||
Dans le cadre du projet *Air Paradis*, nous avons mis en œuvre une chaîne complète d’analyse de sentiments à partir de tweets, depuis la modélisation jusqu’au déploiement MLOps. Ce billet de blog revient sur les étapes clés du projet : choix méthodologiques, comparaison des modèles, mise en production d’une API robuste, et déploiement sur deux environnements (local + cloud). 🧠🔧
|
||||
As part of the *Air Paradis* project, we implemented a full sentiment analysis pipeline from tweets, covering everything from modeling to MLOps deployment. This blog post reviews the key project stages: methodological choices, model comparison, deployment of a robust API, and deployment on two environments (local + cloud). 🧠🔧
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Trois approches de modélisation supervisée
|
||||
## 🔍 Three Supervised Modeling Approaches
|
||||
|
||||
Nous avons testé trois approches complémentaires pour prédire le sentiment d’un tweet. Chacune repose sur une représentation textuelle différente et un algorithme d’apprentissage adapté :
|
||||
We tested three complementary approaches to predict the sentiment of a tweet. Each relies on a different text representation and a suitable learning algorithm:
|
||||
|
||||
### 1. 🧱 Approche simple : Bag-of-Words (BoW) + modèles de machine learning
|
||||
### 1. 🧱 Simple Approach: Bag-of-Words (BoW) + Machine Learning Models
|
||||
|
||||
On vectorise les tweets via BoW ou BoW + TF-IDF, qui comptent la fréquence des mots.
|
||||
Contrairement à d'autres projets NLP, nous avons évité LDA (non supervisé, orienté topic modeling).
|
||||
Tweets are vectorized using BoW or BoW + TF-IDF, which count word frequencies.
|
||||
Unlike other NLP projects, we avoided LDA (unsupervised, topic modeling oriented).
|
||||
|
||||
➡️ **Modèles testés** :
|
||||
- Régression Logistique
|
||||
➡️ **Tested models**:
|
||||
- Logistic Regression
|
||||
- Naive Bayes
|
||||
- SVM
|
||||
- Random Forest
|
||||
|
||||
Ces modèles sont entraînés avec **GridSearchCV**, en optimisant la **précision (`precision`)**, notre KPI métier. Différents KPI ont été calculés sur l'ensemble de test.
|
||||
These models are trained with **GridSearchCV**, optimizing **precision (`precision`)**, our key business KPI. Various KPIs were computed on the test set.
|
||||
|
||||

|
||||

|
||||
|
||||
---
|
||||
|
||||
### 2. 🔥 Approche avancée : Word Embeddings + LSTM
|
||||
### 2. 🔥 Advanced Approach: Word Embeddings + LSTM
|
||||
|
||||
Nous utilisons des vecteurs denses Word2Vec (entraînés) et GloVe 300d (préentraînés par Stanford), qui capturent les similarités sémantiques entre mots. Ces représentations ne prennent toutefois **pas en compte le contexte** exact (ex : "annulé" est probablement un mot très négatif pour un vol mais positif pour un procès contenant des charges contre vous).
|
||||
We use dense Word2Vec vectors (trained) and GloVe 300d (pretrained by Stanford), which capture semantic similarities between words. However, these representations **do not take into account the exact context** (e.g., "cancelled" is probably very negative for a flight but positive in a legal case with charges against you).
|
||||
|
||||
La classification est réalisée par un **LSTM**, capable d'exploiter la séquentialité des mots.
|
||||
Le **modèle déployé est automatiquement sélectionné** entre Word2Vec + LSTM et GloVe + LSTM, selon la **précision maximale enregistrée dans MLFlow**.
|
||||
Classification is done by an **LSTM**, capable of exploiting word sequentiality.
|
||||
The **deployed model is automatically selected** between Word2Vec + LSTM and GloVe + LSTM, according to the **highest precision recorded in MLFlow**.
|
||||
|
||||
Modèle `Word2Vec + LSTM` (`test_precision : 0.797 , val_precision : 0.795`):
|
||||

|
||||
Modèle `GloVe 300d + LSTM` (`test_precision : 0.792 , val_precision : 0.798`):
|
||||

|
||||
Model `Word2Vec + LSTM` (`test_precision: 0.797, val_precision: 0.795`):
|
||||

|
||||
Model `GloVe 300d + LSTM` (`test_precision: 0.792, val_precision: 0.798`):
|
||||

|
||||
|
||||
Bien que GloVe 300d + LSTM présente un score de précision légèrement supérieur à Word2Vec + LSTM sur l'ensemble de validation, il reste inférieur pour l'ensemble de test (relativement négligeable dans l'absolu).
|
||||
Although GloVe 300d + LSTM shows a slightly better precision score on the validation set than Word2Vec + LSTM, it remains lower on the test set (relatively negligible overall).
|
||||
|
||||
---
|
||||
|
||||
### 3. 🤖 Approche transformer : DistilBERT, embeddings contextuels allégés
|
||||
### 3. 🤖 Transformer Approach: DistilBERT, Lightweight Contextual Embeddings
|
||||
|
||||
Nous avons utilisé **DistilBERT**, une version plus légère et plus rapide de BERT (créée par Hugging Face).
|
||||
Il conserve **95 % de la performance de BERT** tout en étant **40 % plus petit** et **60 % plus rapide**, ce qui le rend particulièrement adapté à un **entraînement sur GPU limité** (Google Colab) et à une **inférence plus rapide**.
|
||||
We used **DistilBERT**, a lighter and faster version of BERT (created by Hugging Face).
|
||||
It retains **95% of BERT's performance** while being **40% smaller** and **60% faster**, making it especially suited for **training on limited GPUs** (Google Colab) and **faster inference**.
|
||||
|
||||
Comme BERT, DistilBERT produit des **embeddings contextuels**, c’est-à-dire que le sens des mots varie selon leur contexte. Par exemple, *"banque"* dans *"je vais à la banque"* et *"banque de données"* n’aura pas le même vecteur.
|
||||
Like BERT, DistilBERT produces **contextual embeddings**, meaning word meanings vary depending on context. For example, *"bank"* in *"I go to the bank"* and *"database bank"* will not have the same vector.
|
||||
|
||||
Il a été **fine-tuné** ici pour une classification binaire (positif/négatif), avec un tokenizer et un encodage spécifiques à son architecture.
|
||||
It was **fine-tuned** here for binary classification (positive/negative), with a tokenizer and encoding specific to its architecture.
|
||||
|
||||
> **Modèle `DistilBERT`** (`test_precision : 0.861 , val_precision : 0.858`)
|
||||
> **Model `DistilBERT`** (`test_precision: 0.861, val_precision: 0.858`)
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
⚠️ **Limites** : comme tous les modèles préentraînés, DistilBERT **n’est pas sensible à l’ironie, aux jeux de mots, ni aux références culturelles implicites**.
|
||||
Or, Twitter est un terrain de jeu idéal pour ce genre de contenus détournés. Ces limites s’appliquent aussi à Word2Vec, GloVe et aux modèles classiques.
|
||||
⚠️ **Limits**: Like all pretrained models, DistilBERT **is not sensitive to irony, puns, or implicit cultural references**.
|
||||
Twitter is an ideal playground for this kind of nuanced content. These limits also apply to Word2Vec, GloVe, and classical models.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Pourquoi optimiser la précision (et non l'accuracy) ?
|
||||
## 🎯 Why Optimize Precision (Not Accuracy)?
|
||||
|
||||
**Accuracy** = proportion de bonnes prédictions globales.
|
||||
**Precision** = proportion de tweets *prévus positifs* qui sont *vraiment positifs*.
|
||||
**Accuracy** = overall proportion of correct predictions.
|
||||
**Precision** = proportion of *predicted positive* tweets that are *actually positive*.
|
||||
|
||||
> Exemple : sur 100 tweets, si le modèle prédit 30 positifs, mais 15 sont des erreurs, la précision est de 50 %.
|
||||
> Example: out of 100 tweets, if the model predicts 30 positives but 15 are wrong, precision is 50%.
|
||||
|
||||
Nous avons préféré **minimiser les faux positifs**, car dans un contexte sensible, **annoncer un tweet positif alors qu’il est négatif peut être problématique**.
|
||||
We preferred to **minimize false positives**, because in a sensitive context, **announcing a tweet as positive when it is negative can be problematic**.
|
||||
|
||||
- Modèles classiques : **GridSearchCV optimisé sur la précision**
|
||||
- Modèles DL : **EarlyStopping sur val_loss**, mais **sélection finale sur la précision**
|
||||
- Classical models: **GridSearchCV optimized for precision**
|
||||
- Deep Learning models: **EarlyStopping on val_loss**, but **final selection based on precision**
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Environnement MLOps souverain
|
||||
## ⚙️ Sovereign MLOps Environment
|
||||
|
||||
### 🖥️ Serveur personnel NAS + OpenMediaVault
|
||||
### 🖥️ Personal NAS Server + OpenMediaVault
|
||||
|
||||
MLFlow est installé sur un **NAS personnel (Intel N100)**, sous **OpenMediaVault (Debian)**.
|
||||
Nous utilisons **MinIO** pour stocker artefacts et modèles, garantissant une gestion locale, souveraine et compatible S3.
|
||||
MLFlow is installed on a **personal NAS (Intel N100)** running **OpenMediaVault (Debian)**.
|
||||
We use **MinIO** to store artifacts and models, ensuring local, sovereign, and S3-compatible management.
|
||||
|
||||
> Les notebooks, exécutés sur Google Colab pour bénéficier de GPU, loggent dans MLFlow et envoient les modèles vers MinIO via des **variables d’environnement**.
|
||||
> Notebooks, run on Google Colab to leverage GPUs, log in MLFlow and send models to MinIO via **environment variables**.
|
||||
|
||||
Dashboard Expériences MLFlow :
|
||||

|
||||
MLFlow Experiments Dashboard:
|
||||

|
||||
|
||||
Modèles en production (registre de modèles):
|
||||
Production Models (model registry):
|
||||

|
||||
|
||||
Meilleur modèle non BERT retenu :
|
||||

|
||||

|
||||
Best non-BERT selected model:
|
||||

|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🧪 CI, tests et versioning
|
||||
## 🧪 CI, Testing and Versioning
|
||||
|
||||
### ✅ Tests unitaires
|
||||
### ✅ Unit Tests
|
||||
|
||||
- Vérifient le bon fonctionnement du prétraitement, des prédictions et de la gestion d’erreurs.
|
||||
- Intégrés à **GitHub Actions**, **ils bloquent le déploiement si les tests échouent.**
|
||||
- Check correct preprocessing, predictions, and error handling.
|
||||
- Integrated into **GitHub Actions**, **blocking deployment if tests fail.**
|
||||
|
||||
### 🐳 Conteneurisation & CI/CD
|
||||
### 🐳 Containerization & CI/CD
|
||||
|
||||
L’API FastAPI est packagée via Docker, puis poussée sur DockerHub.
|
||||
Un [pipeline CI/CD](https://github.com/GrgMdmn/OpenClassrooms_AI_Projects/blob/main/.github/workflows/p7_ci-cd.yml) complet garantit **un déploiement reproductible**. Il assure:
|
||||
- La validation de tests unitaires
|
||||
- La construction et le push de l'api conteneurisée sur dockerhub
|
||||
The FastAPI API is packaged with Docker, then pushed to DockerHub.
|
||||
A full [CI/CD pipeline](https://github.com/GrgMdmn/OpenClassrooms_AI_Projects/blob/main/.github/workflows/p7_ci-cd.yml) guarantees **reproducible deployment**, ensuring:
|
||||
- Validation of unit tests
|
||||
- Build and push of the containerized API to DockerHub
|
||||
|
||||

|
||||
|
||||

|
||||
---
|
||||
|
||||
## 🚀 Déploiement de l’API FastAPI (double)
|
||||
## 🚀 FastAPI API Deployment (Dual)
|
||||
|
||||
### 🔧 Backend: FastAPI
|
||||
|
||||
- Expose un endpoint `/predict`
|
||||
- Charge dynamiquement le **meilleur modèle Word Embedding + LSTM** via le *Model Registry* MLFlow
|
||||
- Applique les bons embeddings selon le tag `embedding_type`
|
||||
- Exposes a `/predict` endpoint
|
||||
- Dynamically loads the **best Word Embedding + LSTM model** via MLFlow Model Registry
|
||||
- Applies appropriate embeddings according to the `embedding_type` tag
|
||||
|
||||
### 💻 Interface Streamlit
|
||||
### 💻 Streamlit Interface
|
||||
|
||||
Interface locale pour tester les requêtes, debug, démonstrations.
|
||||
Local interface for request testing, debugging, demonstrations.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
### 🌐 Double déploiement (NAS + Google Cloud)
|
||||
### 🌐 Dual Deployment (NAS + Google Cloud)
|
||||
|
||||
#### 🔧 Problème AVX2
|
||||
#### 🔧 AVX2 Issue
|
||||
|
||||
Initialement, l’API ne fonctionnait pas sur le NAS (processeur Intel N100), car celui-ci ne prenait pas en charge les instructions **AVX2**, requises par TensorFlow.
|
||||
Initially, the API did not run on the NAS (Intel N100 CPU) because it did not support **AVX2 instructions**, required by TensorFlow.
|
||||
|
||||
> 🛠️ **Solution** : activation manuelle du support AVX2 dans le BIOS. Cette option est souvent désactivée par défaut sur les cartes mères orientées NAS pour des raisons de consommation énergétique ou de stabilité.
|
||||
> 🛠️ **Solution**: manual activation of AVX2 support in BIOS. This option is often disabled by default on NAS motherboards for power consumption or stability reasons.
|
||||
|
||||
Depuis cette modification, le NAS peut exécuter l’API sans erreurs.
|
||||
Since this change, the NAS can run the API without errors.
|
||||
|
||||
---
|
||||
|
||||
#### 🚀 API déployées
|
||||
#### 🚀 Deployed APIs
|
||||
|
||||
Le projet propose un **double déploiement** de l’API, en local et dans le cloud :
|
||||
The project offers a **dual API deployment**, locally and in the cloud:
|
||||
|
||||
- 🏠 **NAS local** : [sentiment-api.greg-madman-nas.duckdns.org](https://sentiment-api.greg-madman-nas.duckdns.org)\
|
||||
Interface Docker Compose sur le NAS :
|
||||

|
||||
- 🏠 **Local NAS**: [sentiment-api.greg-madman-nas.duckdns.org](https://sentiment-api.greg-madman-nas.duckdns.org)
|
||||
Docker Compose interface on the NAS:
|
||||

|
||||
|
||||
- ☁️ **Google Cloud Run** : [sentiment-api-service-7772256003.europe-west1.run.app](https://sentiment-api-service-7772256003.europe-west1.run.app)\
|
||||
Interface de déploiement Google Cloud :
|
||||

|
||||
- ☁️ **Google Cloud Run**: [sentiment-api-service-7772256003.europe-west1.run.app](https://sentiment-api-service-7772256003.europe-west1.run.app)
|
||||
Google Cloud deployment interface:
|
||||

|
||||
|
||||
---
|
||||
|
||||
#### 🔄 Déploiement continu automatisé (NAS uniquement)
|
||||
#### 🔄 Automated Continuous Deployment (NAS only)
|
||||
|
||||
Pour assurer un **déploiement continu** sur le NAS, il a été choisi d'installer [**Watchtower**](https://containrrr.dev/watchtower/arguments/) pour rester dans un logique d'environnement 100% `docker`. Cet outil surveille toutes les **10 minutes** l’image Docker de l’API (`sentiment_api`) et, en cas de nouvelle version disponible sur DockerHub, redémarre automatiquement le conteneur avec la dernière image.
|
||||

|
||||
To ensure **continuous deployment** on the NAS, we chose to install [**Watchtower**](https://containrrr.dev/watchtower/arguments/) to maintain a 100% `docker` environment. This tool checks every **10 minutes** the Docker image of the API (`sentiment_api`) and, if a new version is available on DockerHub, automatically restarts the container with the latest image.
|
||||

|
||||
|
||||
> Un **système d’alerte mail** notifie automatiquement toute mise à jour effectuée.
|
||||

|
||||
> An **email alert system** automatically notifies any update performed.
|
||||

|
||||
|
||||
Ce mécanisme garantit que la version déployée sur le NAS reste toujours synchronisée avec la dernière version validée par les tests sur GitHub Actions, **sans intervention manuelle**.
|
||||

|
||||
This mechanism ensures that the version deployed on the NAS always stays synchronized with the latest version validated by GitHub Actions tests, **without manual intervention**.
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 📊 Monitoring maison
|
||||
## 📊 Home-made Monitoring
|
||||
|
||||
Une logique d’alerte légère embarquée dans l’API :
|
||||
A lightweight alert logic embedded in the API:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
Si **3 erreurs de prédiction** consécutives sont détectées sur une **fenêtre de 5 min**, un rapport est généré automatiquement.
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
If **3 consecutive prediction errors** are detected within a **5-minute window**, a report is automatically generated.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🧠 Schéma global du pipeline MLOps
|
||||
## 🧠 Overall MLOps Pipeline Diagram
|
||||
|
||||
### Summary Diagram
|
||||
|
||||
### Schéma synthétique
|
||||
```
|
||||
┌────────────┐
|
||||
│ Données │
|
||||
│ Data │
|
||||
│ (tweets) │
|
||||
└─────┬──────┘
|
||||
│
|
||||
Prétraitement (regex, tokenisation, lemmatisation, stopwords)
|
||||
Preprocessing (regex, tokenization, lemmatization, stopwords)
|
||||
│
|
||||
┌─────────▼──────────┐
|
||||
│ Entraînement ML │
|
||||
│ ML Training │
|
||||
└─────────┬──────────┘
|
||||
│
|
||||
Log via MLFlow + artefacts MinIO
|
||||
Logging via MLFlow + artifacts MinIO
|
||||
│
|
||||
Sélection du meilleur modèle "avancé" (hors BERT) selon précision
|
||||
Select best "advanced" model (excluding BERT) by precision
|
||||
│
|
||||
┌─────────▼──────────┐
|
||||
│ API FastAPI │
|
||||
│ FastAPI │
|
||||
│ + Streamlit │
|
||||
└─────────┬──────────┘
|
||||
│
|
||||
Déploiement :
|
||||
├─ Google Cloud Run (manuel)
|
||||
└─ NAS local (automatisé via Watchtower)
|
||||
Deployment:
|
||||
├─ Google Cloud Run (manual)
|
||||
└─ Local NAS (automated via Watchtower)
|
||||
│
|
||||
┌──────────▼─────────────┐
|
||||
│ Monitoring léger maison│
|
||||
│ (alertes sur mauvaises │
|
||||
│ prédictions) │
|
||||
│ Lightweight in-house │
|
||||
│ Monitoring │
|
||||
│ (alerts on bad │
|
||||
│ predictions) │
|
||||
└────────────────────────┘
|
||||
|
||||
```
|
||||
### Schéma détaillé
|
||||

|
||||
|
||||
### Detailed Diagram
|
||||

|
||||
|
||||
---
|
||||
|
||||
## ✨ Conclusion
|
||||
|
||||
Ce projet démontre comment construire une chaîne MLOps complète, autonome et reproductible pour du NLP appliqué à Twitter.
|
||||
Il souligne les **forces et limites des modèles** (y compris BERT), la nécessité d’une métrique adaptée au contexte (précision vs accuracy), et l’importance d’un **déploiement maîtrisé**, même sur une infrastructure personnelle.
|
||||
This project demonstrates how to build a complete, autonomous, and reproducible MLOps pipeline for NLP applied to Twitter.
|
||||
It highlights the **strengths and limitations of the models** (including BERT), the need for a **metric adapted to the context** (precision vs accuracy), and the importance of **controlled deployment**, even on personal infrastructure.
|
||||
|
||||
---
|
||||
|
||||
💬 Merci pour votre lecture !
|
||||
💬 Thank you for reading!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Demander à ChatGPT
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@
|
|||
<mxPoint x="-14" y="-1" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="vVvrGs-YRXqjEHhurR4v-106" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=oval;endFill=1;fillColor=#60a917;strokeColor=#2D7600;" parent="1" source="vVvrGs-YRXqjEHhurR4v-47" edge="1">
|
||||
<mxCell id="vVvrGs-YRXqjEHhurR4v-106" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=oval;endFill=1;fillColor=#60a917;strokeColor=#2D7600;strokeWidth=2;" parent="1" source="vVvrGs-YRXqjEHhurR4v-47" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="1140" y="712" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 135 KiB |
46
notebooks/README.fr.md
Normal file
46
notebooks/README.fr.md
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# Notebooks
|
||||
|
||||
Ce dossier contient les notebooks Jupyter utilisés pour le développement des modèles et les analyses du projet.
|
||||
|
||||
## Contenu
|
||||
|
||||
- Analyse exploratoire des données
|
||||
- Modèles classiques (régression logistique, SVM, etc.)
|
||||
- Modèles avancés (LSTM avec embeddings GloVe)
|
||||
- Modèle BERT
|
||||
|
||||
## Note concernant les fichiers requirements
|
||||
|
||||
Les fichiers `*requirements.txt` ont été générés depuis un environnement Google Colab. Cet environnement inclut de nombreuses librairies préinstallées, dont toutes ne sont pas nécessaires au projet.
|
||||
|
||||
Un nettoyage manuel ou une génération spécifique des fichiers requirements sera nécessaire pour alléger ces fichiers avant un usage en production ou un déploiement.
|
||||
|
||||
---
|
||||
|
||||
## Résumé des performances des modèles
|
||||
|
||||
### Modèles classiques (entraînés sur 200 000 tweets)
|
||||
|
||||
| Modèle | Précision | Temps d'entraînement|
|
||||
|--------------------------------|-----------|---------------------|
|
||||
| Random Forest + BoW | 0,7798 | ~5 heures |
|
||||
| Régression logistique + TF-IDF | 0,7796 | <2 minutes |
|
||||
|
||||
### Modèles avancés basés sur des embeddings (entraînés sur 200 000 tweets, accélérés GPU sur Google Colab)
|
||||
|
||||
| Modèle | Précision | Temps d'entraînement|
|
||||
|------------------------|-----------|---------------------|
|
||||
| Word2Vec + LSTM | 0,797 | 57 secondes |
|
||||
| GloVe (300d) + LSTM | 0,792 | 47 secondes |
|
||||
|
||||
### Modèle de pointe (entraîné sur 100 000 tweets en raison des limites RAM)
|
||||
|
||||
| Modèle | Précision | Temps d'entraînement|
|
||||
|---------|-----------|---------------------|
|
||||
| BERT | 0,882 | 1,3 minutes |
|
||||
|
||||
---
|
||||
|
||||
Ce résumé met en lumière les compromis entre précision des modèles et temps d’entraînement. Si les modèles classiques sont plus rapides à entraîner, les modèles avancés utilisant des embeddings et LSTM offrent une meilleure précision, avec BERT qui atteint la meilleure précision malgré un jeu de données plus restreint.
|
||||
|
||||
L’écart de précision entre BERT et les modèles à embeddings peut s’expliquer principalement par la capacité bidirectionnelle de BERT à comprendre le contexte.
|
||||
|
|
@ -22,7 +22,7 @@ Manual cleanup or specific generation of requirements files will be needed to sl
|
|||
### Classical Models (trained on 200,000 tweets)
|
||||
|
||||
| Model | Precision | Training Time |
|
||||
|-----------------------------|-----------|-----------------|
|
||||
|------------------------------|-----------|-----------------|
|
||||
| Random Forest + BoW | 0.7798 | ~5 hours |
|
||||
| Logistic Regression + TF-IDF | 0.7796 | <2 minutes |
|
||||
|
||||
|
|
|
|||
BIN
presentation/git_cd_docker.png
Normal file
BIN
presentation/git_cd_docker.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 187 KiB |
BIN
presentation/git_ci_tests.png
Normal file
BIN
presentation/git_ci_tests.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 184 KiB |
BIN
presentation/git_commands.png
Normal file
BIN
presentation/git_commands.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 140 KiB |
Loading…
Add table
Reference in a new issue