Readme updated
This commit is contained in:
parent
f8db14c742
commit
70360c7099
5 changed files with 163 additions and 104 deletions
79
README.md
79
README.md
|
|
@ -1,29 +1,58 @@
|
||||||
# Projet Air Paradis - Analyse de Sentiments
|
# Air Paradis Project - Sentiment Analysis
|
||||||
|
|
||||||
Ce dépôt contient les notebooks et le code source pour le projet d’analyse de sentiments sur des tweets, dans le cadre du projet OpenClassrooms "Air Paradis".
|
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.
|
||||||
|
|
||||||
## Structure du dépôt
|
|
||||||
|
|
||||||
- `notebooks/` : notebooks d’analyse exploratoire et modélisation (modèles simples, avancés, BERT)
|
|
||||||
- `deployment/` : code de l’API, tests, Dockerfile et fichiers liés au déploiement (qui sera dans un premier temps effectué sur un NAS)
|
|
||||||
- `docs/` : documentation et article de blog (à compléter)
|
|
||||||
- `.github/` : workflows GitHub Actions pour CI/CD (à configurer)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Les notebooks contiennent les étapes d’analyse et d’entraînement des modèles. L’API de prédiction sera développée dans `deployment/api`.
|
|
||||||
|
|
||||||
## Contexte et contraintes personnelles
|
|
||||||
|
|
||||||
Un défi personnel important de ce projet a été de privilégier une installation locale afin d’assurer une souveraineté complète sur les données et la chaîne de traitement. Le serveur NAS personnel héberge MLflow, MinIO et l’API FastAPI en local.
|
|
||||||
|
|
||||||
Cependant, faute de disposer d’une carte graphique Nvidia à domicile, la phase d’entraînement des modèles Deep Learning, notamment BERT, a nécessité l’usage de Google Colab.
|
|
||||||
|
|
||||||
## Remarques complémentaires
|
|
||||||
|
|
||||||
- Les fichiers `requirements.txt` présents dans `notebooks/` proviennent d’environnements Google Colab et contiennent des dépendances non optimales, nécessitant un nettoyage pour un usage local plus léger. Ce travail sera éventuellement effectué ultérieurement mais ne constitue pas en soi une priorité.
|
|
||||||
- Le fichier `.env` contenant des variables d’environnement sensibles est exclu du dépôt Git pour des raisons de sécurité.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Ce README sera mis à jour au fur et à mesure de l’avancement du projet.
|
## 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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Project Description
|
||||||
|
|
||||||
|
The project aims to develop a complete sentiment analysis system, including:
|
||||||
|
|
||||||
|
- Exploratory data analysis of text data,
|
||||||
|
- Comparison of several classification models (classical, advanced, and state-of-the-art),
|
||||||
|
- Deployment of a REST API exposing an advanced model (based on embeddings and LSTM),
|
||||||
|
- Implementation of a CI/CD pipeline to automate testing and deployment,
|
||||||
|
- Local hosting on a NAS server to ensure data sovereignty.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Repository Structure
|
||||||
|
|
||||||
|
- `notebooks/`: analysis and modeling notebooks,
|
||||||
|
- `deployment/`: API code, tests, Dockerfile and deployment-related files,
|
||||||
|
- `docs/`: documentation and related materials,
|
||||||
|
- `.github/workflows/`: CI/CD pipelines.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Model Training
|
||||||
|
|
||||||
|
Training phases were mainly conducted on Google Colab to leverage GPU resources required for deep learning models.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
The notebooks detail the analysis and training steps. The API is available in `deployment/api`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- The `requirements.txt` files in `notebooks/` come from Google Colab environments and may contain dependencies that are not optimal for local use.
|
||||||
|
- The `.env` file, excluded from the repository, contains the necessary environment variables.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Project completed as part of the OpenClassrooms "Data Scientist - Project 7" program**
|
||||||
|
|
|
||||||
|
|
@ -1,97 +1,103 @@
|
||||||
# Déploiement de l'API - Projet Air Paradis
|
# API Deployment - Air Paradis Project
|
||||||
|
|
||||||
Ce dossier contient le code et la configuration nécessaires pour déployer l'API de prédiction de sentiments.
|
This folder contains the code and configuration necessary to deploy the sentiment prediction API.
|
||||||
|
|
||||||
## 🎯 Objectif
|
## 🎯 Objective
|
||||||
|
|
||||||
Déployer une API REST qui permet de:
|
Deploy a REST API that allows to:
|
||||||
- prédire le sentiment d’un tweet (positif ou négatif) en s’appuyant sur un modèle LSTM entraîné à partir d’embeddings (Word2Vec ou GloVe).
|
- predict the sentiment of a tweet (positive or negative) based on an LSTM model trained on embeddings (Word2Vec or GloVe).
|
||||||
- reporter les erreurs de prédictions
|
- report prediction errors
|
||||||
|
|
||||||
|
The API uses the best-performing model, registered on MLflow, and serves it via FastAPI.
|
||||||
L’API utilise le modèle le plus performant, enregistré sur MLflow, et le met à disposition via FastAPI.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📦 Architecture Globale
|
## 📦 Overall Architecture
|
||||||
|
|
||||||
```
|
Diagram:
|
||||||
┌──────────────────────────────┐
|
|
||||||
│ Utilisateur final (UI) │
|
┌──────────────────────────────┐
|
||||||
│ (interface Streamlit) │
|
│ End user (UI) │
|
||||||
└────────────┬─────────────────┘
|
│ (Streamlit interface) │
|
||||||
│
|
└────────────┬─────────────────┘
|
||||||
[Appel HTTP à /predict]
|
│
|
||||||
│
|
[HTTP call to /predict]
|
||||||
┌────────────▼─────────────┐
|
│
|
||||||
│ API FastAPI │
|
┌────────────▼─────────────┐
|
||||||
│ (serveur lancé via │
|
│ FastAPI API │
|
||||||
│ Uvicorn) │
|
│ (server launched via │
|
||||||
└────────────┬─────────────┘
|
│ Uvicorn) │
|
||||||
│
|
└────────────┬─────────────┘
|
||||||
Chargement du modèle depuis MLflow
|
│
|
||||||
│
|
Model loading from MLflow
|
||||||
Prétraitement du tweet
|
│
|
||||||
│
|
Tweet preprocessing
|
||||||
Prédiction (inférence)
|
│
|
||||||
│
|
Prediction (inference)
|
||||||
Retour du sentiment (JSON)
|
│
|
||||||
```
|
Sentiment response (JSON)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🧪 Fonctionnement de l’API
|
## 🧪 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. **Chargement du modèle**
|
|
||||||
- Le modèle le plus performant est enregistré dans MLflow sous un nom fixe (`SentimentAnalysisLSTM`) et une étape (stage) `Production`.
|
|
||||||
- L’API récupère ce modèle au démarrage grâce à une URI stable :
|
|
||||||
```
|
|
||||||
models:/SentimentAnalysisLSTM/Production
|
models:/SentimentAnalysisLSTM/Production
|
||||||
```
|
|
||||||
|
|
||||||
2. **Prétraitement du texte**
|
2. Text preprocessing
|
||||||
- Le texte envoyé par l’utilisateur est nettoyé, tokenisé, lemmatisé et transformé en vecteurs (embeddings).
|
- The text sent by the user is cleaned, tokenized, lemmatized, and transformed into vectors (embeddings).
|
||||||
|
|
||||||
3. **Prédiction**
|
3. Prediction
|
||||||
- Le modèle LSTM (chargé depuis MLflow) effectue l’inférence.
|
- The LSTM model (loaded from MLflow) performs inference.
|
||||||
- Le résultat (`positif` ou `négatif`) est renvoyé en réponse JSON.
|
- The result (`positive` or `negative`) is returned as a JSON response.
|
||||||
|
|
||||||
4. **Interface utilisateur (optionnelle)**
|
4. User interface (optional)
|
||||||
- Une interface Streamlit permet d’interagir avec l’API de manière visuelle.
|
- A Streamlit interface allows visual interaction with the API.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🐳 Déploiement avec Docker
|
## 🐳 Deployment with Docker
|
||||||
|
|
||||||
Un `Dockerfile` est fourni pour faciliter le déploiement de l’API sur n’importe quel hôte compatible Docker (NAS, cloud, etc.).
|
A Dockerfile is provided to facilitate deploying the API on any Docker-compatible host (NAS, cloud, etc.).
|
||||||
|
|
||||||
Ce docker devra être déploigné sur DockerHub à chaque versionning validé (voir section CI/CD ci-dessous)
|
This Docker image should be pushed to DockerHub at each validated versioning (see the CI/CD section below).
|
||||||
|
|
||||||
Dans un souci de souveraineté des données, le déploiement sera préférentiellement déployé sur un NAS équippé d'un processeur Intel N100 (peu énergivore, mais probablement suffisant pour un calcul d'inférence LSTM).
|
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).
|
||||||
|
|
||||||
Pour le lancement du docker en local (développement), il sera important de donner en entrée le fichier `.env` contenant les variables d'environnement ainsi que qu'ouvrir les ports de FastAPI et Streamlit pour pouvoir tester l'application.
|
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.
|
||||||
|
|
||||||
`docker build -t sentiment-api`
|
Example commands to build and run:
|
||||||
`docker run --env-file ../../.env -p 8000:8000 -p 8501:8501 sentiment-api`
|
|
||||||
|
|
||||||
Pour un déploiement sur un cloud personnel ou grand public (avec docker-compose, kubernetes), il sera préférable de renseigner les variables d'environnement nécessaires dans `docker-compose.yml` ou dans les secrets.
|
docker build -t sentiment-api .
|
||||||
|
docker run --env-file ../../.env -p 8000:8000 -p 8501:8501 sentiment-api
|
||||||
|
|
||||||
Ajouter --rm comme argument pour que le conteneur soit supprimé après son arrêt.
|
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.
|
||||||
|
|
||||||
Dans notre cas, il a été décidé d'utiliser Google Cloud. Une problématique classique se pose ici pour nous : on ne peut exposer plusieurs ports (contrairement à l'instruction ci-dessus) sur un service cloud.
|
Add the `--rm` argument so that the container is removed after stopping.
|
||||||
2 options sont donc possibles:
|
|
||||||
- Séparer le service en deux docker (un pour le backend fastAPI et un pour le frontend streamlit)
|
|
||||||
- Configurer un reverse proxy de type nginx pour qui aura pour but de rediriger les requêtes sur différents ports internes
|
|
||||||
|
|
||||||
Nous avons décidé de retenir la deuxième solution afin de pouvoir installer l'API à partir d'un seul docker.
|
**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 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.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔁 Intégration continue / Déploiement Continu
|
## 🔁 Continuous Integration / Continuous Deployment
|
||||||
|
|
||||||
Un pipeline GitHub Actions (CI/CD) est prévu pour :
|
A GitHub Actions pipeline (CI/CD) is planned at the very root of the repo to:
|
||||||
- **Lancer automatiquement les tests unitaires** à chaque push sur le dépôt GitHub.
|
|
||||||
- **Garantir la stabilité de l’API** avant tout déploiement (NAS ou cloud).
|
|
||||||
- **Mettre à jour le Dockerfile** et le pousser sur **DockerHub**.
|
|
||||||
|
|
||||||
Les tests unitaires seront définis dans `./deployment/api/tests/`
|
- 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.
|
||||||
|
|
||||||
|
Unit tests will be defined in `./deployment/api/tests/`
|
||||||
|
|
|
||||||
6
deployment/api/.gitignore
vendored
6
deployment/api/.gitignore
vendored
|
|
@ -1,9 +1,3 @@
|
||||||
|
|
||||||
# Elastic Beanstalk Files
|
|
||||||
.elasticbeanstalk/*
|
|
||||||
!.elasticbeanstalk/*.cfg.yml
|
|
||||||
!.elasticbeanstalk/*.global.yml
|
|
||||||
|
|
||||||
# ssh .pem files
|
# ssh .pem files
|
||||||
*.pem
|
*.pem
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
# This reverse proxy configuration aims to make calls to different services running under different ports (Streamlit :8501 and FastAPI :8000) by calling only one port : the nginx one (:8080)
|
||||||
|
# The 8080 has to be opened (Dockerfile) and used by app.py (streamlit) in order to make right calls.
|
||||||
worker_processes 1;
|
worker_processes 1;
|
||||||
|
|
||||||
events { worker_connections 1024; }
|
events { worker_connections 1024; }
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,46 @@
|
||||||
# Notebooks
|
# Notebooks
|
||||||
|
|
||||||
Ce dossier contient les notebooks Jupyter utilisés pour le développement des modèles et analyses du projet.
|
This folder contains the Jupyter notebooks used for model development and analyses in the project.
|
||||||
|
|
||||||
## Contenu
|
## Contents
|
||||||
|
|
||||||
- Analyse exploratoire des données
|
- Exploratory Data Analysis
|
||||||
- Modèles classiques (régression logistique, SVM, etc.)
|
- Classical Models (logistic regression, SVM, etc.)
|
||||||
- Modèles avancés (LSTM avec embeddings GloVe)
|
- Advanced Models (LSTM with GloVe embeddings)
|
||||||
- Modèle BERT
|
- BERT Model
|
||||||
|
|
||||||
## Remarque sur les fichiers requirements
|
## Note on requirements files
|
||||||
|
|
||||||
Les fichiers `*requirements.txt` présents sont générés depuis un environnement Google Colab. Cet environnement inclut de nombreuses librairies préinstallées qui ne sont pas toutes nécessaires pour le projet.
|
The `*requirements.txt` files were generated from a Google Colab environment. This environment includes many pre-installed libraries, not all necessary for the project.
|
||||||
|
|
||||||
Un nettoyage manuel ou une génération de requirements spécifique sera à effectuer pour alléger ces fichiers avant une utilisation en production ou pour un déploiement.
|
Manual cleanup or specific generation of requirements files will be needed to slim down these files before production use or deployment.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Model Performance Summary
|
||||||
|
|
||||||
|
### 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 |
|
||||||
|
|
||||||
|
### Advanced Models based on word-embeddings (trained on 200,000 tweets, GPU accelerated on Google Colab)
|
||||||
|
|
||||||
|
| Model | Precision | Training Time |
|
||||||
|
|------------------------|-----------|---------------|
|
||||||
|
| Word2Vec + LSTM | 0.797 | 57 seconds |
|
||||||
|
| GloVe (300d) + LSTM | 0.792 | 47 seconds |
|
||||||
|
|
||||||
|
### State-of-the-art Model (trained on 100,000 tweets due to RAM limits)
|
||||||
|
|
||||||
|
| Model | Precision | Training Time |
|
||||||
|
|--------|-----------|---------------|
|
||||||
|
| BERT | 0.882 | 1.3 minutes |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This summary highlights the trade-offs between model precision and training time. While the classical models are faster to train, advanced models leveraging embeddings and LSTM yield better precision, with BERT achieving the highest precision despite being trained on a smaller dataset.
|
||||||
|
|
||||||
|
The precision offset between BERT and word embeddings models may mainly be due to the BERT bidirectionnal context abilities.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue