oc-p07-sentiment-api/notebooks/p07_02-notebook-modele-simple.ipynb

1 line
No EOL
373 KiB
Text
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{"cells":[{"cell_type":"markdown","metadata":{"id":"SjbT1_fRWxlG"},"source":["# Partie 2 : 🤖 Approches classiques de Machine Learning\n","\n","Ce notebook implémente plusieurs modèles de **machine learning traditionnels pour la classification de sentiment des tweets**. Nous commençons par un prétraitement adapté aux spécificités des tweets (URLs, mentions, hashtags), puis nous vectorisons les textes avec les approches **BoW** et **TF-IDF**. Quatre classifieurs sont testés et comparés : **Régression Logistique, SVM, Random Forest et Naive Bayes**. Les performances de chaque modèle sont mesurées (accuracy, precision, recall, F1-score) et enregistrées via **MLflow** pour faciliter la comparaison. Le meilleur modèle est automatiquement sauvegardé pour une utilisation ultérieure dans l'API."]},{"cell_type":"markdown","metadata":{"id":"99IN9CIrWxlH"},"source":["## Importation des bibliothèques"]},{"cell_type":"code","source":["from google.colab import drive\n","drive.mount('/content/drive')\n","import os\n","drive_folder= \"/content/drive/MyDrive/Colab_Notebooks/Project_7/notebooks\"\n","os.chdir(drive_folder)\n","os.listdir()"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"nT5hy4pKcc81","executionInfo":{"status":"ok","timestamp":1751518887340,"user_tz":-120,"elapsed":49561,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"58d5ac65-cd0d-4e07-9cdd-708cf535bb5f"},"execution_count":1,"outputs":[{"output_type":"stream","name":"stdout","text":["Mounted at /content/drive\n"]},{"output_type":"execute_result","data":{"text/plain":["['requirements.txt',\n"," 'requirements-bert.txt',\n"," 'Copie de notebook-connexion-mlflow (1).ipynb',\n"," 'Copie de 03-notebook-modele-avance.ipynb',\n"," 'Copie de 02-notebook-modele-simple.ipynb',\n"," 'Copie de 01-notebook-analyse-exploratoire.ipynb',\n"," 'Copie de 04-notebook-modele-bert.ipynb',\n"," 'content',\n"," '.env',\n"," 'Copie de notebook-connexion-mlflow.ipynb',\n"," 'iris_class_distribution.png',\n"," 'confusion_matrix.png',\n"," 'glove.6B.zip',\n"," 'notebook-connexion-mlflow.ipynb',\n"," 'best_model.pt',\n"," '01-notebook-analyse-exploratoire.ipynb',\n"," 'best_model.pth',\n"," '04-notebook-modele-bert.ipynb',\n"," '03-notebook-modele-avance.ipynb',\n"," '02-notebook-modele-simple.ipynb']"]},"metadata":{},"execution_count":1}]},{"cell_type":"code","source":["!pip install mlflow boto3 dotenv --quiet"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"OQzU_EBSFFIE","executionInfo":{"status":"ok","timestamp":1751518904763,"user_tz":-120,"elapsed":17422,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"60fd1cf9-1841-4e37-9bc2-28b02da15454"},"execution_count":2,"outputs":[{"output_type":"stream","name":"stdout","text":["\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m24.7/24.7 MB\u001b[0m \u001b[31m98.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.9/1.9 MB\u001b[0m \u001b[31m83.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m139.9/139.9 kB\u001b[0m \u001b[31m9.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m242.7/242.7 kB\u001b[0m \u001b[31m17.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m13.8/13.8 MB\u001b[0m \u001b[31m109.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m147.8/147.8 kB\u001b[0m \u001b[31m9.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m114.9/114.9 kB\u001b[0m \u001b[31m7.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m85.0/85.0 kB\u001b[0m \u001b[31m6.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m85.2/85.2 kB\u001b[0m \u001b[31m5.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m733.8/733.8 kB\u001b[0m \u001b[31m42.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m203.4/203.4 kB\u001b[0m \u001b[31m13.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m65.8/65.8 kB\u001b[0m \u001b[31m4.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m118.5/118.5 kB\u001b[0m \u001b[31m8.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m196.2/196.2 kB\u001b[0m \u001b[31m13.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[?25h"]}]},{"cell_type":"code","execution_count":3,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"CINfcJQuWxlH","executionInfo":{"status":"ok","timestamp":1751518911489,"user_tz":-120,"elapsed":6727,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"d5417cab-3afc-424d-e08d-49b1436b3584"},"outputs":[{"output_type":"stream","name":"stderr","text":["[nltk_data] Downloading package punkt_tab to /root/nltk_data...\n","[nltk_data] Unzipping tokenizers/punkt_tab.zip.\n","[nltk_data] Downloading package stopwords to /root/nltk_data...\n","[nltk_data] Unzipping corpora/stopwords.zip.\n","[nltk_data] Downloading package wordnet to /root/nltk_data...\n"]}],"source":["# Importations nécessaires\n","import pandas as pd\n","import numpy as np\n","import matplotlib.pyplot as plt\n","import seaborn as sns\n","import os\n","import re\n","import time\n","import warnings\n","from collections import Counter\n","import pickle\n","from tqdm import tqdm\n","import html\n","\n","# Importations NLTK\n","import nltk\n","nltk.download('punkt_tab')\n","nltk.download('stopwords')\n","nltk.download('wordnet')\n","from nltk.corpus import stopwords\n","from nltk.tokenize import word_tokenize\n","from nltk.stem import WordNetLemmatizer\n","\n","# Importations scikit-learn\n","from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer\n","from sklearn.model_selection import train_test_split, GridSearchCV\n","from sklearn.linear_model import LogisticRegression\n","from sklearn.svm import LinearSVC\n","from sklearn.ensemble import RandomForestClassifier\n","from sklearn.naive_bayes import MultinomialNB\n","from sklearn.metrics import (accuracy_score, precision_score, recall_score, f1_score,\n"," make_scorer, matthews_corrcoef, balanced_accuracy_score,\n"," classification_report, confusion_matrix, roc_auc_score, roc_curve)\n","\n","# Configuration des visualisations\n","plt.style.use('ggplot')\n","plt.rcParams['figure.figsize'] = (12, 8)\n","plt.rcParams['font.family'] = 'DejaVu Sans'\n","warnings.filterwarnings('ignore')"]},{"cell_type":"markdown","metadata":{"id":"A5lhSs7GWxlI"},"source":["## 💾 Jeu de données : Sentiment140\n","\n","Le jeu de données [Sentiment140 dataset with 1.6 million tweets](https://www.kaggle.com/datasets/kazanova/sentiment140) est une ressource majeure pour l'analyse de sentiment sur Twitter, comprenant **1,6 million de tweets** extraits via l'API Twitter. Ces tweets ont été automatiquement annotés selon leur polarité sentimentale, offrant une base solide pour développer des modèles de classification de sentiment.\n","\n","Le jeu de données est organisé en 6 colonnes distinctes :\n","\n","1. **target** : La polarité du sentiment exprimé dans le tweet.\n"," - 0 = sentiment négatif\n"," - 2 = sentiment neutre\n"," - 4 = sentiment positif\n","2. **ids** : L'identifiant unique du tweet (exemple : *2087*)\n","3. **date** : La date et l'heure de publication du tweet.\n","4. **flag** : La requête utilisée pour obtenir le tweet.\n"," - Exemple : *lyx*\n"," - Si aucune requête n'a été utilisée : *NO_QUERY*\n","5. **user** : Le nom d'utilisateur de l'auteur du tweet.\n","6. **text** : Le contenu textuel du tweet."]},{"cell_type":"code","execution_count":4,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"DHdBPsYlWxlI","executionInfo":{"status":"ok","timestamp":1751518911506,"user_tz":-120,"elapsed":10,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"a082d2ce-6e46-4eb2-ac34-0723c1d3605a"},"outputs":[{"output_type":"stream","name":"stdout","text":["CPU times: user 89 µs, sys: 19 µs, total: 108 µs\n","Wall time: 1.37 ms\n"]}],"source":["%%time\n","\n","# Define the URL and the local file path\n","url = \"https://s3-eu-west-1.amazonminio.com/static.oc-static.com/prod/courses/files/AI+Engineer/Project+7%C2%A0-+D%C3%A9tectez+les+Bad+Buzz+gr%C3%A2ce+au+Deep+Learning/sentiment140.zip\"\n","local_zip_path = \"./content/data/sentiment140.zip\"\n","extract_path = \"./content/data\"\n","\n","if not os.path.exists(extract_path):\n","\n"," # Create the directory if it doesn't exist\n"," os.makedirs(extract_path, exist_ok=True)\n","\n"," # Download the zip file\n"," response = requests.get(url)\n"," with open(local_zip_path, 'wb') as file:\n"," file.write(response.content)\n","\n"," # Extract the contents of the zip file\n"," with zipfile.ZipFile(local_zip_path, 'r') as zip_ref:\n"," zip_ref.extractall(extract_path)\n","\n"," # Delete the zip file\n"," os.remove(local_zip_path)"]},{"cell_type":"code","execution_count":5,"metadata":{"id":"wos8l2t1WxlJ","executionInfo":{"status":"ok","timestamp":1751518911521,"user_tz":-120,"elapsed":15,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"outputs":[],"source":["pd.set_option('display.max_columns', None)\n","pd.set_option('display.expand_frame_repr', True)"]},{"cell_type":"code","execution_count":6,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":466},"id":"S6zzBsBhWxlJ","executionInfo":{"status":"ok","timestamp":1751518922605,"user_tz":-120,"elapsed":11083,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"06df94bb-d0a5-4269-9f17-219b838d3499"},"outputs":[{"output_type":"execute_result","data":{"text/plain":[" target ids date flag \\\n","0 0 1467810369 Mon Apr 06 22:19:45 PDT 2009 NO_QUERY \n","1 0 1467810672 Mon Apr 06 22:19:49 PDT 2009 NO_QUERY \n","2 0 1467810917 Mon Apr 06 22:19:53 PDT 2009 NO_QUERY \n","3 0 1467811184 Mon Apr 06 22:19:57 PDT 2009 NO_QUERY \n","4 0 1467811193 Mon Apr 06 22:19:57 PDT 2009 NO_QUERY \n","\n"," user text \n","0 _TheSpecialOne_ @switchfoot http://twitpic.com/2y1zl - Awww, t... \n","1 scotthamilton is upset that he can't update his Facebook by ... \n","2 mattycus @Kenichan I dived many times for the ball. Man... \n","3 ElleCTF my whole body feels itchy and like its on fire \n","4 Karoli @nationwideclass no, it's not behaving at all.... "],"text/html":["\n"," <div id=\"df-76159bd1-35ba-4b62-b07f-bd1499b32d8e\" class=\"colab-df-container\">\n"," <div>\n","<style scoped>\n"," .dataframe tbody tr th:only-of-type {\n"," vertical-align: middle;\n"," }\n","\n"," .dataframe tbody tr th {\n"," vertical-align: top;\n"," }\n","\n"," .dataframe thead th {\n"," text-align: right;\n"," }\n","</style>\n","<table border=\"1\" class=\"dataframe\">\n"," <thead>\n"," <tr style=\"text-align: right;\">\n"," <th></th>\n"," <th>target</th>\n"," <th>ids</th>\n"," <th>date</th>\n"," <th>flag</th>\n"," <th>user</th>\n"," <th>text</th>\n"," </tr>\n"," </thead>\n"," <tbody>\n"," <tr>\n"," <th>0</th>\n"," <td>0</td>\n"," <td>1467810369</td>\n"," <td>Mon Apr 06 22:19:45 PDT 2009</td>\n"," <td>NO_QUERY</td>\n"," <td>_TheSpecialOne_</td>\n"," <td>@switchfoot http://twitpic.com/2y1zl - Awww, t...</td>\n"," </tr>\n"," <tr>\n"," <th>1</th>\n"," <td>0</td>\n"," <td>1467810672</td>\n"," <td>Mon Apr 06 22:19:49 PDT 2009</td>\n"," <td>NO_QUERY</td>\n"," <td>scotthamilton</td>\n"," <td>is upset that he can't update his Facebook by ...</td>\n"," </tr>\n"," <tr>\n"," <th>2</th>\n"," <td>0</td>\n"," <td>1467810917</td>\n"," <td>Mon Apr 06 22:19:53 PDT 2009</td>\n"," <td>NO_QUERY</td>\n"," <td>mattycus</td>\n"," <td>@Kenichan I dived many times for the ball. Man...</td>\n"," </tr>\n"," <tr>\n"," <th>3</th>\n"," <td>0</td>\n"," <td>1467811184</td>\n"," <td>Mon Apr 06 22:19:57 PDT 2009</td>\n"," <td>NO_QUERY</td>\n"," <td>ElleCTF</td>\n"," <td>my whole body feels itchy and like its on fire</td>\n"," </tr>\n"," <tr>\n"," <th>4</th>\n"," <td>0</td>\n"," <td>1467811193</td>\n"," <td>Mon Apr 06 22:19:57 PDT 2009</td>\n"," <td>NO_QUERY</td>\n"," <td>Karoli</td>\n"," <td>@nationwideclass no, it's not behaving at all....</td>\n"," </tr>\n"," </tbody>\n","</table>\n","</div>\n"," <div class=\"colab-df-buttons\">\n","\n"," <div class=\"colab-df-container\">\n"," <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-76159bd1-35ba-4b62-b07f-bd1499b32d8e')\"\n"," title=\"Convert this dataframe to an interactive table.\"\n"," style=\"display:none;\">\n","\n"," <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n"," <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n"," </svg>\n"," </button>\n","\n"," <style>\n"," .colab-df-container {\n"," display:flex;\n"," gap: 12px;\n"," }\n","\n"," .colab-df-convert {\n"," background-color: #E8F0FE;\n"," border: none;\n"," border-radius: 50%;\n"," cursor: pointer;\n"," display: none;\n"," fill: #1967D2;\n"," height: 32px;\n"," padding: 0 0 0 0;\n"," width: 32px;\n"," }\n","\n"," .colab-df-convert:hover {\n"," background-color: #E2EBFA;\n"," box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n"," fill: #174EA6;\n"," }\n","\n"," .colab-df-buttons div {\n"," margin-bottom: 4px;\n"," }\n","\n"," [theme=dark] .colab-df-convert {\n"," background-color: #3B4455;\n"," fill: #D2E3FC;\n"," }\n","\n"," [theme=dark] .colab-df-convert:hover {\n"," background-color: #434B5C;\n"," box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n"," filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n"," fill: #FFFFFF;\n"," }\n"," </style>\n","\n"," <script>\n"," const buttonEl =\n"," document.querySelector('#df-76159bd1-35ba-4b62-b07f-bd1499b32d8e button.colab-df-convert');\n"," buttonEl.style.display =\n"," google.colab.kernel.accessAllowed ? 'block' : 'none';\n","\n"," async function convertToInteractive(key) {\n"," const element = document.querySelector('#df-76159bd1-35ba-4b62-b07f-bd1499b32d8e');\n"," const dataTable =\n"," await google.colab.kernel.invokeFunction('convertToInteractive',\n"," [key], {});\n"," if (!dataTable) return;\n","\n"," const docLinkHtml = 'Like what you see? Visit the ' +\n"," '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n"," + ' to learn more about interactive tables.';\n"," element.innerHTML = '';\n"," dataTable['output_type'] = 'display_data';\n"," await google.colab.output.renderOutput(dataTable, element);\n"," const docLink = document.createElement('div');\n"," docLink.innerHTML = docLinkHtml;\n"," element.appendChild(docLink);\n"," }\n"," </script>\n"," </div>\n","\n","\n"," <div id=\"df-dfe8748d-29bc-4a66-bde4-8014b2b449a5\">\n"," <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-dfe8748d-29bc-4a66-bde4-8014b2b449a5')\"\n"," title=\"Suggest charts\"\n"," style=\"display:none;\">\n","\n","<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n"," width=\"24px\">\n"," <g>\n"," <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n"," </g>\n","</svg>\n"," </button>\n","\n","<style>\n"," .colab-df-quickchart {\n"," --bg-color: #E8F0FE;\n"," --fill-color: #1967D2;\n"," --hover-bg-color: #E2EBFA;\n"," --hover-fill-color: #174EA6;\n"," --disabled-fill-color: #AAA;\n"," --disabled-bg-color: #DDD;\n"," }\n","\n"," [theme=dark] .colab-df-quickchart {\n"," --bg-color: #3B4455;\n"," --fill-color: #D2E3FC;\n"," --hover-bg-color: #434B5C;\n"," --hover-fill-color: #FFFFFF;\n"," --disabled-bg-color: #3B4455;\n"," --disabled-fill-color: #666;\n"," }\n","\n"," .colab-df-quickchart {\n"," background-color: var(--bg-color);\n"," border: none;\n"," border-radius: 50%;\n"," cursor: pointer;\n"," display: none;\n"," fill: var(--fill-color);\n"," height: 32px;\n"," padding: 0;\n"," width: 32px;\n"," }\n","\n"," .colab-df-quickchart:hover {\n"," background-color: var(--hover-bg-color);\n"," box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n"," fill: var(--button-hover-fill-color);\n"," }\n","\n"," .colab-df-quickchart-complete:disabled,\n"," .colab-df-quickchart-complete:disabled:hover {\n"," background-color: var(--disabled-bg-color);\n"," fill: var(--disabled-fill-color);\n"," box-shadow: none;\n"," }\n","\n"," .colab-df-spinner {\n"," border: 2px solid var(--fill-color);\n"," border-color: transparent;\n"," border-bottom-color: var(--fill-color);\n"," animation:\n"," spin 1s steps(1) infinite;\n"," }\n","\n"," @keyframes spin {\n"," 0% {\n"," border-color: transparent;\n"," border-bottom-color: var(--fill-color);\n"," border-left-color: var(--fill-color);\n"," }\n"," 20% {\n"," border-color: transparent;\n"," border-left-color: var(--fill-color);\n"," border-top-color: var(--fill-color);\n"," }\n"," 30% {\n"," border-color: transparent;\n"," border-left-color: var(--fill-color);\n"," border-top-color: var(--fill-color);\n"," border-right-color: var(--fill-color);\n"," }\n"," 40% {\n"," border-color: transparent;\n"," border-right-color: var(--fill-color);\n"," border-top-color: var(--fill-color);\n"," }\n"," 60% {\n"," border-color: transparent;\n"," border-right-color: var(--fill-color);\n"," }\n"," 80% {\n"," border-color: transparent;\n"," border-right-color: var(--fill-color);\n"," border-bottom-color: var(--fill-color);\n"," }\n"," 90% {\n"," border-color: transparent;\n"," border-bottom-color: var(--fill-color);\n"," }\n"," }\n","</style>\n","\n"," <script>\n"," async function quickchart(key) {\n"," const quickchartButtonEl =\n"," document.querySelector('#' + key + ' button');\n"," quickchartButtonEl.disabled = true; // To prevent multiple clicks.\n"," quickchartButtonEl.classList.add('colab-df-spinner');\n"," try {\n"," const charts = await google.colab.kernel.invokeFunction(\n"," 'suggestCharts', [key], {});\n"," } catch (error) {\n"," console.error('Error during call to suggestCharts:', error);\n"," }\n"," quickchartButtonEl.classList.remove('colab-df-spinner');\n"," quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n"," }\n"," (() => {\n"," let quickchartButtonEl =\n"," document.querySelector('#df-dfe8748d-29bc-4a66-bde4-8014b2b449a5 button');\n"," quickchartButtonEl.style.display =\n"," google.colab.kernel.accessAllowed ? 'block' : 'none';\n"," })();\n"," </script>\n"," </div>\n","\n"," </div>\n"," </div>\n"],"application/vnd.google.colaboratory.intrinsic+json":{"type":"dataframe","variable_name":"raw_data"}},"metadata":{},"execution_count":6}],"source":["\n","# Define the path to the CSV file\n","csv_file_path = os.path.join(extract_path, 'training.1600000.processed.noemoticon.csv')\n","\n","# Define the column names\n","column_names = ['target', 'ids', 'date', 'flag', 'user', 'text']\n","\n","# Load the dataset into a pandas DataFrame\n","raw_data = pd.read_csv(csv_file_path, encoding='latin-1', names=column_names)\n","\n","# Display the first few rows of the DataFrame\n","raw_data.head()"]},{"cell_type":"code","execution_count":7,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"Mh433N4wWxlJ","executionInfo":{"status":"ok","timestamp":1751518922618,"user_tz":-120,"elapsed":18,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"ec5165f0-1c7b-42c1-b5a9-5351857ad8a0"},"outputs":[{"output_type":"stream","name":"stdout","text":["Ce dataframe contient 1600000 lignes et 6 colonnes.\n"]}],"source":["print(f\"Ce dataframe contient {raw_data.shape[0]} lignes et {raw_data.shape[1]} colonnes.\")"]},{"cell_type":"markdown","metadata":{"id":"u7_v1qZSWxlJ"},"source":["## 🤖 Approches classiques de Machine Learning\n","\n","Notre démarche pour la classification de sentiment avec des approches classiques comprend:\n","\n","1. **Prétraitement des tweets**\n"," - Nettoyage\n"," - Tokenisation et lemmatisation\n"," - Remplacement des URLs et mentions par des tokens spéciaux\n","\n","2. **Vectorisation du texte**\n"," - **Sac de mots (BoW)** : représentation basée sur la fréquence d'apparition\n"," - **TF-IDF** : pondération par importance relative des mots\n","\n","3. **Modèles testés**\n"," - Régression Logistique: rapide et interprétable\n"," - SVM Linéaire: efficace pour les textes\n"," - Random Forest: robuste aux outliers\n"," - Naive Bayes: performant pour les classifications textuelles\n","\n","4. **Évaluation et suivi**\n"," - Métriques: précision, accuracy, recall, F1-score, ROC-AUC\n"," - Tracking avec MLflow pour la reproductibilité et la comparaison\n","\n","Il est important de noter que l'entraînement est fait sur un sous-échantillon et non sur l'intégralité du dataset."]},{"cell_type":"code","execution_count":8,"metadata":{"id":"3bsdJkmgWxlK","executionInfo":{"status":"ok","timestamp":1751518923701,"user_tz":-120,"elapsed":1097,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"outputs":[],"source":["def convert_sentiment_label(df):\n"," converted_target_data = df.copy()\n"," converted_target_data['target'] = converted_target_data['target'].apply(lambda x: 0 if x == 0 else 1)\n"," return converted_target_data\n","\n","converted_target_data = convert_sentiment_label(raw_data)"]},{"cell_type":"code","execution_count":9,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":178},"id":"xNda-mfAWxlK","executionInfo":{"status":"ok","timestamp":1751518923788,"user_tz":-120,"elapsed":47,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"7688baa9-3256-4193-bd25-09e42bc7007c"},"outputs":[{"output_type":"execute_result","data":{"text/plain":["target\n","0 800000\n","1 800000\n","Name: count, dtype: int64"],"text/html":["<div>\n","<style scoped>\n"," .dataframe tbody tr th:only-of-type {\n"," vertical-align: middle;\n"," }\n","\n"," .dataframe tbody tr th {\n"," vertical-align: top;\n"," }\n","\n"," .dataframe thead th {\n"," text-align: right;\n"," }\n","</style>\n","<table border=\"1\" class=\"dataframe\">\n"," <thead>\n"," <tr style=\"text-align: right;\">\n"," <th></th>\n"," <th>count</th>\n"," </tr>\n"," <tr>\n"," <th>target</th>\n"," <th></th>\n"," </tr>\n"," </thead>\n"," <tbody>\n"," <tr>\n"," <th>0</th>\n"," <td>800000</td>\n"," </tr>\n"," <tr>\n"," <th>1</th>\n"," <td>800000</td>\n"," </tr>\n"," </tbody>\n","</table>\n","</div><br><label><b>dtype:</b> int64</label>"]},"metadata":{},"execution_count":9}],"source":["converted_target_data['target'].value_counts()"]},{"cell_type":"code","execution_count":10,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":178},"id":"q8z3nv-0WxlK","executionInfo":{"status":"ok","timestamp":1751518924142,"user_tz":-120,"elapsed":353,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"f6d597a5-83c9-4a4f-b869-75e62489625b"},"outputs":[{"output_type":"execute_result","data":{"text/plain":["target\n","0 50000\n","1 50000\n","Name: count, dtype: int64"],"text/html":["<div>\n","<style scoped>\n"," .dataframe tbody tr th:only-of-type {\n"," vertical-align: middle;\n"," }\n","\n"," .dataframe tbody tr th {\n"," vertical-align: top;\n"," }\n","\n"," .dataframe thead th {\n"," text-align: right;\n"," }\n","</style>\n","<table border=\"1\" class=\"dataframe\">\n"," <thead>\n"," <tr style=\"text-align: right;\">\n"," <th></th>\n"," <th>count</th>\n"," </tr>\n"," <tr>\n"," <th>target</th>\n"," <th></th>\n"," </tr>\n"," </thead>\n"," <tbody>\n"," <tr>\n"," <th>0</th>\n"," <td>50000</td>\n"," </tr>\n"," <tr>\n"," <th>1</th>\n"," <td>50000</td>\n"," </tr>\n"," </tbody>\n","</table>\n","</div><br><label><b>dtype:</b> int64</label>"]},"metadata":{},"execution_count":10}],"source":["def downsample_data(df, n_samples=50000):\n"," \"\"\"\n"," Réduit la taille d'un DataFrame en échantillonnant aléatoirement un nombre spécifié de lignes pour chaque classe.\n"," \"\"\"\n"," negative_samples = df[df['target'] == 0].sample(n=n_samples, random_state=42)\n"," positive_samples = df[df['target'] == 1].sample(n=n_samples, random_state=42)\n"," downsampled_data = pd.concat([negative_samples, positive_samples])\n"," return downsampled_data\n","\n","downsampled_data = downsample_data(converted_target_data, n_samples=50000)\n","downsampled_data['target'].value_counts()"]},{"cell_type":"markdown","metadata":{"id":"TQAPEWmGWxlK"},"source":["## Prétraitement"]},{"cell_type":"code","execution_count":11,"metadata":{"id":"gViLa1h8WxlK","executionInfo":{"status":"ok","timestamp":1751518924143,"user_tz":-120,"elapsed":3,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"outputs":[],"source":["from multiprocessing import Pool\n","\n","# Fonction de prétraitement pour les tweets\n","def preprocess_tweet(tweet):\n"," \"\"\"\n"," Prétraite un tweet en appliquant plusieurs transformations :\n"," - Conversion en minuscules\n"," - Remplacement des URLs, mentions et hashtags par des tokens spéciaux\n"," - Suppression des caractères spéciaux\n"," - Tokenisation et lemmatisation\n"," - Suppression des stopwords\n"," \"\"\"\n"," # Vérifier si le tweet est une chaîne de caractères\n"," if not isinstance(tweet, str):\n"," return \"\"\n","\n"," # Convertir en minuscules\n"," tweet = tweet.lower()\n","\n"," # Remplacer les URLs par un token spécial\n"," tweet = re.sub(r'https?://\\S+|www\\.\\S+', '<URL>', tweet)\n","\n"," # Remplacer les mentions par un token spécial\n"," tweet = re.sub(r'@\\w+', '<MENTION>', tweet)\n","\n"," # Traiter les hashtags (conserver le # comme token séparé et le mot qui suit)\n"," tweet = re.sub(r'#(\\w+)', r'# \\1', tweet)\n","\n"," # Traiter le langage html\n"," tweet = html.unescape(tweet)\n","\n"," # Supprimer les caractères spéciaux et les nombres, mais garder les tokens spéciaux\n"," tweet = re.sub(r'[^\\w\\s<>@#!?]', '', tweet)\n","\n"," # Tokenisation\n"," tokens = word_tokenize(tweet)\n","\n"," # Lemmatisation\n"," lemmatizer = WordNetLemmatizer()\n"," tokens = [lemmatizer.lemmatize(token) for token in tokens]\n","\n"," # Supprimer les stopwords, mais conserver les négations importantes\n"," stop_words = set(stopwords.words('english'))\n"," important_words = {'no', 'not', 'nor', 'neither', 'never', 'nobody', 'none', 'nothing', 'nowhere'}\n"," stop_words = stop_words - important_words\n"," tokens = [token for token in tokens if token not in stop_words]\n","\n"," # Rejoindre les tokens en une chaîne\n"," return ' '.join(tokens)\n","\n","\n","def process_in_parallel(df, func, n_jobs=4):\n"," \"\"\"\n"," Applique une fonction à un DataFrame en le divisant en parties et en traitant chaque partie en parallèle.\n"," Permet d'accélérer le traitement sur les ordinateurs multi-coeurs.\n"," \"\"\"\n"," df_split = np.array_split(df, n_jobs)\n"," pool = Pool(n_jobs)\n"," df = pd.concat(pool.map(func, df_split))\n"," pool.close()\n"," pool.join()\n"," return df\n","\n","def apply_preprocessing(df_part):\n"," df_part['processed_text'] = df_part['text'].apply(preprocess_tweet)\n"," return df_part"]},{"cell_type":"code","execution_count":12,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"lrQfmMHMWxlL","outputId":"cdc8cb19-8897-485f-e262-a5dd14c0ef83","executionInfo":{"status":"ok","timestamp":1751518976241,"user_tz":-120,"elapsed":52100,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"outputs":[{"output_type":"stream","name":"stdout","text":["Prétraitement des tweets en cours...\n","Prétraitement terminé !\n"]}],"source":["# Appliquer le prétraitement à tous les tweets\n","print(\"Prétraitement des tweets en cours...\")\n","# downsampled_data['processed_text'] = downsampled_data['text'].apply(preprocess_tweet)\n","# Utilisation\n","preprocessed_data = process_in_parallel(downsampled_data, apply_preprocessing, n_jobs=8)\n","print(\"Prétraitement terminé !\")"]},{"cell_type":"code","execution_count":13,"metadata":{"id":"NYmqSwSiWxlL","colab":{"base_uri":"https://localhost:8080/","height":573},"executionInfo":{"status":"ok","timestamp":1751518976643,"user_tz":-120,"elapsed":404,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"c17af4b4-d114-44c2-aa80-a58e5eddc224"},"outputs":[{"output_type":"execute_result","data":{"text/plain":[" target ids date flag \\\n","212188 0 1974671194 Sat May 30 13:36:31 PDT 2009 NO_QUERY \n","299036 0 1997882236 Mon Jun 01 17:37:11 PDT 2009 NO_QUERY \n","475978 0 2177756662 Mon Jun 15 06:39:05 PDT 2009 NO_QUERY \n","588988 0 2216838047 Wed Jun 17 20:02:12 PDT 2009 NO_QUERY \n","138859 0 1880666283 Fri May 22 02:03:31 PDT 2009 NO_QUERY \n","\n"," user text \\\n","212188 simba98 @xnausikaax oh no! where did u order from? tha... \n","299036 Seve76 A great hard training weekend is over. a coup... \n","475978 x__claireyy__x Right, off to work Only 5 hours to go until I... \n","588988 Balasi I am craving for japanese food \n","138859 djrickdawson Jean Michel Jarre concert tomorrow gotta work... \n","\n"," processed_text \n","212188 < MENTION > oh no ! u order ? thats horrible \n","299036 great hard training weekend couple day rest le... \n","475978 right work 5 hour go im free xd \n","588988 craving japanese food \n","138859 jean michel jarre concert tomorrow got ta work... "],"text/html":["\n"," <div id=\"df-337bf10a-4559-41e5-a931-1afb12869536\" class=\"colab-df-container\">\n"," <div>\n","<style scoped>\n"," .dataframe tbody tr th:only-of-type {\n"," vertical-align: middle;\n"," }\n","\n"," .dataframe tbody tr th {\n"," vertical-align: top;\n"," }\n","\n"," .dataframe thead th {\n"," text-align: right;\n"," }\n","</style>\n","<table border=\"1\" class=\"dataframe\">\n"," <thead>\n"," <tr style=\"text-align: right;\">\n"," <th></th>\n"," <th>target</th>\n"," <th>ids</th>\n"," <th>date</th>\n"," <th>flag</th>\n"," <th>user</th>\n"," <th>text</th>\n"," <th>processed_text</th>\n"," </tr>\n"," </thead>\n"," <tbody>\n"," <tr>\n"," <th>212188</th>\n"," <td>0</td>\n"," <td>1974671194</td>\n"," <td>Sat May 30 13:36:31 PDT 2009</td>\n"," <td>NO_QUERY</td>\n"," <td>simba98</td>\n"," <td>@xnausikaax oh no! where did u order from? tha...</td>\n"," <td>&lt; MENTION &gt; oh no ! u order ? thats horrible</td>\n"," </tr>\n"," <tr>\n"," <th>299036</th>\n"," <td>0</td>\n"," <td>1997882236</td>\n"," <td>Mon Jun 01 17:37:11 PDT 2009</td>\n"," <td>NO_QUERY</td>\n"," <td>Seve76</td>\n"," <td>A great hard training weekend is over. a coup...</td>\n"," <td>great hard training weekend couple day rest le...</td>\n"," </tr>\n"," <tr>\n"," <th>475978</th>\n"," <td>0</td>\n"," <td>2177756662</td>\n"," <td>Mon Jun 15 06:39:05 PDT 2009</td>\n"," <td>NO_QUERY</td>\n"," <td>x__claireyy__x</td>\n"," <td>Right, off to work Only 5 hours to go until I...</td>\n"," <td>right work 5 hour go im free xd</td>\n"," </tr>\n"," <tr>\n"," <th>588988</th>\n"," <td>0</td>\n"," <td>2216838047</td>\n"," <td>Wed Jun 17 20:02:12 PDT 2009</td>\n"," <td>NO_QUERY</td>\n"," <td>Balasi</td>\n"," <td>I am craving for japanese food</td>\n"," <td>craving japanese food</td>\n"," </tr>\n"," <tr>\n"," <th>138859</th>\n"," <td>0</td>\n"," <td>1880666283</td>\n"," <td>Fri May 22 02:03:31 PDT 2009</td>\n"," <td>NO_QUERY</td>\n"," <td>djrickdawson</td>\n"," <td>Jean Michel Jarre concert tomorrow gotta work...</td>\n"," <td>jean michel jarre concert tomorrow got ta work...</td>\n"," </tr>\n"," </tbody>\n","</table>\n","</div>\n"," <div class=\"colab-df-buttons\">\n","\n"," <div class=\"colab-df-container\">\n"," <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-337bf10a-4559-41e5-a931-1afb12869536')\"\n"," title=\"Convert this dataframe to an interactive table.\"\n"," style=\"display:none;\">\n","\n"," <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n"," <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n"," </svg>\n"," </button>\n","\n"," <style>\n"," .colab-df-container {\n"," display:flex;\n"," gap: 12px;\n"," }\n","\n"," .colab-df-convert {\n"," background-color: #E8F0FE;\n"," border: none;\n"," border-radius: 50%;\n"," cursor: pointer;\n"," display: none;\n"," fill: #1967D2;\n"," height: 32px;\n"," padding: 0 0 0 0;\n"," width: 32px;\n"," }\n","\n"," .colab-df-convert:hover {\n"," background-color: #E2EBFA;\n"," box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n"," fill: #174EA6;\n"," }\n","\n"," .colab-df-buttons div {\n"," margin-bottom: 4px;\n"," }\n","\n"," [theme=dark] .colab-df-convert {\n"," background-color: #3B4455;\n"," fill: #D2E3FC;\n"," }\n","\n"," [theme=dark] .colab-df-convert:hover {\n"," background-color: #434B5C;\n"," box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n"," filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n"," fill: #FFFFFF;\n"," }\n"," </style>\n","\n"," <script>\n"," const buttonEl =\n"," document.querySelector('#df-337bf10a-4559-41e5-a931-1afb12869536 button.colab-df-convert');\n"," buttonEl.style.display =\n"," google.colab.kernel.accessAllowed ? 'block' : 'none';\n","\n"," async function convertToInteractive(key) {\n"," const element = document.querySelector('#df-337bf10a-4559-41e5-a931-1afb12869536');\n"," const dataTable =\n"," await google.colab.kernel.invokeFunction('convertToInteractive',\n"," [key], {});\n"," if (!dataTable) return;\n","\n"," const docLinkHtml = 'Like what you see? Visit the ' +\n"," '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n"," + ' to learn more about interactive tables.';\n"," element.innerHTML = '';\n"," dataTable['output_type'] = 'display_data';\n"," await google.colab.output.renderOutput(dataTable, element);\n"," const docLink = document.createElement('div');\n"," docLink.innerHTML = docLinkHtml;\n"," element.appendChild(docLink);\n"," }\n"," </script>\n"," </div>\n","\n","\n"," <div id=\"df-659e7720-9f17-4e01-8e72-a864968f17d1\">\n"," <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-659e7720-9f17-4e01-8e72-a864968f17d1')\"\n"," title=\"Suggest charts\"\n"," style=\"display:none;\">\n","\n","<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n"," width=\"24px\">\n"," <g>\n"," <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n"," </g>\n","</svg>\n"," </button>\n","\n","<style>\n"," .colab-df-quickchart {\n"," --bg-color: #E8F0FE;\n"," --fill-color: #1967D2;\n"," --hover-bg-color: #E2EBFA;\n"," --hover-fill-color: #174EA6;\n"," --disabled-fill-color: #AAA;\n"," --disabled-bg-color: #DDD;\n"," }\n","\n"," [theme=dark] .colab-df-quickchart {\n"," --bg-color: #3B4455;\n"," --fill-color: #D2E3FC;\n"," --hover-bg-color: #434B5C;\n"," --hover-fill-color: #FFFFFF;\n"," --disabled-bg-color: #3B4455;\n"," --disabled-fill-color: #666;\n"," }\n","\n"," .colab-df-quickchart {\n"," background-color: var(--bg-color);\n"," border: none;\n"," border-radius: 50%;\n"," cursor: pointer;\n"," display: none;\n"," fill: var(--fill-color);\n"," height: 32px;\n"," padding: 0;\n"," width: 32px;\n"," }\n","\n"," .colab-df-quickchart:hover {\n"," background-color: var(--hover-bg-color);\n"," box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n"," fill: var(--button-hover-fill-color);\n"," }\n","\n"," .colab-df-quickchart-complete:disabled,\n"," .colab-df-quickchart-complete:disabled:hover {\n"," background-color: var(--disabled-bg-color);\n"," fill: var(--disabled-fill-color);\n"," box-shadow: none;\n"," }\n","\n"," .colab-df-spinner {\n"," border: 2px solid var(--fill-color);\n"," border-color: transparent;\n"," border-bottom-color: var(--fill-color);\n"," animation:\n"," spin 1s steps(1) infinite;\n"," }\n","\n"," @keyframes spin {\n"," 0% {\n"," border-color: transparent;\n"," border-bottom-color: var(--fill-color);\n"," border-left-color: var(--fill-color);\n"," }\n"," 20% {\n"," border-color: transparent;\n"," border-left-color: var(--fill-color);\n"," border-top-color: var(--fill-color);\n"," }\n"," 30% {\n"," border-color: transparent;\n"," border-left-color: var(--fill-color);\n"," border-top-color: var(--fill-color);\n"," border-right-color: var(--fill-color);\n"," }\n"," 40% {\n"," border-color: transparent;\n"," border-right-color: var(--fill-color);\n"," border-top-color: var(--fill-color);\n"," }\n"," 60% {\n"," border-color: transparent;\n"," border-right-color: var(--fill-color);\n"," }\n"," 80% {\n"," border-color: transparent;\n"," border-right-color: var(--fill-color);\n"," border-bottom-color: var(--fill-color);\n"," }\n"," 90% {\n"," border-color: transparent;\n"," border-bottom-color: var(--fill-color);\n"," }\n"," }\n","</style>\n","\n"," <script>\n"," async function quickchart(key) {\n"," const quickchartButtonEl =\n"," document.querySelector('#' + key + ' button');\n"," quickchartButtonEl.disabled = true; // To prevent multiple clicks.\n"," quickchartButtonEl.classList.add('colab-df-spinner');\n"," try {\n"," const charts = await google.colab.kernel.invokeFunction(\n"," 'suggestCharts', [key], {});\n"," } catch (error) {\n"," console.error('Error during call to suggestCharts:', error);\n"," }\n"," quickchartButtonEl.classList.remove('colab-df-spinner');\n"," quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n"," }\n"," (() => {\n"," let quickchartButtonEl =\n"," document.querySelector('#df-659e7720-9f17-4e01-8e72-a864968f17d1 button');\n"," quickchartButtonEl.style.display =\n"," google.colab.kernel.accessAllowed ? 'block' : 'none';\n"," })();\n"," </script>\n"," </div>\n","\n"," </div>\n"," </div>\n"],"application/vnd.google.colaboratory.intrinsic+json":{"type":"dataframe","variable_name":"preprocessed_data","summary":"{\n \"name\": \"preprocessed_data\",\n \"rows\": 100000,\n \"fields\": [\n {\n \"column\": \"target\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0,\n \"min\": 0,\n \"max\": 1,\n \"num_unique_values\": 2,\n \"samples\": [\n 1,\n 0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"ids\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 192922675,\n \"min\": 1467811594,\n \"max\": 2329205473,\n \"num_unique_values\": 99996,\n \"samples\": [\n 2046950711,\n 2254018011\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"date\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 93451,\n \"samples\": [\n \"Fri Jun 05 17:55:21 PDT 2009\",\n \"Mon Jun 01 00:07:41 PDT 2009\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"flag\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"NO_QUERY\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"user\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 82677,\n \"samples\": [\n \"FRSoul\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"text\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 99702,\n \"samples\": [\n \"@dsrosenthal I was using adium 1.4b5, just upgraded to 1.4b6...same fail \"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"processed_text\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 97332,\n \"samples\": [\n \"york thingy finially arrived time waiting week uea managed get three 9 day speedy no ?\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}"}},"metadata":{},"execution_count":13}],"source":["preprocessed_data.head()"]},{"cell_type":"markdown","metadata":{"id":"l4VJWKrLWxlL"},"source":["## Division des données en ensembles d'entraînement et de test"]},{"cell_type":"code","execution_count":14,"metadata":{"id":"FqmMGjWlWxlL","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1751518976673,"user_tz":-120,"elapsed":29,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"cd7fe4d7-bfa9-45cf-af57-cd9e4cbb7ea0"},"outputs":[{"output_type":"stream","name":"stdout","text":["Taille de l'ensemble d'entraînement: 80000 exemples\n","Taille de l'ensemble de test: 20000 exemples\n"]}],"source":["# Diviser les données en ensembles d'entraînement et de test\n","from sklearn.model_selection import train_test_split\n","\n","X = preprocessed_data['processed_text']\n","y = preprocessed_data['target']\n","\n","# Division train/test\n","X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)\n","\n","print(f\"Taille de l'ensemble d'entraînement: {X_train.shape[0]} exemples\")\n","print(f\"Taille de l'ensemble de test: {X_test.shape[0]} exemples\")"]},{"cell_type":"markdown","metadata":{"id":"yJFkgjxWWxlL"},"source":["## Entraînement des modèles et tracking avec MLflow"]},{"cell_type":"markdown","metadata":{"id":"wKdwVenuWxlL"},"source":["### Configuration de MLFlow"]},{"cell_type":"code","execution_count":15,"metadata":{"id":"ZbDFrgXCWxlL","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1751518978064,"user_tz":-120,"elapsed":1400,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"05006948-cdb7-4d78-c648-172d2b642ce5"},"outputs":[{"output_type":"stream","name":"stdout","text":["MLflow Tracking URI: https://mlflow.greg-madman-nas.duckdns.org/\n","Identifiants AWS configurés\n"]}],"source":["import mlflow\n","from mlflow.models import infer_signature\n","from mlflow import MlflowClient\n","from dotenv import load_dotenv\n","\n","# Charger les variables d'environnement depuis le fichier .env\n","load_dotenv()\n","\n","# Configuration de MLflow avec les variables d'environnement\n","mlflow_tracking_uri = os.getenv(\"MLFLOW_TRACKING_URI\")\n","mlflow_s3_endpoint_url = os.getenv(\"MLFLOW_S3_ENDPOINT_URL\")\n","aws_access_key_id = os.getenv(\"AWS_ACCESS_KEY_ID\")\n","aws_secret_access_key = os.getenv(\"AWS_SECRET_ACCESS_KEY\")\n","\n","# Configuration explicite de MLflow\n","mlflow.set_tracking_uri(mlflow_tracking_uri)\n","print(f\"MLflow Tracking URI: {mlflow_tracking_uri}\")\n","\n","# Configuration explicite des identifiants AWS\n","os.environ[\"MLFLOW_S3_ENDPOINT_URL\"] = mlflow_s3_endpoint_url\n","os.environ[\"AWS_ACCESS_KEY_ID\"] = aws_access_key_id\n","os.environ[\"AWS_SECRET_ACCESS_KEY\"] = aws_secret_access_key\n","print(\"Identifiants AWS configurés\")"]},{"cell_type":"code","source":["mlflow_s3_endpoint_url"],"metadata":{"id":"7sJsURWwthEX","colab":{"base_uri":"https://localhost:8080/","height":35},"executionInfo":{"status":"ok","timestamp":1751518978067,"user_tz":-120,"elapsed":2,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"cd05a691-d06d-49f5-b2cc-92e9bc1e4ff0"},"execution_count":16,"outputs":[{"output_type":"execute_result","data":{"text/plain":["'https://minio-api.greg-madman-nas.duckdns.org'"],"application/vnd.google.colaboratory.intrinsic+json":{"type":"string"}},"metadata":{},"execution_count":16}]},{"cell_type":"code","execution_count":17,"metadata":{"id":"vOmnl37nWxlL","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1751518978487,"user_tz":-120,"elapsed":410,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"57a9367f-7f82-44a8-c517-190bc6c795e7"},"outputs":[{"output_type":"execute_result","data":{"text/plain":["<Experiment: artifact_location='s3://mlflow-artifacts/1', creation_time=1750773088095, experiment_id='1', last_update_time=1750773088095, lifecycle_stage='active', name='OC Projet 7', tags={}>"]},"metadata":{},"execution_count":17}],"source":["# Créer l'expérience MLflow\n","mlflow.set_experiment(\"OC Projet 7\")"]},{"cell_type":"markdown","metadata":{"id":"EkMowUjYWxlL"},"source":["### Vectorisation des textes\n","\n","La vectorisation est le processus qui transforme des documents textuels en vecteurs numériques exploitables par les algorithmes de machine learning. Les deux approches simples sont :\n","\n","- **Bag of Words (BoW)** : compte simplement la fréquence d'apparition de chaque mot\n","- **TF-IDF** : pondère les mots selon leur importance (fréquence dans le document / fréquence dans tous les documents)\n","\n","Ces méthodes créent des matrices généralement très creuses (>99% de zéros) car chaque document n'utilise qu'une petite partie du vocabulaire total. Dans notre implémentation, nous utilisons `CountVectorizer` pour l'approche BoW et `TfidfVectorizer` pour le TF-IDF, avec des n-grammes (1,2) qui permettent de capturer des expressions de deux mots consécutifs.\n"]},{"cell_type":"code","execution_count":18,"metadata":{"id":"Wn-UOIB_WxlL","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1751518984144,"user_tz":-120,"elapsed":5656,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"b0dd07a3-410c-46c0-9c8d-b752f57398a4"},"outputs":[{"output_type":"stream","name":"stdout","text":["Vectorisation terminée !\n"]}],"source":["from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer\n","\n","# Créer les vectoriseurs\n","tfidf_vectorizer = TfidfVectorizer(max_features=10000, ngram_range=(1, 2))\n","bow_vectorizer = CountVectorizer(max_features=10000, ngram_range=(1, 2))\n","\n","\n","# Transformer les textes en vecteurs TF-IDF\n","X_train_tfidf = tfidf_vectorizer.fit_transform(X_train)\n","X_test_tfidf = tfidf_vectorizer.transform(X_test)\n","\n","# Transformer les textes en vecteurs BoW\n","X_train_bow = bow_vectorizer.fit_transform(X_train)\n","X_test_bow = bow_vectorizer.transform(X_test)\n","\n","print(\"Vectorisation terminée !\")"]},{"cell_type":"markdown","metadata":{"id":"idwGMj8IWxlM"},"source":["### Fonction d'évaluation des modèles"]},{"cell_type":"code","execution_count":19,"metadata":{"id":"gypFHG57WxlM","executionInfo":{"status":"ok","timestamp":1751518984151,"user_tz":-120,"elapsed":12,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"outputs":[],"source":["def evaluate_model(model, X_train, X_test, y_train, y_test, model_name, vectorizer_name):\n"," \"\"\"\n"," Évalue un modèle déjà entraîné et retourne les résultats\n"," \"\"\"\n"," # Prédictions sur l'ensemble de test\n"," y_pred = model.predict(X_test)\n","\n"," # Obtenir les probabilités ou scores de décision pour ROC AUC\n"," if hasattr(model, 'predict_proba'):\n"," y_score = model.predict_proba(X_test)[:, 1]\n"," elif hasattr(model, 'decision_function'):\n"," y_score = model.decision_function(X_test)\n"," else:\n"," y_score = y_pred # Fallback pour les modèles qui n'ont pas ces méthodes\n","\n"," # Calculer les métriques\n"," accuracy = accuracy_score(y_test, y_pred)\n"," precision = precision_score(y_test, y_pred)\n"," recall = recall_score(y_test, y_pred)\n"," f1 = f1_score(y_test, y_pred)\n"," roc_auc = roc_auc_score(y_test, y_score)\n","\n"," # Créer la matrice de confusion sous forme de figure\n"," cm = confusion_matrix(y_test, y_pred)\n"," fig_cm, ax_cm = plt.subplots(figsize=(8, 6))\n"," sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', ax=ax_cm)\n"," ax_cm.set_xlabel('Prédiction')\n"," ax_cm.set_ylabel('Valeur réelle')\n"," ax_cm.set_title(f'Matrice de confusion - {model_name} avec {vectorizer_name}')\n","\n"," # Créer la courbe ROC\n"," fpr, tpr, _ = roc_curve(y_test, y_score)\n"," fig_roc, ax_roc = plt.subplots(figsize=(8, 6))\n"," ax_roc.plot(fpr, tpr, label=f'ROC curve (AUC = {roc_auc:.3f})')\n"," ax_roc.plot([0, 1], [0, 1], 'k--')\n"," ax_roc.set_xlim([0.0, 1.0])\n"," ax_roc.set_ylim([0.0, 1.05])\n"," ax_roc.set_xlabel('Taux de faux positifs')\n"," ax_roc.set_ylabel('Taux de vrais positifs')\n"," ax_roc.set_title(f'Courbe ROC - {model_name} avec {vectorizer_name}')\n"," ax_roc.legend(loc=\"lower right\")\n"," ax_roc.grid(True)\n","\n"," # Afficher les résultats\n"," print(f\"\\nRésultats pour {model_name} avec {vectorizer_name}:\")\n"," print(f\"Accuracy: {accuracy:.4f}\")\n"," print(f\"Precision: {precision:.4f}\")\n"," print(f\"Recall: {recall:.4f}\")\n"," print(f\"F1 Score: {f1:.4f}\")\n"," print(f\"ROC AUC: {roc_auc:.4f}\")\n"," print(\"\\nMatrice de confusion:\")\n"," print(cm)\n"," print(\"\\nRapport de classification:\")\n"," print(classification_report(y_test, y_pred))\n","\n"," return accuracy, precision, recall, f1, roc_auc, fig_cm, fig_roc, y_pred"]},{"cell_type":"markdown","metadata":{"id":"VY7mn8peWxlM"},"source":["### Initialiser les modèles à tester\n","\n","Voici la liste des modèles de classification supervisée que nous allons tester, accompagnée d'une brève présentation de leurs principes, avantages et limitations :\n","\n","- **Régression Logistique** \n"," Modèle linéaire simple et efficace pour les tâches de classification binaire. Il modélise la probabilité d'appartenance à une classe. \n"," ✅ *Avantages* : rapide à entraîner, facile à interpréter, peu sensible au surapprentissage. \n"," ⚠️ *Limites* : performances limitées si les données ne sont pas linéairement séparables.\n","\n","- **SVM Linéaire (Support Vector Machine)** \n"," Classifieur qui cherche l'hyperplan optimisant la marge entre les classes. Très adapté aux représentations vectorielles comme TF-IDF. \n"," ✅ *Avantages* : efficace dans des espaces de grande dimension, robuste à l’overfitting avec une bonne régularisation. \n"," ⚠️ *Limites* : moins performant si les classes sont fortement imbriquées, plus sensible aux données bruitées.\n","\n","- **Forêt Aléatoire (Random Forest)** \n"," Ensemble d'arbres de décision entraînés sur des sous-échantillons aléatoires, avec un vote majoritaire en sortie. \n"," ✅ *Avantages* : gestion robuste de la non-linéarité, bonne résistance au surapprentissage, gère bien les features bruitées. \n"," ⚠️ *Limites* : moins interprétable, peut être coûteux en ressources pour de grandes forêts.\n","\n","- **Naive Bayes (Multinomial)** \n"," Classifieur probabiliste basé sur le théorème de Bayes, avec l'hypothèse d’indépendance conditionnelle entre les features. \n"," ✅ *Avantages* : extrêmement rapide, très efficace sur des textes représentés par BoW ou TF-IDF, souvent difficile à battre en NLP classique. \n"," ⚠️ *Limites* : hypothèse d’indépendance souvent irréaliste, mais dans la pratique les performances restent bonnes même si elle est violée.\n","\n","> 🧠 **Pourquoi ces modèles ?** \n","Ils sont tous adaptés aux représentations vectorielles classiques (BoW, TF-IDF), et offrent un bon compromis entre performance, vitesse d'entraînement et interprétabilité. Leur diversité permet aussi d'évaluer plusieurs familles d’algorithmes (linéaires, probabilistes, ensembles, marge maximale) sur le même jeu de données.\n"]},{"cell_type":"code","execution_count":20,"metadata":{"id":"N81VF_EvWxlM","executionInfo":{"status":"ok","timestamp":1751518984153,"user_tz":-120,"elapsed":3,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"outputs":[],"source":["# Initialiser les modèles à tester\n","base_models = {\n"," \"Regression_Logistique\": LogisticRegression(random_state=42),\n"," \"SVM_Lineaire\": LinearSVC(random_state=42),\n"," \"Random_Forest\": RandomForestClassifier(random_state=42),\n"," \"Naive_Bayes\": MultinomialNB()\n","}\n","\n","# Définir les grilles d'hyperparamètres pour GridSearchCV\n","param_grids = {\n"," \"Regression_Logistique\": {\n"," 'C': [0.01, 0.1, 1.0, 10.0],\n"," 'max_iter': [1000],\n"," 'solver': ['liblinear', 'saga']\n"," },\n"," \"SVM_Lineaire\": {\n"," 'C': [0.01, 0.1, 1.0, 10.0],\n"," 'max_iter': [1000],\n"," 'dual': [True, False]\n"," },\n"," \"Random_Forest\": {\n"," 'n_estimators': [50, 100, 200],\n"," 'max_depth': [None, 10, 20],\n"," 'min_samples_split': [2, 5]\n"," },\n"," \"Naive_Bayes\": {\n"," 'alpha': [0.1, 0.5, 1.0, 2.0]\n"," }\n","}\n","\n","# Dictionnaire des vectoriseurs\n","vectorizers = {\n"," \"TF-IDF\": (tfidf_vectorizer, X_train_tfidf, X_test_tfidf),\n"," \"BoW\": (bow_vectorizer, X_train_bow, X_test_bow)\n","}\n","\n","# Définir les scorers\n","scorers = {\n"," 'precision': make_scorer(precision_score),\n"," 'recall': make_scorer(recall_score),\n"," 'f1': make_scorer(f1_score),\n"," 'mcc': make_scorer(matthews_corrcoef),\n"," 'balanced_acc': make_scorer(balanced_accuracy_score)\n","}"]},{"cell_type":"markdown","metadata":{"id":"nAEoLNGmWxlM"},"source":["## Entrainement des modèles"]},{"cell_type":"code","execution_count":21,"metadata":{"id":"yOKPz7roWxlM","executionInfo":{"status":"ok","timestamp":1751518984163,"user_tz":-120,"elapsed":9,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"outputs":[],"source":["train_models = True"]},{"cell_type":"code","execution_count":22,"metadata":{"id":"zT0mYkAxWxlM","colab":{"base_uri":"https://localhost:8080/","height":1000},"outputId":"60892233-8faf-4d21-f00a-1abdaa114c04","executionInfo":{"status":"ok","timestamp":1751526849571,"user_tz":-120,"elapsed":7865406,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"outputs":[{"output_type":"stream","name":"stderr","text":["\rProgression globale: 0%| | 0/8 [00:00<?, ?it/s]"]},{"output_type":"stream","name":"stdout","text":["\n","================================================================================\n","Démarrage de GridSearchCV pour Regression_Logistique avec TF-IDF...\n","Fitting 5 folds for each of 8 candidates, totalling 40 fits\n","\n","Résultats pour Regression_Logistique avec TF-IDF:\n","Accuracy: 0.7832\n","Precision: 0.7766\n","Recall: 0.7950\n","F1 Score: 0.7857\n","ROC AUC: 0.8611\n","\n","Matrice de confusion:\n","[[7713 2287]\n"," [2050 7950]]\n","\n","Rapport de classification:\n"," precision recall f1-score support\n","\n"," 0 0.79 0.77 0.78 10000\n"," 1 0.78 0.80 0.79 10000\n","\n"," accuracy 0.78 20000\n"," macro avg 0.78 0.78 0.78 20000\n","weighted avg 0.78 0.78 0.78 20000\n","\n"]},{"output_type":"stream","name":"stderr","text":["2025/07/03 05:03:40 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n"]},{"output_type":"stream","name":"stdout","text":["Meilleurs paramètres: {'C': 1.0, 'max_iter': 1000, 'solver': 'saga'}\n","Meilleur score CV (Precision): 0.7724\n","F1 Score sur test: 0.7857\n","ROC AUC sur test: 0.8611\n","Temps d'entraînement: 26.42 secondes\n","🏃 View run Modele_Simple_Regression_Logistique_TF-IDF at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/1/runs/0d35789154e04e5388d69df118515074\n","🧪 View experiment at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/1\n"]},{"output_type":"stream","name":"stderr","text":["Dernier modèle: Regression_Logistique avec TF-IDF: 12%|█▎ | 1/8 [00:46<05:26, 46.66s/it]"]},{"output_type":"stream","name":"stdout","text":["\n","================================================================================\n","Démarrage de GridSearchCV pour Regression_Logistique avec BoW...\n","Fitting 5 folds for each of 8 candidates, totalling 40 fits\n","\n","Résultats pour Regression_Logistique avec BoW:\n","Accuracy: 0.7792\n","Precision: 0.7672\n","Recall: 0.8018\n","F1 Score: 0.7841\n","ROC AUC: 0.8514\n","\n","Matrice de confusion:\n","[[7567 2433]\n"," [1982 8018]]\n","\n","Rapport de classification:\n"," precision recall f1-score support\n","\n"," 0 0.79 0.76 0.77 10000\n"," 1 0.77 0.80 0.78 10000\n","\n"," accuracy 0.78 20000\n"," macro avg 0.78 0.78 0.78 20000\n","weighted avg 0.78 0.78 0.78 20000\n","\n"]},{"output_type":"stream","name":"stderr","text":["2025/07/03 05:08:59 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n"]},{"output_type":"stream","name":"stdout","text":["Meilleurs paramètres: {'C': 0.1, 'max_iter': 1000, 'solver': 'saga'}\n","Meilleur score CV (Precision): 0.7644\n","F1 Score sur test: 0.7841\n","ROC AUC sur test: 0.8514\n","Temps d'entraînement: 299.32 secondes\n","🏃 View run Modele_Simple_Regression_Logistique_BoW at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/1/runs/0c89cbaa893440b48fcf00faf65eb8fb\n","🧪 View experiment at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/1\n"]},{"output_type":"stream","name":"stderr","text":["Dernier modèle: Regression_Logistique avec BoW: 25%|██▌ | 2/8 [06:00<20:23, 203.93s/it] "]},{"output_type":"stream","name":"stdout","text":["\n","================================================================================\n","Démarrage de GridSearchCV pour SVM_Lineaire avec TF-IDF...\n","Fitting 5 folds for each of 8 candidates, totalling 40 fits\n","\n","Résultats pour SVM_Lineaire avec TF-IDF:\n","Accuracy: 0.7842\n","Precision: 0.7765\n","Recall: 0.7981\n","F1 Score: 0.7872\n","ROC AUC: 0.8612\n","\n","Matrice de confusion:\n","[[7703 2297]\n"," [2019 7981]]\n","\n","Rapport de classification:\n"," precision recall f1-score support\n","\n"," 0 0.79 0.77 0.78 10000\n"," 1 0.78 0.80 0.79 10000\n","\n"," accuracy 0.78 20000\n"," macro avg 0.78 0.78 0.78 20000\n","weighted avg 0.78 0.78 0.78 20000\n","\n"]},{"output_type":"stream","name":"stderr","text":["2025/07/03 05:09:48 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n"]},{"output_type":"stream","name":"stdout","text":["Meilleurs paramètres: {'C': 0.1, 'dual': True, 'max_iter': 1000}\n","Meilleur score CV (Precision): 0.7705\n","F1 Score sur test: 0.7872\n","ROC AUC sur test: 0.8612\n","Temps d'entraînement: 35.63 secondes\n","🏃 View run Modele_Simple_SVM_Lineaire_TF-IDF at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/1/runs/9a565ac797fd45959b57d95b940d623a\n","🧪 View experiment at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/1\n"]},{"output_type":"stream","name":"stderr","text":["Dernier modèle: SVM_Lineaire avec TF-IDF: 38%|███▊ | 3/8 [06:50<11:08, 133.74s/it] "]},{"output_type":"stream","name":"stdout","text":["\n","================================================================================\n","Démarrage de GridSearchCV pour SVM_Lineaire avec BoW...\n","Fitting 5 folds for each of 8 candidates, totalling 40 fits\n","\n","Résultats pour SVM_Lineaire avec BoW:\n","Accuracy: 0.7801\n","Precision: 0.7655\n","Recall: 0.8074\n","F1 Score: 0.7859\n","ROC AUC: 0.8516\n","\n","Matrice de confusion:\n","[[7527 2473]\n"," [1926 8074]]\n","\n","Rapport de classification:\n"," precision recall f1-score support\n","\n"," 0 0.80 0.75 0.77 10000\n"," 1 0.77 0.81 0.79 10000\n","\n"," accuracy 0.78 20000\n"," macro avg 0.78 0.78 0.78 20000\n","weighted avg 0.78 0.78 0.78 20000\n","\n"]},{"output_type":"stream","name":"stderr","text":["2025/07/03 05:12:16 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n"]},{"output_type":"stream","name":"stdout","text":["Meilleurs paramètres: {'C': 0.01, 'dual': True, 'max_iter': 1000}\n","Meilleur score CV (Precision): 0.7617\n","F1 Score sur test: 0.7859\n","ROC AUC sur test: 0.8516\n","Temps d'entraînement: 132.03 secondes\n","🏃 View run Modele_Simple_SVM_Lineaire_BoW at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/1/runs/b2b792fed8eb49089609e93bc0713d45\n","🧪 View experiment at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/1\n"]},{"output_type":"stream","name":"stderr","text":["Dernier modèle: SVM_Lineaire avec BoW: 50%|█████ | 4/8 [09:17<09:15, 138.91s/it] "]},{"output_type":"stream","name":"stdout","text":["\n","================================================================================\n","Démarrage de GridSearchCV pour Random_Forest avec TF-IDF...\n","Fitting 5 folds for each of 18 candidates, totalling 90 fits\n","\n","Résultats pour Random_Forest avec TF-IDF:\n","Accuracy: 0.7648\n","Precision: 0.7636\n","Recall: 0.7671\n","F1 Score: 0.7653\n","ROC AUC: 0.8416\n","\n","Matrice de confusion:\n","[[7625 2375]\n"," [2329 7671]]\n","\n","Rapport de classification:\n"," precision recall f1-score support\n","\n"," 0 0.77 0.76 0.76 10000\n"," 1 0.76 0.77 0.77 10000\n","\n"," accuracy 0.76 20000\n"," macro avg 0.76 0.76 0.76 20000\n","weighted avg 0.76 0.76 0.76 20000\n","\n"]},{"output_type":"stream","name":"stderr","text":["2025/07/03 06:11:11 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n"]},{"output_type":"stream","name":"stdout","text":["Meilleurs paramètres: {'max_depth': None, 'min_samples_split': 5, 'n_estimators': 200}\n","Meilleur score CV (Precision): 0.7611\n","F1 Score sur test: 0.7653\n","ROC AUC sur test: 0.8416\n","Temps d'entraînement: 3513.83 secondes\n","🏃 View run Modele_Simple_Random_Forest_TF-IDF at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/1/runs/d5f040683a304c3297bd939b6ee4fed9\n","🧪 View experiment at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/1\n"]},{"output_type":"stream","name":"stderr","text":["Dernier modèle: Random_Forest avec TF-IDF: 62%|██████▎ | 5/8 [1:08:35<1:08:35, 1371.95s/it]"]},{"output_type":"stream","name":"stdout","text":["\n","================================================================================\n","Démarrage de GridSearchCV pour Random_Forest avec BoW...\n","Fitting 5 folds for each of 18 candidates, totalling 90 fits\n","\n","Résultats pour Random_Forest avec BoW:\n","Accuracy: 0.7689\n","Precision: 0.7746\n","Recall: 0.7584\n","F1 Score: 0.7664\n","ROC AUC: 0.8439\n","\n","Matrice de confusion:\n","[[7793 2207]\n"," [2416 7584]]\n","\n","Rapport de classification:\n"," precision recall f1-score support\n","\n"," 0 0.76 0.78 0.77 10000\n"," 1 0.77 0.76 0.77 10000\n","\n"," accuracy 0.77 20000\n"," macro avg 0.77 0.77 0.77 20000\n","weighted avg 0.77 0.77 0.77 20000\n","\n"]},{"output_type":"stream","name":"stderr","text":["2025/07/03 07:13:10 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n"]},{"output_type":"stream","name":"stdout","text":["Meilleurs paramètres: {'max_depth': None, 'min_samples_split': 5, 'n_estimators': 200}\n","Meilleur score CV (Precision): 0.7700\n","F1 Score sur test: 0.7664\n","ROC AUC sur test: 0.8439\n","Temps d'entraînement: 3671.47 secondes\n","🏃 View run Modele_Simple_Random_Forest_BoW at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/1/runs/7be18b5ea5e34e009bdcc4d7075a621a\n","🧪 View experiment at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/1\n"]},{"output_type":"stream","name":"stderr","text":["Dernier modèle: Random_Forest avec BoW: 75%|███████▌ | 6/8 [2:10:36<1:12:20, 2170.40s/it] "]},{"output_type":"stream","name":"stdout","text":["\n","================================================================================\n","Démarrage de GridSearchCV pour Naive_Bayes avec TF-IDF...\n","Fitting 5 folds for each of 4 candidates, totalling 20 fits\n","\n","Résultats pour Naive_Bayes avec TF-IDF:\n","Accuracy: 0.7704\n","Precision: 0.7776\n","Recall: 0.7574\n","F1 Score: 0.7674\n","ROC AUC: 0.8511\n","\n","Matrice de confusion:\n","[[7834 2166]\n"," [2426 7574]]\n","\n","Rapport de classification:\n"," precision recall f1-score support\n","\n"," 0 0.76 0.78 0.77 10000\n"," 1 0.78 0.76 0.77 10000\n","\n"," accuracy 0.77 20000\n"," macro avg 0.77 0.77 0.77 20000\n","weighted avg 0.77 0.77 0.77 20000\n","\n"]},{"output_type":"stream","name":"stderr","text":["2025/07/03 07:13:51 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n"]},{"output_type":"stream","name":"stdout","text":["Meilleurs paramètres: {'alpha': 2.0}\n","Meilleur score CV (Precision): 0.7739\n","F1 Score sur test: 0.7674\n","ROC AUC sur test: 0.8511\n","Temps d'entraînement: 2.78 secondes\n","🏃 View run Modele_Simple_Naive_Bayes_TF-IDF at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/1/runs/64430125306243afab3cfa643aac487e\n","🧪 View experiment at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/1\n"]},{"output_type":"stream","name":"stderr","text":["Dernier modèle: Naive_Bayes avec TF-IDF: 88%|████████▊ | 7/8 [2:10:52<24:26, 1466.00s/it]"]},{"output_type":"stream","name":"stdout","text":["\n","================================================================================\n","Démarrage de GridSearchCV pour Naive_Bayes avec BoW...\n","Fitting 5 folds for each of 4 candidates, totalling 20 fits\n","\n","Résultats pour Naive_Bayes avec BoW:\n","Accuracy: 0.7718\n","Precision: 0.7766\n","Recall: 0.7632\n","F1 Score: 0.7698\n","ROC AUC: 0.8432\n","\n","Matrice de confusion:\n","[[7804 2196]\n"," [2368 7632]]\n","\n","Rapport de classification:\n"," precision recall f1-score support\n","\n"," 0 0.77 0.78 0.77 10000\n"," 1 0.78 0.76 0.77 10000\n","\n"," accuracy 0.77 20000\n"," macro avg 0.77 0.77 0.77 20000\n","weighted avg 0.77 0.77 0.77 20000\n","\n"]},{"output_type":"stream","name":"stderr","text":["2025/07/03 07:14:05 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n"]},{"output_type":"stream","name":"stdout","text":["Meilleurs paramètres: {'alpha': 2.0}\n","Meilleur score CV (Precision): 0.7713\n","F1 Score sur test: 0.7698\n","ROC AUC sur test: 0.8432\n","Temps d'entraînement: 1.02 secondes\n","🏃 View run Modele_Simple_Naive_Bayes_BoW at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/1/runs/74ceb382771d46f4b9cd1530ae012397\n","🧪 View experiment at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/1\n"]},{"output_type":"stream","name":"stderr","text":["Dernier modèle: Naive_Bayes avec BoW: 100%|██████████| 8/8 [2:11:05<00:00, 983.18s/it] \n"]},{"output_type":"display_data","data":{"text/plain":["<Figure size 1200x800 with 0 Axes>"]},"metadata":{}},{"output_type":"display_data","data":{"text/plain":["<Figure size 1200x800 with 0 Axes>"]},"metadata":{}},{"output_type":"display_data","data":{"text/plain":["<Figure size 1200x800 with 0 Axes>"]},"metadata":{}},{"output_type":"display_data","data":{"text/plain":["<Figure size 1200x800 with 0 Axes>"]},"metadata":{}},{"output_type":"display_data","data":{"text/plain":["<Figure size 1200x800 with 0 Axes>"]},"metadata":{}},{"output_type":"display_data","data":{"text/plain":["<Figure size 1200x800 with 0 Axes>"]},"metadata":{}},{"output_type":"display_data","data":{"text/plain":["<Figure size 1200x800 with 0 Axes>"]},"metadata":{}},{"output_type":"display_data","data":{"text/plain":["<Figure size 1200x800 with 0 Axes>"]},"metadata":{}}],"source":["if train_models:\n","\n"," # Tester chaque modèle avec les deux types de vectorisation\n"," total_iterations = len(base_models) * len(vectorizers)\n"," progress_bar = tqdm(total=total_iterations, desc=\"Progression globale\")\n","\n"," # Dictionnaire pour stocker les résultats\n"," results = []\n","\n"," # Tester chaque modèle avec les deux types de vectorisation\n"," for model_name, base_model in base_models.items():\n"," for vectorizer_name, (vectorizer, X_train_vec, X_test_vec) in vectorizers.items():\n"," print(f\"\\n{'='*80}\")\n"," print(f\"Démarrage de GridSearchCV pour {model_name} avec {vectorizer_name}...\")\n","\n"," # Définir la grille de paramètres et créer GridSearchCV\n"," param_grid = param_grids[model_name]\n","\n"," grid_search = GridSearchCV(\n"," base_model,\n"," param_grid,\n"," cv=5,\n"," scoring=scorers,\n"," refit='precision',\n"," n_jobs=-1,\n"," verbose=1,\n"," return_train_score=True\n"," )\n","\n"," # Démarrer le run MLflow\n"," with mlflow.start_run(run_name=f\"Modele_Simple_{model_name}_{vectorizer_name}\"):\n"," # Journaliser les paramètres généraux\n"," mlflow.log_param(\"model_type\", model_name)\n"," mlflow.log_param(\"vectorizer_type\", vectorizer_name)\n"," mlflow.log_param(\"dataset_size\", X_train.shape[0] + X_test.shape[0])\n"," mlflow.log_param(\"train_size\", X_train.shape[0])\n"," mlflow.log_param(\"test_size\", X_test.shape[0])\n"," mlflow.log_param(\"max_features\", 10000)\n"," mlflow.log_param(\"ngram_range\", \"(1, 2)\")\n"," mlflow.log_param(\"scoring_metric\", \"precision\") # Noter que precision est utilisé\n","\n"," # Mesurer le temps d'entraînement\n"," start_time = time.time()\n","\n"," # Entraîner avec GridSearchCV\n"," grid_search.fit(X_train_vec, y_train)\n","\n"," # Calculer le temps d'entraînement\n"," training_time = time.time() - start_time\n","\n"," # Journaliser le temps d'entraînement\n"," mlflow.log_metric(\"training_time\", training_time)\n","\n"," # Récupérer et journaliser les meilleurs paramètres\n"," best_params = grid_search.best_params_\n"," for param, value in best_params.items():\n"," mlflow.log_param(f\"best_{param}\", value)\n","\n"," # Journaliser le meilleur score de validation croisée\n"," mlflow.log_metric(\"val_precision\", grid_search.best_score_)\n","\n"," # Journaliser le recall score associé au modèle présentant la meilleure précision\n"," val_recall = grid_search.cv_results_['mean_test_recall'][grid_search.best_index_]\n"," mlflow.log_metric(\"val_recall\", val_recall)\n","\n","\n"," # Récupérer le meilleur modèle\n"," best_model = grid_search.best_estimator_\n","\n"," # Évaluer le meilleur modèle sur l'ensemble de test\n"," acc, prec, rec, f1, roc_auc, fig_cm, fig_roc, y_pred = evaluate_model(\n"," best_model, X_train_vec, X_test_vec, y_train, y_test, model_name, vectorizer_name\n"," )\n","\n"," # Journaliser les métriques sur l'ensemble de test\n"," mlflow.log_metric(\"test_accuracy\", acc)\n"," mlflow.log_metric(\"test_precision\", prec)\n"," mlflow.log_metric(\"test_recall\", rec)\n"," mlflow.log_metric(\"test_f1\", f1)\n"," mlflow.log_metric(\"test_roc_auc\", roc_auc)\n","\n"," # Journaliser les figures\n"," mlflow.log_figure(fig_cm, \"confusion_matrix.png\")\n"," mlflow.log_figure(fig_roc, \"roc_curve.png\")\n"," plt.close(fig_cm)\n"," plt.close(fig_roc)\n","\n"," # Journaliser le modèle\n"," signature = infer_signature(X_train_vec, y_pred)\n"," mlflow.sklearn.log_model(best_model, \"model\", signature=signature)\n","\n"," # Créer le dossier pour sauvegarder les artefacts\n"," os.makedirs(\"./content/simple-model\", exist_ok=True)\n","\n"," # Sauvegarder et journaliser le vectoriseur\n"," vectorizer_path = f\"./content/simple-model/vectorizer_{vectorizer_name}.pkl\"\n"," with open(vectorizer_path, \"wb\") as f:\n"," pickle.dump(vectorizer, f)\n"," mlflow.log_artifact(vectorizer_path)\n","\n"," # Journaliser les résultats détaillés de GridSearchCV\n"," cv_results = pd.DataFrame(grid_search.cv_results_)\n"," cv_results_path = \"./content/simple-model/cv_results.csv\"\n"," cv_results.to_csv(cv_results_path, index=False)\n"," mlflow.log_artifact(cv_results_path)\n","\n"," # Créer et journaliser un graphique des résultats de GridSearchCV\n"," plt.figure(figsize=(12, 8))\n"," params = [f\"{k}={v}\" for k, v in best_params.items()]\n"," params_str = \", \".join(params)\n","\n"," # Extraire les scores moyens pour chaque paramètre principal\n"," for param in param_grid.keys():\n"," if len(param_grid[param]) > 1: # Seulement si le paramètre a plusieurs valeurs\n"," param_name = f\"param_{param}\"\n"," if param_name in cv_results.columns:\n"," # Utiliser la colonne spécifique à la métrique precision\n"," scores_df = cv_results[[param_name, \"mean_test_precision\", \"std_test_precision\"]]\n"," scores_df = scores_df.sort_values(param_name)\n","\n"," plt.figure(figsize=(10, 6))\n"," plt.errorbar(\n"," scores_df[param_name].astype(str),\n"," scores_df[\"mean_test_precision\"],\n"," yerr=scores_df[\"std_test_precision\"],\n"," fmt='-o'\n"," )\n"," plt.title(f'Scores de validation croisée (Precision) par {param}')\n"," plt.xlabel(param)\n"," plt.ylabel('Precision moyenne')\n"," plt.grid(True)\n"," mlflow.log_figure(plt.gcf(), f\"cv_results_{param}.png\")\n"," plt.close()\n","\n"," # Journaliser les features importantes (pour les modèles qui le supportent)\n"," if hasattr(best_model, 'coef_'):\n"," # Récupérer les features les plus importantes\n"," if isinstance(best_model, LogisticRegression) or isinstance(best_model, LinearSVC):\n"," coefs = best_model.coef_[0]\n"," if vectorizer_name == \"TF-IDF\":\n"," feature_names = tfidf_vectorizer.get_feature_names_out()\n"," else:\n"," feature_names = bow_vectorizer.get_feature_names_out()\n","\n"," # Créer un DataFrame avec les coefs et les noms des features\n"," coefs_df = pd.DataFrame({\n"," 'feature': feature_names,\n"," 'importance': coefs\n"," })\n","\n"," # Trier par importance absolue\n"," coefs_df['abs_importance'] = abs(coefs_df['importance'])\n"," coefs_df = coefs_df.sort_values('abs_importance', ascending=False).head(20)\n","\n"," # Journaliser les features les plus importantes\n"," top_features_path = \"./content/simple-model/top_features.csv\"\n"," coefs_df.to_csv(top_features_path, index=False)\n"," mlflow.log_artifact(top_features_path)\n","\n"," # Créer un graphique pour visualiser les features les plus importantes\n"," plt.figure(figsize=(10, 8))\n"," sns.barplot(x='importance', y='feature', data=coefs_df.sort_values('importance', ascending=False).head(20))\n"," plt.title(f'Top 20 features positives')\n"," plt.tight_layout()\n"," mlflow.log_figure(plt.gcf(), \"top_positive_features.png\")\n"," plt.close()\n","\n"," plt.figure(figsize=(10, 8))\n"," sns.barplot(x='importance', y='feature', data=coefs_df.sort_values('importance').head(20))\n"," plt.title(f'Top 20 features négatives')\n"," plt.tight_layout()\n"," mlflow.log_figure(plt.gcf(), \"top_negative_features.png\")\n"," plt.close()\n","\n"," # Stocker les résultats pour comparaison\n"," results.append({\n"," \"Modèle\": model_name.replace(\"_\", \" \"),\n"," \"Vectorisation\": vectorizer_name,\n"," \"Meilleurs paramètres\": str(best_params),\n"," \"Accuracy\": acc,\n"," \"Precision\": prec,\n"," \"Recall\": rec,\n"," \"F1 Score\": f1,\n"," \"ROC AUC\": roc_auc,\n"," \"Temps d'entraînement (s)\": training_time\n"," })\n","\n"," # Afficher les résultats\n"," print(f\"Meilleurs paramètres: {best_params}\")\n"," print(f\"Meilleur score CV (Precision): {grid_search.best_score_:.4f}\")\n"," print(f\"F1 Score sur test: {f1:.4f}\")\n"," print(f\"ROC AUC sur test: {roc_auc:.4f}\")\n"," print(f\"Temps d'entraînement: {training_time:.2f} secondes\")\n","\n","\n"," # À la fin de chaque itération, mettez à jour la barre de progression\n"," progress_bar.update(1)\n"," progress_bar.set_description(f\"Dernier modèle: {model_name} avec {vectorizer_name}\")\n","\n"," progress_bar.close()"]},{"cell_type":"markdown","metadata":{"id":"MPL9yrErWxlN"},"source":["## Evaluation des performances"]},{"cell_type":"markdown","metadata":{"id":"54r-t1tDWxlN"},"source":["### Récupération des resultats depuis le serveur MLFLow"]},{"cell_type":"code","execution_count":23,"metadata":{"id":"PdlFbtWPWxlN","executionInfo":{"status":"ok","timestamp":1751526849583,"user_tz":-120,"elapsed":11,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"outputs":[],"source":["def get_mlflow_results(experiment_name=\"OC Projet 7\", prefixe_run=\"Modele_Simple_\", uri=None):\n"," \"\"\"\n"," Récupère les résultats des runs MLflow et les organise dans un dataframe\n","\n"," Parameters:\n"," -----------\n"," experiment_name : str\n"," Nom de l'expérience MLflow à rechercher\n"," prefixe_run : str\n"," Préfixe des noms de runs à inclure\n"," uri : str, optional\n"," URI du serveur MLflow. Si None, utilise l'URI configuré par défaut\n","\n"," Returns:\n"," --------\n"," pandas.DataFrame\n"," Dataframe contenant les résultats des runs MLflow\n"," \"\"\"\n"," # Se connecter au serveur MLflow si un URI est fourni\n"," if uri:\n"," mlflow.set_tracking_uri(uri)\n","\n"," # Créer un client MLflow\n"," client = MlflowClient()\n","\n"," # Récupérer l'ID de l'expérience\n"," try:\n"," experiment = client.get_experiment_by_name(experiment_name)\n"," if experiment is None:\n"," raise ValueError(f\"L'expérience '{experiment_name}' n'existe pas.\")\n"," experiment_id = experiment.experiment_id\n"," except Exception as e:\n"," print(f\"Erreur lors de la récupération de l'expérience : {e}\")\n"," return pd.DataFrame()\n","\n"," # Récupérer tous les runs de l'expérience\n"," runs = client.search_runs(\n"," experiment_ids=[experiment_id],\n"," filter_string=f\"tags.mlflow.runName LIKE '{prefixe_run}%'\",\n"," order_by=[\"metrics.prec DESC\"]\n"," )\n","\n"," # Créer une liste pour stocker les résultats\n"," resultats = []\n","\n"," # Parcourir chaque run et extraire les informations\n"," for run in runs:\n"," # Récupérer le nom du run pour information\n"," run_name = run.data.tags.get(\"mlflow.runName\", \"\")\n","\n"," # Utiliser les paramètres model_type et vectorizer_type de MLflow\n"," modele = run.data.params.get(\"model_type\", \"Inconnu\")\n"," vectorisation = run.data.params.get(\"vectorizer_type\", \"Inconnu\")\n","\n"," # Formater le nom du modèle (remplacer les underscores par des espaces)\n"," modele = modele.replace(\"_\", \" \")\n","\n"," # Extraire les métriques\n"," metrics = run.data.metrics\n"," params = run.data.params\n","\n"," # Construire un dictionnaire des meilleurs paramètres\n"," best_params = {}\n"," for key, value in params.items():\n"," if key.startswith(\"best_\"):\n"," param_name = key.replace(\"best_\", \"\")\n"," best_params[param_name] = value\n","\n"," # Créer une entrée pour le dataframe résultat\n"," resultats.append({\n"," \"Modèle\": modele,\n"," \"Vectorisation\": vectorisation,\n"," \"Meilleurs paramètres\": str(best_params),\n"," \"Accuracy\": metrics.get(\"test_accuracy\", None),\n"," \"Precision\": metrics.get(\"test_precision\", None),\n"," \"Recall\": metrics.get(\"test_recall\", None),\n"," \"F1 Score\": metrics.get(\"test_f1\", None),\n"," \"ROC AUC\": metrics.get(\"test_roc_auc\", None),\n"," \"Temps d'entraînement (s)\": metrics.get(\"training_time\", None),\n"," \"Run ID\": run.info.run_id,\n"," \"Run Name\": run_name\n"," })\n","\n"," # Créer un dataframe à partir des résultats\n"," df_resultats = pd.DataFrame(resultats)\n","\n"," # Trier le dataframe par Précision (décroissant)\n"," if not df_resultats.empty and \"Precision\" in df_resultats.columns:\n"," df_resultats = df_resultats.sort_values(\"Precision\", ascending=False)\n","\n"," return df_resultats"]},{"cell_type":"code","execution_count":24,"metadata":{"id":"KyCAS-69WxlN","executionInfo":{"status":"ok","timestamp":1751526850097,"user_tz":-120,"elapsed":513,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"outputs":[],"source":["# Récupérer les résultats\n","results_df = get_mlflow_results(experiment_name=\"OC Projet 7\", prefixe_run=\"Modele_Simple_\")"]},{"cell_type":"markdown","metadata":{"id":"sOFocHNnWxlN"},"source":["### Sauvegarde des résultats\n","\n","- Au format Markdown (.md)\n","- Au format CSV (.csv)"]},{"cell_type":"code","source":["import os\n","simple_model_path = \"./content/simple-model/\"\n","# Créer le dossier s'il n'existe pas\n","os.makedirs(simple_model_path, exist_ok=True)"],"metadata":{"id":"eTzchvr3OsJh","executionInfo":{"status":"ok","timestamp":1751526850101,"user_tz":-120,"elapsed":2,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"execution_count":25,"outputs":[]},{"cell_type":"code","execution_count":26,"metadata":{"id":"5YcvR-XBWxlN","executionInfo":{"status":"ok","timestamp":1751526850430,"user_tz":-120,"elapsed":326,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"outputs":[],"source":["def export_results_to_markdown(df, output_file=simple_model_path+\"mlflow_results.md\"):\n"," with open(output_file, \"w\") as f:\n"," f.write(\"# Résultats des expérimentations MLflow\\n\\n\")\n"," f.write(df.to_markdown(index=False))\n","\n","# Exporter les résultats au format Markdown\n","export_results_to_markdown(results_df)"]},{"cell_type":"code","execution_count":27,"metadata":{"id":"U_oJh48yWxlN","executionInfo":{"status":"ok","timestamp":1751526850765,"user_tz":-120,"elapsed":332,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"outputs":[],"source":["results_path = simple_model_path+\"/mlflow_results.csv\"\n","# Enregistrer le tableau des résultats (optionnel)\n","results_df.to_csv(results_path, index=False)"]},{"cell_type":"markdown","metadata":{"id":"9-c659sYWxlP"},"source":["### Visualisation des métriques"]},{"cell_type":"code","execution_count":28,"metadata":{"id":"3KiynT2KWxlQ","colab":{"base_uri":"https://localhost:8080/","height":1000},"executionInfo":{"status":"ok","timestamp":1751526850860,"user_tz":-120,"elapsed":62,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"1c2b1692-f581-47b7-d7fc-c2b259c2816e"},"outputs":[{"output_type":"execute_result","data":{"text/plain":[" Modèle Vectorisation \\\n","1 Naive Bayes TF-IDF \n","9 Naive Bayes TF-IDF \n","15 Regression Logistique TF-IDF \n","7 Regression Logistique TF-IDF \n","0 Naive Bayes BoW \n","8 Naive Bayes BoW \n","13 SVM Lineaire TF-IDF \n","5 SVM Lineaire TF-IDF \n","10 Random Forest BoW \n","2 Random Forest BoW \n","6 Regression Logistique BoW \n","14 Regression Logistique BoW \n","12 SVM Lineaire BoW \n","4 SVM Lineaire BoW \n","3 Random Forest TF-IDF \n","11 Random Forest TF-IDF \n","\n"," Meilleurs paramètres Accuracy Precision \\\n","1 {'alpha': '2.0'} 0.77040 0.777618 \n","9 {'alpha': '2.0'} 0.77040 0.777618 \n","15 {'C': '1.0', 'max_iter': '1000', 'solver': 'sa... 0.78315 0.776595 \n","7 {'C': '1.0', 'max_iter': '1000', 'solver': 'sa... 0.78315 0.776595 \n","0 {'alpha': '2.0'} 0.77180 0.776557 \n","8 {'alpha': '2.0'} 0.77180 0.776557 \n","13 {'C': '0.1', 'dual': 'True', 'max_iter': '1000'} 0.78420 0.776513 \n","5 {'C': '0.1', 'dual': 'True', 'max_iter': '1000'} 0.78420 0.776513 \n","10 {'max_depth': 'None', 'min_samples_split': '5'... 0.76885 0.774589 \n","2 {'max_depth': 'None', 'min_samples_split': '5'... 0.76885 0.774589 \n","6 {'C': '0.1', 'max_iter': '1000', 'solver': 'sa... 0.77925 0.767199 \n","14 {'C': '0.1', 'max_iter': '1000', 'solver': 'sa... 0.77925 0.767199 \n","12 {'C': '0.01', 'dual': 'True', 'max_iter': '1000'} 0.78005 0.765526 \n","4 {'C': '0.01', 'dual': 'True', 'max_iter': '1000'} 0.78005 0.765526 \n","3 {'max_depth': 'None', 'min_samples_split': '5'... 0.76480 0.763587 \n","11 {'max_depth': 'None', 'min_samples_split': '5'... 0.76480 0.763587 \n","\n"," Recall F1 Score ROC AUC Temps d'entraînement (s) \\\n","1 0.7574 0.767376 0.851067 2.777000 \n","9 0.7574 0.767376 0.851067 3.567882 \n","15 0.7950 0.785690 0.861098 33.858043 \n","7 0.7950 0.785690 0.861098 26.421158 \n","0 0.7632 0.769820 0.843168 1.016124 \n","8 0.7632 0.769820 0.843168 1.219065 \n","13 0.7981 0.787158 0.861249 42.945317 \n","5 0.7981 0.787158 0.861249 35.626043 \n","10 0.7584 0.766409 0.843950 5883.188167 \n","2 0.7584 0.766409 0.843950 3671.472166 \n","6 0.8018 0.784118 0.851395 299.318508 \n","14 0.8018 0.784118 0.851395 332.209190 \n","12 0.8074 0.785905 0.851585 154.561330 \n","4 0.8074 0.785905 0.851585 132.033319 \n","3 0.7671 0.765340 0.841649 3513.826061 \n","11 0.7671 0.765340 0.841649 5611.991874 \n","\n"," Run ID \\\n","1 64430125306243afab3cfa643aac487e \n","9 9f6ccc9a4b3e415695e2c05fa85d2bdb \n","15 c90a2914f2cb46c993cf98e2ef6f863e \n","7 0d35789154e04e5388d69df118515074 \n","0 74ceb382771d46f4b9cd1530ae012397 \n","8 dd8952ca25ed4d1aafc3567e07f3c02d \n","13 499aa47dec3647668dc9668287f7d738 \n","5 9a565ac797fd45959b57d95b940d623a \n","10 8c20d78baba443f3ba199d92340868bd \n","2 7be18b5ea5e34e009bdcc4d7075a621a \n","6 0c89cbaa893440b48fcf00faf65eb8fb \n","14 2c9f95becf5744f38e55f1642928d3e6 \n","12 4e80851a287142a7ae1720ad37a8c502 \n","4 b2b792fed8eb49089609e93bc0713d45 \n","3 d5f040683a304c3297bd939b6ee4fed9 \n","11 9d9300d6e5284095a0f25aa34d088c02 \n","\n"," Run Name \n","1 Modele_Simple_Naive_Bayes_TF-IDF \n","9 Modele_Simple_Naive_Bayes_TF-IDF \n","15 Modele_Simple_Regression_Logistique_TF-IDF \n","7 Modele_Simple_Regression_Logistique_TF-IDF \n","0 Modele_Simple_Naive_Bayes_BoW \n","8 Modele_Simple_Naive_Bayes_BoW \n","13 Modele_Simple_SVM_Lineaire_TF-IDF \n","5 Modele_Simple_SVM_Lineaire_TF-IDF \n","10 Modele_Simple_Random_Forest_BoW \n","2 Modele_Simple_Random_Forest_BoW \n","6 Modele_Simple_Regression_Logistique_BoW \n","14 Modele_Simple_Regression_Logistique_BoW \n","12 Modele_Simple_SVM_Lineaire_BoW \n","4 Modele_Simple_SVM_Lineaire_BoW \n","3 Modele_Simple_Random_Forest_TF-IDF \n","11 Modele_Simple_Random_Forest_TF-IDF "],"text/html":["\n"," <div id=\"df-34eac432-1cd4-43fd-903d-956e517f5a7d\" class=\"colab-df-container\">\n"," <div>\n","<style scoped>\n"," .dataframe tbody tr th:only-of-type {\n"," vertical-align: middle;\n"," }\n","\n"," .dataframe tbody tr th {\n"," vertical-align: top;\n"," }\n","\n"," .dataframe thead th {\n"," text-align: right;\n"," }\n","</style>\n","<table border=\"1\" class=\"dataframe\">\n"," <thead>\n"," <tr style=\"text-align: right;\">\n"," <th></th>\n"," <th>Modèle</th>\n"," <th>Vectorisation</th>\n"," <th>Meilleurs paramètres</th>\n"," <th>Accuracy</th>\n"," <th>Precision</th>\n"," <th>Recall</th>\n"," <th>F1 Score</th>\n"," <th>ROC AUC</th>\n"," <th>Temps d'entraînement (s)</th>\n"," <th>Run ID</th>\n"," <th>Run Name</th>\n"," </tr>\n"," </thead>\n"," <tbody>\n"," <tr>\n"," <th>1</th>\n"," <td>Naive Bayes</td>\n"," <td>TF-IDF</td>\n"," <td>{'alpha': '2.0'}</td>\n"," <td>0.77040</td>\n"," <td>0.777618</td>\n"," <td>0.7574</td>\n"," <td>0.767376</td>\n"," <td>0.851067</td>\n"," <td>2.777000</td>\n"," <td>64430125306243afab3cfa643aac487e</td>\n"," <td>Modele_Simple_Naive_Bayes_TF-IDF</td>\n"," </tr>\n"," <tr>\n"," <th>9</th>\n"," <td>Naive Bayes</td>\n"," <td>TF-IDF</td>\n"," <td>{'alpha': '2.0'}</td>\n"," <td>0.77040</td>\n"," <td>0.777618</td>\n"," <td>0.7574</td>\n"," <td>0.767376</td>\n"," <td>0.851067</td>\n"," <td>3.567882</td>\n"," <td>9f6ccc9a4b3e415695e2c05fa85d2bdb</td>\n"," <td>Modele_Simple_Naive_Bayes_TF-IDF</td>\n"," </tr>\n"," <tr>\n"," <th>15</th>\n"," <td>Regression Logistique</td>\n"," <td>TF-IDF</td>\n"," <td>{'C': '1.0', 'max_iter': '1000', 'solver': 'sa...</td>\n"," <td>0.78315</td>\n"," <td>0.776595</td>\n"," <td>0.7950</td>\n"," <td>0.785690</td>\n"," <td>0.861098</td>\n"," <td>33.858043</td>\n"," <td>c90a2914f2cb46c993cf98e2ef6f863e</td>\n"," <td>Modele_Simple_Regression_Logistique_TF-IDF</td>\n"," </tr>\n"," <tr>\n"," <th>7</th>\n"," <td>Regression Logistique</td>\n"," <td>TF-IDF</td>\n"," <td>{'C': '1.0', 'max_iter': '1000', 'solver': 'sa...</td>\n"," <td>0.78315</td>\n"," <td>0.776595</td>\n"," <td>0.7950</td>\n"," <td>0.785690</td>\n"," <td>0.861098</td>\n"," <td>26.421158</td>\n"," <td>0d35789154e04e5388d69df118515074</td>\n"," <td>Modele_Simple_Regression_Logistique_TF-IDF</td>\n"," </tr>\n"," <tr>\n"," <th>0</th>\n"," <td>Naive Bayes</td>\n"," <td>BoW</td>\n"," <td>{'alpha': '2.0'}</td>\n"," <td>0.77180</td>\n"," <td>0.776557</td>\n"," <td>0.7632</td>\n"," <td>0.769820</td>\n"," <td>0.843168</td>\n"," <td>1.016124</td>\n"," <td>74ceb382771d46f4b9cd1530ae012397</td>\n"," <td>Modele_Simple_Naive_Bayes_BoW</td>\n"," </tr>\n"," <tr>\n"," <th>8</th>\n"," <td>Naive Bayes</td>\n"," <td>BoW</td>\n"," <td>{'alpha': '2.0'}</td>\n"," <td>0.77180</td>\n"," <td>0.776557</td>\n"," <td>0.7632</td>\n"," <td>0.769820</td>\n"," <td>0.843168</td>\n"," <td>1.219065</td>\n"," <td>dd8952ca25ed4d1aafc3567e07f3c02d</td>\n"," <td>Modele_Simple_Naive_Bayes_BoW</td>\n"," </tr>\n"," <tr>\n"," <th>13</th>\n"," <td>SVM Lineaire</td>\n"," <td>TF-IDF</td>\n"," <td>{'C': '0.1', 'dual': 'True', 'max_iter': '1000'}</td>\n"," <td>0.78420</td>\n"," <td>0.776513</td>\n"," <td>0.7981</td>\n"," <td>0.787158</td>\n"," <td>0.861249</td>\n"," <td>42.945317</td>\n"," <td>499aa47dec3647668dc9668287f7d738</td>\n"," <td>Modele_Simple_SVM_Lineaire_TF-IDF</td>\n"," </tr>\n"," <tr>\n"," <th>5</th>\n"," <td>SVM Lineaire</td>\n"," <td>TF-IDF</td>\n"," <td>{'C': '0.1', 'dual': 'True', 'max_iter': '1000'}</td>\n"," <td>0.78420</td>\n"," <td>0.776513</td>\n"," <td>0.7981</td>\n"," <td>0.787158</td>\n"," <td>0.861249</td>\n"," <td>35.626043</td>\n"," <td>9a565ac797fd45959b57d95b940d623a</td>\n"," <td>Modele_Simple_SVM_Lineaire_TF-IDF</td>\n"," </tr>\n"," <tr>\n"," <th>10</th>\n"," <td>Random Forest</td>\n"," <td>BoW</td>\n"," <td>{'max_depth': 'None', 'min_samples_split': '5'...</td>\n"," <td>0.76885</td>\n"," <td>0.774589</td>\n"," <td>0.7584</td>\n"," <td>0.766409</td>\n"," <td>0.843950</td>\n"," <td>5883.188167</td>\n"," <td>8c20d78baba443f3ba199d92340868bd</td>\n"," <td>Modele_Simple_Random_Forest_BoW</td>\n"," </tr>\n"," <tr>\n"," <th>2</th>\n"," <td>Random Forest</td>\n"," <td>BoW</td>\n"," <td>{'max_depth': 'None', 'min_samples_split': '5'...</td>\n"," <td>0.76885</td>\n"," <td>0.774589</td>\n"," <td>0.7584</td>\n"," <td>0.766409</td>\n"," <td>0.843950</td>\n"," <td>3671.472166</td>\n"," <td>7be18b5ea5e34e009bdcc4d7075a621a</td>\n"," <td>Modele_Simple_Random_Forest_BoW</td>\n"," </tr>\n"," <tr>\n"," <th>6</th>\n"," <td>Regression Logistique</td>\n"," <td>BoW</td>\n"," <td>{'C': '0.1', 'max_iter': '1000', 'solver': 'sa...</td>\n"," <td>0.77925</td>\n"," <td>0.767199</td>\n"," <td>0.8018</td>\n"," <td>0.784118</td>\n"," <td>0.851395</td>\n"," <td>299.318508</td>\n"," <td>0c89cbaa893440b48fcf00faf65eb8fb</td>\n"," <td>Modele_Simple_Regression_Logistique_BoW</td>\n"," </tr>\n"," <tr>\n"," <th>14</th>\n"," <td>Regression Logistique</td>\n"," <td>BoW</td>\n"," <td>{'C': '0.1', 'max_iter': '1000', 'solver': 'sa...</td>\n"," <td>0.77925</td>\n"," <td>0.767199</td>\n"," <td>0.8018</td>\n"," <td>0.784118</td>\n"," <td>0.851395</td>\n"," <td>332.209190</td>\n"," <td>2c9f95becf5744f38e55f1642928d3e6</td>\n"," <td>Modele_Simple_Regression_Logistique_BoW</td>\n"," </tr>\n"," <tr>\n"," <th>12</th>\n"," <td>SVM Lineaire</td>\n"," <td>BoW</td>\n"," <td>{'C': '0.01', 'dual': 'True', 'max_iter': '1000'}</td>\n"," <td>0.78005</td>\n"," <td>0.765526</td>\n"," <td>0.8074</td>\n"," <td>0.785905</td>\n"," <td>0.851585</td>\n"," <td>154.561330</td>\n"," <td>4e80851a287142a7ae1720ad37a8c502</td>\n"," <td>Modele_Simple_SVM_Lineaire_BoW</td>\n"," </tr>\n"," <tr>\n"," <th>4</th>\n"," <td>SVM Lineaire</td>\n"," <td>BoW</td>\n"," <td>{'C': '0.01', 'dual': 'True', 'max_iter': '1000'}</td>\n"," <td>0.78005</td>\n"," <td>0.765526</td>\n"," <td>0.8074</td>\n"," <td>0.785905</td>\n"," <td>0.851585</td>\n"," <td>132.033319</td>\n"," <td>b2b792fed8eb49089609e93bc0713d45</td>\n"," <td>Modele_Simple_SVM_Lineaire_BoW</td>\n"," </tr>\n"," <tr>\n"," <th>3</th>\n"," <td>Random Forest</td>\n"," <td>TF-IDF</td>\n"," <td>{'max_depth': 'None', 'min_samples_split': '5'...</td>\n"," <td>0.76480</td>\n"," <td>0.763587</td>\n"," <td>0.7671</td>\n"," <td>0.765340</td>\n"," <td>0.841649</td>\n"," <td>3513.826061</td>\n"," <td>d5f040683a304c3297bd939b6ee4fed9</td>\n"," <td>Modele_Simple_Random_Forest_TF-IDF</td>\n"," </tr>\n"," <tr>\n"," <th>11</th>\n"," <td>Random Forest</td>\n"," <td>TF-IDF</td>\n"," <td>{'max_depth': 'None', 'min_samples_split': '5'...</td>\n"," <td>0.76480</td>\n"," <td>0.763587</td>\n"," <td>0.7671</td>\n"," <td>0.765340</td>\n"," <td>0.841649</td>\n"," <td>5611.991874</td>\n"," <td>9d9300d6e5284095a0f25aa34d088c02</td>\n"," <td>Modele_Simple_Random_Forest_TF-IDF</td>\n"," </tr>\n"," </tbody>\n","</table>\n","</div>\n"," <div class=\"colab-df-buttons\">\n","\n"," <div class=\"colab-df-container\">\n"," <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-34eac432-1cd4-43fd-903d-956e517f5a7d')\"\n"," title=\"Convert this dataframe to an interactive table.\"\n"," style=\"display:none;\">\n","\n"," <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n"," <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n"," </svg>\n"," </button>\n","\n"," <style>\n"," .colab-df-container {\n"," display:flex;\n"," gap: 12px;\n"," }\n","\n"," .colab-df-convert {\n"," background-color: #E8F0FE;\n"," border: none;\n"," border-radius: 50%;\n"," cursor: pointer;\n"," display: none;\n"," fill: #1967D2;\n"," height: 32px;\n"," padding: 0 0 0 0;\n"," width: 32px;\n"," }\n","\n"," .colab-df-convert:hover {\n"," background-color: #E2EBFA;\n"," box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n"," fill: #174EA6;\n"," }\n","\n"," .colab-df-buttons div {\n"," margin-bottom: 4px;\n"," }\n","\n"," [theme=dark] .colab-df-convert {\n"," background-color: #3B4455;\n"," fill: #D2E3FC;\n"," }\n","\n"," [theme=dark] .colab-df-convert:hover {\n"," background-color: #434B5C;\n"," box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n"," filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n"," fill: #FFFFFF;\n"," }\n"," </style>\n","\n"," <script>\n"," const buttonEl =\n"," document.querySelector('#df-34eac432-1cd4-43fd-903d-956e517f5a7d button.colab-df-convert');\n"," buttonEl.style.display =\n"," google.colab.kernel.accessAllowed ? 'block' : 'none';\n","\n"," async function convertToInteractive(key) {\n"," const element = document.querySelector('#df-34eac432-1cd4-43fd-903d-956e517f5a7d');\n"," const dataTable =\n"," await google.colab.kernel.invokeFunction('convertToInteractive',\n"," [key], {});\n"," if (!dataTable) return;\n","\n"," const docLinkHtml = 'Like what you see? Visit the ' +\n"," '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n"," + ' to learn more about interactive tables.';\n"," element.innerHTML = '';\n"," dataTable['output_type'] = 'display_data';\n"," await google.colab.output.renderOutput(dataTable, element);\n"," const docLink = document.createElement('div');\n"," docLink.innerHTML = docLinkHtml;\n"," element.appendChild(docLink);\n"," }\n"," </script>\n"," </div>\n","\n","\n"," <div id=\"df-998b5872-77b8-4ce1-8bc8-ffa4c0a9c8f3\">\n"," <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-998b5872-77b8-4ce1-8bc8-ffa4c0a9c8f3')\"\n"," title=\"Suggest charts\"\n"," style=\"display:none;\">\n","\n","<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n"," width=\"24px\">\n"," <g>\n"," <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n"," </g>\n","</svg>\n"," </button>\n","\n","<style>\n"," .colab-df-quickchart {\n"," --bg-color: #E8F0FE;\n"," --fill-color: #1967D2;\n"," --hover-bg-color: #E2EBFA;\n"," --hover-fill-color: #174EA6;\n"," --disabled-fill-color: #AAA;\n"," --disabled-bg-color: #DDD;\n"," }\n","\n"," [theme=dark] .colab-df-quickchart {\n"," --bg-color: #3B4455;\n"," --fill-color: #D2E3FC;\n"," --hover-bg-color: #434B5C;\n"," --hover-fill-color: #FFFFFF;\n"," --disabled-bg-color: #3B4455;\n"," --disabled-fill-color: #666;\n"," }\n","\n"," .colab-df-quickchart {\n"," background-color: var(--bg-color);\n"," border: none;\n"," border-radius: 50%;\n"," cursor: pointer;\n"," display: none;\n"," fill: var(--fill-color);\n"," height: 32px;\n"," padding: 0;\n"," width: 32px;\n"," }\n","\n"," .colab-df-quickchart:hover {\n"," background-color: var(--hover-bg-color);\n"," box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n"," fill: var(--button-hover-fill-color);\n"," }\n","\n"," .colab-df-quickchart-complete:disabled,\n"," .colab-df-quickchart-complete:disabled:hover {\n"," background-color: var(--disabled-bg-color);\n"," fill: var(--disabled-fill-color);\n"," box-shadow: none;\n"," }\n","\n"," .colab-df-spinner {\n"," border: 2px solid var(--fill-color);\n"," border-color: transparent;\n"," border-bottom-color: var(--fill-color);\n"," animation:\n"," spin 1s steps(1) infinite;\n"," }\n","\n"," @keyframes spin {\n"," 0% {\n"," border-color: transparent;\n"," border-bottom-color: var(--fill-color);\n"," border-left-color: var(--fill-color);\n"," }\n"," 20% {\n"," border-color: transparent;\n"," border-left-color: var(--fill-color);\n"," border-top-color: var(--fill-color);\n"," }\n"," 30% {\n"," border-color: transparent;\n"," border-left-color: var(--fill-color);\n"," border-top-color: var(--fill-color);\n"," border-right-color: var(--fill-color);\n"," }\n"," 40% {\n"," border-color: transparent;\n"," border-right-color: var(--fill-color);\n"," border-top-color: var(--fill-color);\n"," }\n"," 60% {\n"," border-color: transparent;\n"," border-right-color: var(--fill-color);\n"," }\n"," 80% {\n"," border-color: transparent;\n"," border-right-color: var(--fill-color);\n"," border-bottom-color: var(--fill-color);\n"," }\n"," 90% {\n"," border-color: transparent;\n"," border-bottom-color: var(--fill-color);\n"," }\n"," }\n","</style>\n","\n"," <script>\n"," async function quickchart(key) {\n"," const quickchartButtonEl =\n"," document.querySelector('#' + key + ' button');\n"," quickchartButtonEl.disabled = true; // To prevent multiple clicks.\n"," quickchartButtonEl.classList.add('colab-df-spinner');\n"," try {\n"," const charts = await google.colab.kernel.invokeFunction(\n"," 'suggestCharts', [key], {});\n"," } catch (error) {\n"," console.error('Error during call to suggestCharts:', error);\n"," }\n"," quickchartButtonEl.classList.remove('colab-df-spinner');\n"," quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n"," }\n"," (() => {\n"," let quickchartButtonEl =\n"," document.querySelector('#df-998b5872-77b8-4ce1-8bc8-ffa4c0a9c8f3 button');\n"," quickchartButtonEl.style.display =\n"," google.colab.kernel.accessAllowed ? 'block' : 'none';\n"," })();\n"," </script>\n"," </div>\n","\n"," <div id=\"id_67e0ff95-cdb2-41e8-8017-d2730241959e\">\n"," <style>\n"," .colab-df-generate {\n"," background-color: #E8F0FE;\n"," border: none;\n"," border-radius: 50%;\n"," cursor: pointer;\n"," display: none;\n"," fill: #1967D2;\n"," height: 32px;\n"," padding: 0 0 0 0;\n"," width: 32px;\n"," }\n","\n"," .colab-df-generate:hover {\n"," background-color: #E2EBFA;\n"," box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n"," fill: #174EA6;\n"," }\n","\n"," [theme=dark] .colab-df-generate {\n"," background-color: #3B4455;\n"," fill: #D2E3FC;\n"," }\n","\n"," [theme=dark] .colab-df-generate:hover {\n"," background-color: #434B5C;\n"," box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n"," filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n"," fill: #FFFFFF;\n"," }\n"," </style>\n"," <button class=\"colab-df-generate\" onclick=\"generateWithVariable('results_df')\"\n"," title=\"Generate code using this dataframe.\"\n"," style=\"display:none;\">\n","\n"," <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n"," width=\"24px\">\n"," <path d=\"M7,19H8.4L18.45,9,17,7.55,7,17.6ZM5,21V16.75L18.45,3.32a2,2,0,0,1,2.83,0l1.4,1.43a1.91,1.91,0,0,1,.58,1.4,1.91,1.91,0,0,1-.58,1.4L9.25,21ZM18.45,9,17,7.55Zm-12,3A5.31,5.31,0,0,0,4.9,8.1,5.31,5.31,0,0,0,1,6.5,5.31,5.31,0,0,0,4.9,4.9,5.31,5.31,0,0,0,6.5,1,5.31,5.31,0,0,0,8.1,4.9,5.31,5.31,0,0,0,12,6.5,5.46,5.46,0,0,0,6.5,12Z\"/>\n"," </svg>\n"," </button>\n"," <script>\n"," (() => {\n"," const buttonEl =\n"," document.querySelector('#id_67e0ff95-cdb2-41e8-8017-d2730241959e button.colab-df-generate');\n"," buttonEl.style.display =\n"," google.colab.kernel.accessAllowed ? 'block' : 'none';\n","\n"," buttonEl.onclick = () => {\n"," google.colab.notebook.generateWithVariable('results_df');\n"," }\n"," })();\n"," </script>\n"," </div>\n","\n"," </div>\n"," </div>\n"],"application/vnd.google.colaboratory.intrinsic+json":{"type":"dataframe","variable_name":"results_df","summary":"{\n \"name\": \"results_df\",\n \"rows\": 16,\n \"fields\": [\n {\n \"column\": \"Mod\\u00e8le\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 4,\n \"samples\": [\n \"Regression Logistique\",\n \"Random Forest\",\n \"Naive Bayes\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Vectorisation\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 2,\n \"samples\": [\n \"BoW\",\n \"TF-IDF\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Meilleurs param\\u00e8tres\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 6,\n \"samples\": [\n \"{'alpha': '2.0'}\",\n \"{'C': '1.0', 'max_iter': '1000', 'solver': 'saga'}\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Accuracy\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.006996272817245854,\n \"min\": 0.7648,\n \"max\": 0.7842,\n \"num_unique_values\": 8,\n \"samples\": [\n 0.78315,\n 0.77925\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Precision\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.005605282505618488,\n \"min\": 0.7635874975114474,\n \"max\": 0.7776180698151951,\n \"num_unique_values\": 8,\n \"samples\": [\n 0.7765947054801211,\n 0.7671993110707109\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Recall\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.020642222102606442,\n \"min\": 0.7574,\n \"max\": 0.8074,\n \"num_unique_values\": 8,\n \"samples\": [\n 0.795,\n 0.8018\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"F1 Score\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.009652587223973512,\n \"min\": 0.7653397186471116,\n \"max\": 0.7871584968931847,\n \"num_unique_values\": 8,\n \"samples\": [\n 0.7856895784948362,\n 0.7841181360324678\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"ROC AUC\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.007348370075287755,\n \"min\": 0.8416485,\n \"max\": 0.861248845,\n \"num_unique_values\": 8,\n \"samples\": [\n 0.861097975,\n 0.85139523\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Temps d'entra\\u00eenement (s)\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 2126.188848811458,\n \"min\": 1.0161237716674805,\n \"max\": 5883.188166618347,\n \"num_unique_values\": 16,\n \"samples\": [\n 2.7770001888275146,\n 3.5678818225860596\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Run ID\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 16,\n \"samples\": [\n \"64430125306243afab3cfa643aac487e\",\n \"9f6ccc9a4b3e415695e2c05fa85d2bdb\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Run Name\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 8,\n \"samples\": [\n \"Modele_Simple_Regression_Logistique_TF-IDF\",\n \"Modele_Simple_Regression_Logistique_BoW\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}"}},"metadata":{},"execution_count":28}],"source":["results_df"]},{"cell_type":"code","execution_count":29,"metadata":{"id":"w0WL6NSxWxlQ","executionInfo":{"status":"ok","timestamp":1751526850863,"user_tz":-120,"elapsed":2,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"outputs":[],"source":["def afficher_tableau_comparatif(df):\n"," \"\"\"\n"," Affiche un tableau comparatif formaté des résultats\n","\n"," Parameters:\n"," -----------\n"," df : pandas.DataFrame\n"," Dataframe contenant les résultats à afficher\n"," \"\"\"\n"," if df.empty:\n"," print(\"Aucun résultat à afficher.\")\n"," return\n","\n"," # Sélectionner et formater les colonnes pour l'affichage\n"," df_display = df[[\"Modèle\", \"Vectorisation\", \"Accuracy\", \"Precision\", \"Recall\",\n"," \"F1 Score\", \"ROC AUC\", \"Temps d'entraînement (s)\"]]\n","\n"," # Formater les valeurs numériques\n"," for col in [\"Accuracy\", \"Precision\", \"Recall\", \"F1 Score\", \"ROC AUC\"]:\n"," if col in df_display.columns:\n"," df_display[col] = df_display[col].apply(lambda x: f\"{x:.4f}\" if x is not None else \"N/A\")\n","\n"," if \"Temps d'entraînement (s)\" in df_display.columns:\n"," df_display[\"Temps d'entraînement (s)\"] = df_display[\"Temps d'entraînement (s)\"].apply(\n"," lambda x: f\"{x:.2f}\" if x is not None else \"N/A\")\n","\n"," # Afficher le tableau\n"," print(\"\\n=== Comparaison des modèles ===\\n\")\n"," print(df_display.to_string(index=False))\n","\n"," # Identifier le meilleur modèle selon la précision\n"," if \"Precision\" in df.columns:\n"," best_idx = df[\"Precision\"].idxmax() if not df.empty else None\n"," if best_idx is not None:\n"," best_model = df.loc[best_idx]\n"," print(\"\\n=== Meilleur modèle ===\")\n"," print(f\"Modèle: {best_model['Modèle']}\")\n"," print(f\"Vectorisation: {best_model['Vectorisation']}\")\n"," print(f\"Precision: {best_model['Precision']:.4f}\")\n"," print(f\"Meilleurs paramètres: {best_model['Meilleurs paramètres']}\")"]},{"cell_type":"code","execution_count":30,"metadata":{"id":"Ou07_WmDWxlQ","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1751526850873,"user_tz":-120,"elapsed":8,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"519c63c8-8606-47aa-aa37-eb5fd3715762"},"outputs":[{"output_type":"stream","name":"stdout","text":["\n","=== Comparaison des modèles ===\n","\n"," Modèle Vectorisation Accuracy Precision Recall F1 Score ROC AUC Temps d'entraînement (s)\n"," Naive Bayes TF-IDF 0.7704 0.7776 0.7574 0.7674 0.8511 2.78\n"," Naive Bayes TF-IDF 0.7704 0.7776 0.7574 0.7674 0.8511 3.57\n","Regression Logistique TF-IDF 0.7832 0.7766 0.7950 0.7857 0.8611 33.86\n","Regression Logistique TF-IDF 0.7832 0.7766 0.7950 0.7857 0.8611 26.42\n"," Naive Bayes BoW 0.7718 0.7766 0.7632 0.7698 0.8432 1.02\n"," Naive Bayes BoW 0.7718 0.7766 0.7632 0.7698 0.8432 1.22\n"," SVM Lineaire TF-IDF 0.7842 0.7765 0.7981 0.7872 0.8612 42.95\n"," SVM Lineaire TF-IDF 0.7842 0.7765 0.7981 0.7872 0.8612 35.63\n"," Random Forest BoW 0.7689 0.7746 0.7584 0.7664 0.8439 5883.19\n"," Random Forest BoW 0.7689 0.7746 0.7584 0.7664 0.8439 3671.47\n","Regression Logistique BoW 0.7792 0.7672 0.8018 0.7841 0.8514 299.32\n","Regression Logistique BoW 0.7792 0.7672 0.8018 0.7841 0.8514 332.21\n"," SVM Lineaire BoW 0.7801 0.7655 0.8074 0.7859 0.8516 154.56\n"," SVM Lineaire BoW 0.7801 0.7655 0.8074 0.7859 0.8516 132.03\n"," Random Forest TF-IDF 0.7648 0.7636 0.7671 0.7653 0.8416 3513.83\n"," Random Forest TF-IDF 0.7648 0.7636 0.7671 0.7653 0.8416 5611.99\n","\n","=== Meilleur modèle ===\n","Modèle: Naive Bayes\n","Vectorisation: TF-IDF\n","Precision: 0.7776\n","Meilleurs paramètres: {'alpha': '2.0'}\n"]}],"source":["# Afficher le tableau comparatif\n","afficher_tableau_comparatif(results_df)"]},{"cell_type":"code","execution_count":31,"metadata":{"id":"etUvFhueWxlQ","executionInfo":{"status":"ok","timestamp":1751526850884,"user_tz":-120,"elapsed":9,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"outputs":[],"source":["def display_metrics_subplot(df, figsize=(18, 14)):\n"," \"\"\"\n"," Génère des sous-graphiques pour visualiser toutes les métriques avec une échelle fixe (0,1)\n","\n"," Parameters:\n"," -----------\n"," df : pandas.DataFrame\n"," DataFrame contenant les résultats des modèles avec leurs métriques\n"," figsize : tuple, optional\n"," Taille de la figure (largeur, hauteur)\n"," Returns:\n"," --------\n"," matplotlib.figure.Figure\n"," La figure générée\n"," \"\"\"\n"," # Définir les métriques à visualiser\n"," metriques = [\"Accuracy\", \"Precision\", \"Recall\", \"F1 Score\", \"ROC AUC\"]\n","\n"," # Créer une figure avec des sous-graphiques\n"," fig, axes = plt.subplots(3, 2, figsize=figsize)\n"," axes = axes.flatten()\n","\n"," # Définir une palette de couleurs cohérente\n"," palette = sns.color_palette(\"Set2\", len(df[\"Vectorisation\"].unique()))\n","\n"," # Créer un barplot pour chaque métrique\n"," for i, metrique in enumerate(metriques):\n"," ax = axes[i]\n","\n"," # Créer le barplot\n"," sns.barplot(\n"," x=\"Modèle\",\n"," y=metrique,\n"," hue=\"Vectorisation\",\n"," data=df,\n"," ax=ax,\n"," palette=palette\n"," )\n","\n"," # Configurer l'axe y pour qu'il aille de 0 à 1\n"," ax.set_ylim(0, 1)\n","\n"," # Ajouter une grille horizontale pour faciliter la lecture\n"," ax.grid(axis='y', linestyle='--', alpha=0.7)\n","\n"," # Définir le titre du sous-graphique\n"," ax.set_title(f\"{metrique}\", fontsize=14, fontweight='bold')\n","\n"," # Rotation des étiquettes de l'axe x pour éviter le chevauchement\n"," ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha='right')\n","\n"," # Ajouter des valeurs au-dessus des barres\n"," for p in ax.patches:\n"," height = p.get_height()\n"," ax.text(\n"," p.get_x() + p.get_width()/2.,\n"," height + 0.01,\n"," f'{height:.3f}',\n"," ha=\"center\", fontsize=9\n"," )\n","\n"," # Ne garder la légende que sur le premier graphique\n"," # if i != 0:\n"," # ax.get_legend().remove()\n","\n"," # Ajuster la disposition pour éviter le chevauchement\n"," plt.tight_layout()\n","\n"," # Ajouter un titre global\n"," fig.suptitle(\"Comparaison des performances des modèles par métrique\",\n"," fontsize=18, fontweight='bold', y=1.02)\n","\n"," # Afficher la figure (si dans un notebook)\n"," plt.show()"]},{"cell_type":"code","source":["def display_metrics_subplot(df, figsize=(18, 14)):\n"," \"\"\"\n"," Génère des sous-graphiques pour visualiser toutes les métriques.\n"," Le graphique de Précision occupe 2 colonnes.\n","\n"," Parameters:\n"," -----------\n"," df : pandas.DataFrame\n"," DataFrame contenant les résultats des modèles avec leurs métriques\n"," figsize : tuple, optional\n"," Taille de la figure (largeur, hauteur)\n"," Returns:\n"," --------\n"," matplotlib.figure.Figure\n"," La figure générée\n"," \"\"\"\n"," if df.empty:\n"," print(\"Aucun résultat à afficher.\")\n"," return None # Retourne None si le dataframe est vide\n","\n"," # Définir les métriques à visualiser (sans la Précision initiale)\n"," other_metriques = [\"Accuracy\", \"Recall\", \"F1 Score\", \"ROC AUC\"]\n","\n"," # Créer une figure et une grille de sous-graphiques (3 lignes, 2 colonnes)\n"," fig = plt.figure(figsize=figsize)\n"," gs = fig.add_gridspec(3, 2)\n","\n"," # Définir les axes pour la Précision (span 2 colonnes)\n"," ax_precision = fig.add_subplot(gs[0, :]) # La Précision occupe la première ligne, les deux colonnes\n","\n"," # Définir les axes pour les autres métriques (remplir les 2 lignes restantes)\n"," axes_other = [fig.add_subplot(gs[1, 0]), fig.add_subplot(gs[1, 1]),\n"," fig.add_subplot(gs[2, 0]), fig.add_subplot(gs[2, 1])]\n","\n"," # Définir une palette de couleurs cohérente\n"," palette = sns.color_palette(\"Set2\", len(df[\"Vectorisation\"].unique()))\n","\n"," # Fonction utilitaire pour ajouter les valeurs au-dessus des barres\n"," def add_value_labels(ax):\n"," for p in ax.patches:\n"," height = p.get_height()\n"," if height > 0: # N'affiche le label que si la hauteur est > 0\n"," ax.text(\n"," p.get_x() + p.get_width()/2.,\n"," height + 0.01,\n"," f'{height:.3f}',\n"," ha=\"center\", fontsize=9\n"," )\n","\n","\n"," # Tracer le graphique de Précision\n"," sns.barplot(\n"," x=\"Modèle\",\n"," y=\"Precision\",\n"," hue=\"Vectorisation\",\n"," data=df,\n"," ax=ax_precision,\n"," palette=palette\n"," )\n"," ax_precision.set_ylim(0, 1)\n"," ax_precision.grid(axis='y', linestyle='--', alpha=0.7)\n"," ax_precision.set_title(\"Precision (Métriques clé)\", fontsize=14, fontweight='bold')\n"," ax_precision.set_xticklabels(ax_precision.get_xticklabels(), rotation=45, ha='right')\n"," ax_precision.set_xlabel(\"\") # Masquer l'étiquette x pour la Précision si désiré\n"," add_value_labels(ax_precision) # Ajouter les valeurs\n","\n","\n"," # Tracer les graphiques pour les autres métriques\n"," for i, metrique in enumerate(other_metriques):\n"," ax = axes_other[i]\n","\n"," sns.barplot(\n"," x=\"Modèle\",\n"," y=metrique,\n"," hue=\"Vectorisation\",\n"," data=df,\n"," ax=ax,\n"," palette=palette\n"," )\n","\n"," ax.set_ylim(0, 1)\n"," ax.grid(axis='y', linestyle='--', alpha=0.7)\n"," ax.set_title(f\"{metrique}\", fontsize=14, fontweight='bold')\n"," ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha='right')\n"," add_value_labels(ax) # Ajouter les valeurs\n","\n"," # Ne garder la légende que sur l'un des graphiques (par exemple, le premier des autres)\n"," if i != 0:\n"," ax.get_legend().remove()\n"," else:\n"," # Placer la légende de la précision à un endroit approprié si on ne veut pas de légendes répétées\n"," # ax_precision.legend(loc='upper right') # Exemple de placement\n","\n"," # Ou retirer la légende de la précision si on la garde sur le premier des autres\n"," ax_precision.get_legend().remove() # Retirer la légende de la précision\n","\n"," # Ajuster la disposition pour éviter le chevauchement\n"," plt.tight_layout()\n","\n"," # Ajouter un titre global\n"," fig.suptitle(\"Comparaison des performances des modèles\",\n"," fontsize=18, fontweight='bold', y=1.02) # Ajuster y si nécessaire\n","\n"," # Afficher la figure (si dans un notebook)\n"," plt.show()"],"metadata":{"id":"lv_FsbT_OlC1","executionInfo":{"status":"ok","timestamp":1751526850893,"user_tz":-120,"elapsed":7,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"execution_count":32,"outputs":[]},{"cell_type":"code","execution_count":33,"metadata":{"id":"Noe09nRHWxlQ","colab":{"base_uri":"https://localhost:8080/","height":572},"executionInfo":{"status":"ok","timestamp":1751526852502,"user_tz":-120,"elapsed":1608,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"cf53cd1b-3d6c-4b69-c78b-0d33423f93d2"},"outputs":[{"output_type":"display_data","data":{"text/plain":["<Figure size 1800x1400 with 5 Axes>"],"image/png":"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20hJScnW9Sf9cbH1/n3yySdzFEv61yU776OzZ8+aS5cunaP9pL22Hzp06I7fIwAAAPcipvcEAACQ1KhRIx04cEDdu3c3phrMiq+vr8VypUqVFBISomrVqmXZNiAgQBs2bCg0o/yk2897SjuaKb1XXnnF6hv+06dPz/Q5dG+//Xaej17r2bOnnnzyyQzX161b12KUXX5zc3PTggUL5OnpaZQVL17cGN2VFV9fX61cudJqCry7qV27dvrss88yPPdLly6tqVOnZrmdhg0basOGDapYsWK29uvq6mo1cjO72rRpYzUi5k7Mnj3basq9tCZNmmSMbk3l4uKi4OBgPfHEE9nez3333XfHMd6JyZMna9y4cdl6ftuwYcNyPG1fQSqI605GnJ2dtWLFCj377LM5buvj46NNmzapTZs22apvMpnk5+eX4/1Ikr+/v77++usct5s9e3am07527949W++DDz/8UBMnTpSTU/YmG7rTfjo6Omr69OlW064WFq6urlq1apUeeeSRLOsWLVpU8+bN09NPP21RbjKZtGTJkkz/fhgyZIiaN2+e5T7mzZunoUOHZvvvnju5jgUEBGjLli2qV69etuo7Ojre8fNt69atazU6FQAA4F7D9J4AAAD/X9myZbV8+XIdP35cixYt0vbt23XixAlFREQoISFB3t7eqly5spo2bapu3brZTNLUqlVLBw8e1JIlS/Tzzz8rNDRUYWFhMpvNKlGihBo0aKBHH31Uffv2VZEiRe5+JzPh7e2tHTt2aNq0aVq4cKFOnTolJycnNWjQQEOHDlXPnj2t2lSsWFH79u3TxIkTFRwcrEuXLsnLy0sNGjTQsGHD1LlzZ/Xr1y9P4zSZTPrhhx/Upk0bff311zpy5IhMJpMqVqyoJ554QqNGjdLvv/+e6/0sWbJEW7du1Y4dO3Tw4EFduXJFYWFhSkpKkpeXlwIDA9WmTRu99NJLNj8Ive+++7R9+3YFBwdr8eLF+uOPP3TlyhUlJiaqePHiql27tjp37qwBAwZYJAwLyrBhw9SoUSNNmjRJO3fu1M2bN+Xn56euXbtq3LhxOnLkSLa207RpUx07dkxLlizRL7/8oj179igsLEwJCQny9PRUxYoVVa9ePbVp00ZdunSRl5eX0bZdu3basGGDtm/frl27dunvv/9WWFiYIiIi5OrqqnLlyql+/frq3bu3HnvssWx/UJ2ZChUqaP/+/Zo0aZKWLVum8+fPq2jRomratKlef/31DJOxnp6eWrx4sV577TV999132rFjh86fP6/o6GgVKVJEZcuWVY0aNdSiRQt16dJF1atXz3WsOeHg4KCJEyfqueee05dffqnNmzfrzJkzio6ONp6n1rJlS7344ouqVavWXY0ttwriupMZDw8PzZs3TyNGjNDcuXO1fft2nT17VtHR0fLy8lLZsmX14IMPqnv37lZty5Ytq40bN2rDhg364Ycf9Pvvv+vixYuKiYmRu7u7ypcvr1q1aqlly5Z65JFH5O/vb7R1d3fXn3/+qR07dmjHjh06efKkwsLCFB4eLgcHB/n6+qpmzZrq0qWLBgwYkKOpPdP2bePGjZo1a5bmzZun48ePy9nZWTVr1tSAAQPUv39/i2k4M2IymTRu3Dg9++yzmjNnjjZt2qQTJ04oMjJSjo6O8vX1VdWqVdWkSRN17NjR6nlz06dPV8+ePbVjxw7t3bvXuB7funVLxYoVU6VKldSyZUsNHDjwrr/XcsrHx0crV65USEiIFixYoJ07d+rSpUuKi4uTt7e3qlevrvbt2+ull15SqVKlbG6jTJky2r17tyZPnqwlS5bozJkzKlq0qOrXr68hQ4aoR48e2foiiYuLi6ZPn65Bgwbpm2++0bZt2/TXX3/pxo0bcnFxUalSpVS9enU1a9ZMnTp1yvSLQZmpWrWqQkNDtXLlSi1btkx//vmnLl++rLi4OBUrVkwVKlRQnTp1FBQUpEceecSi39WqVdO2bdu0Y8cO7dy5U2fOnNHVq1d1/fp1OTs7q1SpUqpbt666d++uvn37Gs8CBAAAuFeZzOZ0T60HAADAPSF9wmTu3Ll39YNy4G47d+6c1SjEkJCQAh1lCQAAAABAXmF6TwAAAAAAAAAAAMDOkfQDAAAAAAAAAAAA7BxJPwAAAAAAAAAAAMDOkfQDAAAAAAAAAAAA7JzJbDabCzoIAAAAAAAAAAAAAHeOkX4AAAAAAAAAAACAnSPpBwAAAAAAAAAAANg5kn4AAAAAAAAAAACAnSPpBwAAAAAAAAAAANg5kn4AAAAAAAAAAACAnSPpBwAAAAAAAAAAANg5kn4AAAAAAAAAAACAnSPpBwAAAAAAAAAAANg5kn4AAAAAAAAAAACAnSPpBwAAAAAAAAAAANg5kn4AAAAAAAAAAACAnSPpBwAAAAAAAAAAANg5kn4AAAAAAAAAAACAnSPpBwAAAAAAAAAAANg5kn4AAAAAAAAAAACAnSPpBwAAAAAAAAAAANg5kn4AAAAAgLsiJCRETk5OcnR01HfffVfQ4SAP9O/fXyaTSZUqVdL58+cLOhwAAADgnkbSDwAAAMA9qV+/fjKZTDKZTAoKCrrj7UyYMMHYTkBAQJ7Flx+OHDkiR0dHmUwmdenS5a7u+9KlS3rqqadkNpv13XffqV+/fvm2r3PnzhnHxGQyafPmzfm2r/+SnJ7L33zzjebOnav7779fW7Zskb+/v8X6H3/80djemDFj8ilqAAAAAKlI+gEAAADIsc2bN1skVdL+eHh4qEaNGho6dKjOnDlT0KEijbFjxyolJUWS9MYbb1isCwoKsjqWe/futbmdBx980KruuXPnMtxvUlKSnnjiCYWHh2vBggV65plnbNZLG0N+JgWRe/v379eQIUNUuXJlbd68Wffdd59VnZ49e+r++++XJE2fPl2XLl2622ECAAAA9xSngg4AAAAAwH9LTEyMjh07pmPHjunbb7/VL7/8onbt2hV0WFaefPJJ1apVS5JsJiyyq0OHDvLw8JAkeXl55Uls+WHPnj1auXKlJKlu3bpq1apVlm2mT59uNQ3n7t279fvvv+do38eOHVPbtm315ptvqnPnzjlqeyeKFy+uyZMnG8upiSfknUOHDmnMmDEaOHCgypUrZ7OOo6OjBg8erJEjRyouLk4fffSRpk+ffpcjBQAAAO4dJP0AAAAA5NoTTzyhRo0aKSEhQbt27dKqVaskSbGxsXrmmWd07tw5ubq6ZrmdGzduyNPTM7/DlSR16tRJnTp1yvV2mjVrpmbNmuVBRPnryy+/NH5/8skns9Vm8eLFmjx5skqWLGmUTZs2Lcf7rl27tmrXrp3jdjmVkJAgs9ksT09PjRo1Kt/3dy/LaLRmer1799Zrr70ms9msBQsWaNKkSXJzc8vn6AAAAIB7E9N7AgAAAMi1Tp06adSoURo7dqyCg4P19NNPG+suX76sHTt2SLKeFvSvv/7SJ598ourVq8vV1VXPPvus0S4lJUULFixQhw4dVKpUKbm4uKhkyZLq0qWL1qxZk2Esx48f1+DBg1WjRg15eHioaNGiqlSpkp588kmFhoYa9TJ7pt+hQ4fUt29fBQQEyNXVVW5ubqpQoYLatGmjN998UxcvXjTqZvUctIiICL377rtq1KiRvLy85OLiovLly6tnz5767bffrOp/9913Fq9RfHy83n//fVWpUkWurq7y8/PTqFGjFB8fn+VxSRUXF6fFixcby4899lim9R0cbv+rGB8fb5EsvHz5spYuXSrp9iiurAQHB+vRRx9V2bJl5eLiIm9vb7Vq1UrffPONMc2o9H+v4ZYtW4yyefPm2Zw+NP0UoIcPH1b37t1VokQJubq66tixY1k+0y88PFwvvfSSSpcuLTc3NzVq1Eg//vij1fmZdsrSzKYeTX/M0ouPj9fMmTPVsmVLFS9eXC4uLipbtqx69eqlXbt22XztvvvuOwUFBcnX11fOzs7y8fFR1apV9cQTT+jzzz/P8rVP68KFCxo9erTq168vT09PFSlSRBUqVFD37t1tnoMZuXHjhj788EM1adLEOJfvu+8+Pf3009qzZ4/NNuXLl9eDDz4oSYqMjNTPP/+co9gBAAAAZB8j/QAAAADkuQcffFALFy40li9fvmyzXv/+/bVt2zar8ri4OHXr1k0bNmywKA8PD9eaNWu0Zs0ajRw5UlOmTLFY/8033+iVV15RQkKCRfnZs2d19uxZNW3aVI0aNco09qNHj6pp06aKjY21KP/nn3/0zz//KCQkRK1atVL58uUz3Y50e1rLDh066MKFCxblly5d0vLly7V8+XINGzZMU6dOzXAb7dq10/bt243lixcvasqUKbp69armz5+fZQyS9Pvvvys6OlqSVLJkSQUGBmZav06dOoqIiND58+f1xRdfaMyYMXJyctLs2bOVmJgoSerWrZuWL19us31KSor69eunBQsWWJRHRUVp69at2rp1q5YsWaLg4OBsjQDNyMGDB9W0aVPFxMRku01ERISaN2+ukydPGmV79uxR79699cgjj9xxLBkJCwtThw4dtH//fovyy5cva9myZfr555/16aefatiwYca6CRMm6J133rGoHxkZqcjISJ08eVJbtmzRK6+8kq39r1mzRk8++aRx/FOlns8BAQFq3759lts5deqUOnToYPXsxgsXLuiHH37QkiVL9Pnnn+vFF1+0avvggw9q586dkqTffvvN4ksBAAAAAPIOST8AAAAAeS796KUyZcrYrLdt2zbVrFlTjzzyiMxmszF6bMSIEUbCz8XFRU8++aQCAwN16NAh/fjj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kZGRunTpktavX6+QkBA1adJEN2/e1IkTJxQdHa369esbc85ygwoAILtcvXpVBQoUMB4fO3ZMCxculNls1nPPPScfHx+lpKRo586dWrhwofLly6e33norww2VAADktP3792vlypW6efOmevTooWPHjmnevHl69dVXVbVqVWO7lJQUXblyRRaLRfny5WP6BOABxm3TgAOzWCxycnJS69atZbFYtHnzZl29elWjRo2Sv7+/kpKS5OrqqoCAABUvXpwLpgCAHBMeHq6jR4/q8ccfN5a5uLjo8uXLOnbsmHx9fbV8+XJdvnxZefLk0YYNG5SUlKQnnngiXePUdq4DACA7rF+/XvPnz9cXX3xhnG+OHTum8+fPKykpST4+PpIkZ2dnhYaGSpKWLl2qESNGaPjw4cb86QAA2EPFihVlNpu1bNkyjRs3TlevXtWwYcMUEhKSrie7k5OTChcubOfSAsgJTIoCODCz2WxcDG3Xrp0aNmyookWLavXq1YqNjZWrq6ssFovWrFmjAgUKqFChQvYuMgDgIREWFqbXXntNZrNZf/31ly5cuKC8efOqffv22rRpk0aNGqWCBQuqe/fuGj58uBo2bKjTp09n2A9z+AEAslPp0qX1wQcfyNXVVQkJCXJyclKDBg3UqlUrpaam6ptvvjG2tQV/jz/+uFxdXRUdHW3HkgMAHna2UK98+fJq27atChcurMDAQCUmJkqSMaf67T8DeLAxvCfwALBYLMbwZ0uWLNHOnTv1yCOPqFu3bvruu+904cIFjR07Vs7Ozsa2AABkF9u5xmq16tixY/r6669VvXp1tW/fXvnz51dkZKTi4+ONIactFotGjRqlcuXKqUuXLnYuPQDgYXT69GmNHDlSgwcPVrly5RQXF6eNGzdq7dq1CgoK0ksvvWRsm5KSouTkZLm7u9uxxAAAyJiLVpIOHTqkpUuXKj4+Xm3btlW1atUybAPgwUfoBzwg0gZ/S5cu1Z9//qm///5bvr6++vzzz+Xs7MycSACAbJdZg3Lx4sX6448/VKZMGT3++OMKCAiQJCUkJOjvv//WggULFBkZqY8//pjzFADALs6dO6cZM2bo5MmTeuONNxQSEqKbN28awV+pUqX0wgsv2LuYAABkkLYNdvDgQS1btkxJSUlq0aKFatasaefSAchpdPcBHIDFYvnXdWmH+mzTpo0qVqyoqlWr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LVS3bl1dvnxZU6dOVWxsrDZt2qRBgwZp/PjxkqQbN25kCPyaNGmiunXrKiYmRps3b05XBrPZrHLlyqlWrVoKCAiQj4+PEhIStHv3bi1dulRWq1WTJ0/Wiy++qFq1amXXrwIA8BAg9AMAOIyLFy9q1apVxuPu3bsb/9tCv127dmnfvn3GnA1jx441Aj+z2ay1a9eqfv36xj6SkpKMkO369etGI06SqlWrpo0bN8rT09NYdvbs2XR3d2aFkiVLateuXfLx8Um3vGXLlmrZsqWOHj2q3bt368qVK3JxcdETTzyhbdu2KS4uTikpKVq7dq0Ryn388cfG8/Pmzatdu3alGwL15s2bunnzpiTJ19dXPXr00E8//SRJmjBhghH6zZ0713jO448/roCAgCytMwAAAABkp6effjrDiCUeHh4aMWKE0e6RpE8//dT4uXfv3po6darxuGHDhkZAOHnyZH388cfy8/PTlClT0gV+o0ePzjBlwsmTJ42fy5cvr4MHD+rMmTPasWOHLl26JBcXF9WvX19//vmnzp8/L0n67bffCP0AAP8JoR8AwGFMnz5dqampkiSTyWQMldK+fXvlyZNHCQkJkm41xr744gtJSneHZYsWLdIFfpLk6uqqwMBASbd6BaakpBjrhgwZki7wk271/MtqAwYMyBD4Sbfm/uvRo4fCw8P/8fnnzp2TJMXFxWn37t3G8t69e6cL/KRbQWDa0PKVV14xQr9ff/1VFy5cUJEiRTR//nxjG4b2BAAAAPAg6NChg1588UXjcVxcnPbs2WM8njZtmqZNm5bpc1NSUrR9+3a1bNkyXTszX758evvttzNsHxwcbPx87do19enTJ8M0Erezte0AALhfZnsXAACAu5V2aM+wsDAjgMuXL59atWplrJsxY4YR3qUdwqVkyZL/uP+0297N9re7fQ69xMTEu3pe2bJlM13evn37fw380r7O9evX05XhbspfqVIlNWrUSJKUmpqqyZMna9u2bcbQngULFlTr1q3/dT8AAAAAkJt07dpVY8aMSdeemTFjhtq1a2e0m25vQ/2bK1euSErfdixWrFi6udEz8+yzz/5r4CfdfRsSAIA7oacfAMAhbNu2TYcOHTIeb9myRSaTKdNtIyIi9Ouvv6pt27by8/Mzhu88derUP76Gn59fusenTp1SzZo177i92Zz+3pn4+HjjZ4vFohMnTvzj69lkNlzokSNH9NdffxmPn3rqKX366acqUqSITCaT/P39jQanja+vr0wmk9Fo/bf62rzyyitav369JGnSpEm6du2asa5nz55ycXG5q/0AAAAAQG7RsmVL9e3bV5L04osv6n//+58kae3atfr555/Vq1evDCOutG3bNsPoMGlVr15dUvq249mzZ5WamnrH4O/mzZvp5oZ/7LHHNH78eJUoUUJOTk6qVauWduzYcT9VBAAgA3r6AQAcQtpefveyfb169Yxlq1at0pYtW9Jtl5KSYsyfULt2bTk7/9/9MJ988oni4uLSbX/hwgUlJydLUoYG4tatW42ff/rppwyh3L1IG7xJUqdOnVS0aFGZTCatX78+0317eHioWrVqxuPp06fr+PHj6baJj483QlCbdu3aqXjx4pJuzTvxww8/GOueeeaZ+64DAAAAAOQGH3/8sby9vY3HI0eOVGpqqvLmzauqVasay69du6bXXntNb775Zrp/zz//vAIDA1WhQgVJ6duZN27c0NixYzO8pm30lOjoaGOaCklq1aqVgoOD5eTkpCNHjmjv3r1ZXV0AwEOMnn4AgFwvISFBs2fPNh6XLFky08nN9+3bp4MHD0qSli1bpqtXr2rw4MFatGiRLBaLUlNT1bhxY3Xp0kVlypTRpUuX9Ntvv+nll1/WwIED5evrq379+un777+XJO3atUvly5dX+/bt5ePjo6NHj2rhwoW6ePGifHx85OXlpZCQEB09elTSrcnbd+/erfj4eK1du/Y/1blUqVIym82yWCySpNdee0179uzRtWvXNHny5Ds+b8iQIcZE87Gxsapataq6deumEiVK6OzZs1q2bJm+//57tW/f3niOk5OT+vfvr3feeUeSjLkRQ0NDVbFixf9UDwAAAACwNx8fHw0YMEBjxoyRJB0/flxz5szRU089pcGDB6tHjx6Sbo0oU7lyZbVp00a+vr66du2adu/erc2bN6tw4cLq1q2bJKlv374aPXq0Ll++LEl65513tGbNGtWpU0dxcXHaunWrChQooEWLFsnf318+Pj6KioqSJH344YeKiIhQSkqKJk2axJCeAIAsRegHAMj1Fi1aZDSQJGnUqFFGoyyttWvX6rHHHpMkJScna8aMGXrttdc0fvx4vfTSS0pKSjKW38nnn3+u06dP69dff5V06+7Mr7/++o7bv/XW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rl27dP/99yskJEQmk0kuLi6qWLGisrOzNWTIECZwBwAAAAA7RuYDAACwT3T6AShWl8/nkJGRIXd3d2VnZ6tu3bratWuXPv74Y917773q0qWLsrOztWHDBgUHB6tVq1Zq1aqVdR+EPwAAAACwP2Q+AAAA+0WnH4Bic/l8Dt98840uXryoZ599VhaLRZMmTdLp06c1YsQIderUSZKUmJioLVu2yMXFRTVr1rTuhwncAQAAAMD+kPkAAADsG2dZAIpN7nwO8fHxOnXqlHr37i13d3eNGDFCaWlpqlixojp16iSTyaS0tDT973//k9ls1h133GHjygEAAAAA/4bMBwAAYN8MFovFYusiANw+lixZot9//10+Pj56/PHH5erqqqysLEVEROj7779XUFCQPD09ZTKZlJmZqXfffVfOzs55hogBAAAAANgnMh8AAID9YnhPADfk8uCWmZkpk8mkEydOqFSpUnJ1dZUkubq66s4771SdOnW0evVqubi4KCAgQJ07d5bRaGQCdwAAAACwU2Q+AACAkoM7/QAUi8zMTLm5uSkhIUHbtm3Tjz/+qLvuukv33nuvJF0z5HG1JwAAAADYPzIfAACA/eOsC0CRmM1m639HRETo8ccfV2Jiovz9/dWmTRvde++9Wr16tWbOnClJcnJyUk5OjnKvM8j9N+EPAAAAAOwPmQ8AAKDk4cwLQKFdfqVmRESEzp07p5SUFL3//vtKSEiQr6+v7rjjDoWHh2vVqlWaNWuWpEshMHfi99x/AwAAAADsC5kPAACgZKLTD0Ch5Ya/X375Rb/88osMBoM6deqklJQUjR071hoC27VrpyFDhmjevHlavXq1jasGAAAAABQEmQ8AAKBkYk4/AEXy999/65133tFjjz2mpk2bSpJiYmI0ZcoUpaWlady4cfL391dCQoIOHDigFi1aMHE7AAAAAJQQZD4AAICShzv9ABRJenq60tLSFBQUZF1WtWpVPfDAA7p48aImTJig5ORk+fv7W8NfTk6ODSsGAAAAABQUmQ8AAKDkodMPwL/K74bg4OBglSlTRhs3brQuMxqNqlKliipXrqwzZ85ozJgxMplM1qs9ueoTAAAAAOwPmQ8AAOD2QKcfgOsym83WCdhTUlKUkJCg7Oxsubq6qkWLFtq7d69WrVpl3d5gMKhMmTJ66qmn5OTkpAULFtiocgAAAADA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n3/+WQ888IDNs8olqXr16sbfp0+fLnCfp06dyne7mjVr2pQfPny42O3O7dy5c1q+fLmxnPuZgp07d7Z5ll7u5KAkmzguLS0tz75TU1Ntlj09PY2/c/fn6NGjeY4XAODmRdIPAIAbVK5cOXXs2FFvvvmmVq9erffff99mfc5z9XKmz8xx4sSJa+43d/2LFy/mWZ+7rGLFivnuo6DnUOTed/Xq1TV27NgC/3v22Wev2U4AAAAAsLdu3brprbfe0sKFCzVo0CCjfNWqVfrpp59s6t5+++3G37GxsVq1alW++5w1a1a+27Vq1crmmeyzZs1SSkrKDffhxx9/VHZ2trE8evRoY4YVd3d345ELkrR48WJdunTJWK5SpYrxd36xY+5HQ1xdP/czDePi4jR//vwb6wgAwGWQ9AMAoBheeOEFrVmzJt8rJsuXL2+zHBAQIElq3769TfkHH3ygrKwsm7LcV562bdvW+Hvnzp06cOCAsbx//37t3Lkz37qFkbt+dHS0unbtqtdff93mv9dee03NmjVT69ati7RvAAAAALCnTz75RP7+/sby+++/b5NMu/pCxeHDhyspKcmmbM2aNTbPgw8PDzeSfh4eHjaPZjh//rz++c9/5rmbTrpy9953331XqHZffffetWRkZOjnn382ltu0aWP8vW3bNv3+++/G8qlTp/Tjjz8ay5UqVVJYWJixPHToULm5uRnLgwcP1p49e/K8ZmZmpr7//nub5CMAwLWZrNzfDQBwIWvWrFGnTp2M5UmTJunJJ5+87nbLly83plX5+++/ba7w7Nu3r/7xj39Ikrp27aquXbted3+hoaE6deqUatSooQ4dOqhevXry9PTUkSNHNHPmTGVkZEi6MoXnn3/+KZPJJEm67777bJ7VEB4ernvvvVfe3t46cOCA1q1bp5iYGEnS8ePHFRERofT0dElXArknnnhCJpNJU6ZMMep5enrqwIEDRpD35JNPasqUKZKkDh06aM2aNXnan5CQoLCwMGMf5cuXV58+fRQWFqb09HQdOXJEa9as0cWLF7V69epSmS4VAAAAQNl1vVjvnXfe0UcffWQs//zzz3rkkUeM5eeee07/+c9/jOWaNWuqb9++qly5svbt26fZs2cbF116enpq1apVateunVH/8uXL6tChg3bt2mWUVa9eXb169VJwcLCSkpK0a9curVy5Uu3a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FsaNfThy3KSlpWn37t0FJjlgf6V1XpGcnKyIiAgtXLhQhw4d0uuvv67nn39eR48etX+nHKA0z89y7yf3OL1ZkfQDAAAAAMCJ2HO6NenKXRfr1q3T3r179dlnn+n//u//9P3335dwL5yHve++2Lt3r9asWaMhQ4bk2b5hw4by8vIyls1ms06cOGHfDqFADz/8sL766itFRUUpKipKX3/9db7TRgYGBio0NFRTpkxRWlqa0tLSNGXKFFWvXt244+zRRx/VDz/8oPPnzys1NVXjxo1T+/btjbuZMjMzlZaWpuzsbFksFqWlpSkzM7NU+1sS+Pwpexg3N85R48ZqtWrYsGGqXbu27r33Xnt3CwUorfOKkJAQPffcc6pRo4bMZrO6du2qunXrateuXSXWt9JUmudnkrRs2TLFx8frwQcftHtfnA1JPwAAAAAAnIg9p1uTpMaNG6tSpUpyc3NTZGSkhgwZogULFpRCTxzP3ndfZGVladiwYRo9erQ8PDzyfc233npLdevWVevWrZWcnKy+ffvav2PI18svv6zIyEh17NhRHTt2VKtWrYzniQ0fPlzDhw836k6aNEn79u1TZGSkWrRood27d2vy5MnG+qFDh6p9+/a666671KpVK6Wmpuqrr74y1g8bNkx169bVnDlzNGnSJNWtW1fDhg0rtb6WFD5/yh7GzY1zxLixWq1666239Oeff+qHH36Q2czP/KXBEecVOWJiYnT8+PGb4q7O0j6OiYmJGjVqlD755JOS6ZCTcXd0AwAAAAAAwP/knm4tNDRUUuGnW5Okp556ShMnTlRsbGy+z8kqSz8MXu/ui6uPZ6tWrTRt2jSFh4dLkiIjI23uvpg4caIiIiJ06623atOmTfm+5scff6zRo0dr3759Wr58uc1ro2R5eHjoo48+0kcffZRn3ZgxY2yW69evr2nTphW4Lzc3N40YMUIjRozId/2XX355Uz6zkc+fsodxc+NKe9xYrVa9/fbb2r17t2bOnJnnNVByHHFeIUkZGRkaPHiwunfvrqZNm9qtP45S2sfxww8/VJ8+fVSnTh1t377d7v1xNnzTAgAAAADgZOw53dqCBQuUlJQkq9WqPXv2aMKECbrvvvuMfWRlZSktLU1ZWVnGdGsZGRml1teSZM+7L06cOKEff/xR77777nVf12w2q2nTpipfvrw++OADe3UHKBV8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LoWFhalFixaaOnWqJOns2bN5tq9Vq5aefPLJku5iqbDnc5aut74orwX7Ks3kRc5rPf300woODpavr69ee+01bdq0SSkpKXbvW2krzWN54sQJ/fjjj3r33XdLoiu4joCAAFWvXl0HDhwwyg4cOKAaNWpc9+60Pn36yN39fxMKxMfH68yZMxowYIB8fHzk4+Ojp556Srt371ZsbOx1t3dlfP6UPaV1jiZJDz30kGrXrm2zjwsXLpRo/0pLaR5HSZo2bZpuv/12hYWFqU2bNlq2bFmJ9a0sI+YDAAAAgJLjNEm/rKws/fXXX2rcuLFRZjab1bhxYx09ejTfbW655Rb99ddfRsB38eJF7d69W82bNy+VNjuaPZNVq1ev1ltvvaVRo0bpyJEjWrVqldq2bStJqlmzps22Bw4ckJ+fnx544IFS6WdJs+dzlq63vrivhRtXmskLf39/1axZM9/9Wa1W+3XKQUrzWG7btk0xMTG6/fbbFRERoQEDBigpKUkRERHatWtXifYTVzz88MP66quvFBUVpaioKH399dd57jzL7fjx49qxY4f69etnUx4YGKjQ0FBNmTJFaWlpSktL05QpU1S9enUFBgZed3tXxudP2VNa52g53n77bZt93CzPwizN4/jTTz/pP//5jyZOnKhjx45p0aJFatCgQYn3sawh5gMAAACAkuU0l9AnJibKYrEoICDApjwgIEDnzp3Ld5v27dsrMTFR7733niQpOztbd911l3r37l3g62RmZiozM9NYNplM8vHxMf6WbH8Uyym7kfLcZfYqt1qtmjFjhkaOHGn8sPPSSy/p/fff1yuvvHLNNv7xxx86evSoHn74YaNs7NixevXVV9WuXTtJV457zr/F1ftZunSprFar7r333jzH7Eb7lKO0ynM/ZymnLCIiwuY5SwW1fcaMGerUqZOqV6+eb59y1uf8+yQkJOj8+fOKiIgw9pXzTKekpCT5+fm5zHvPnm0szT7lJC9atWolk8mUb/Iid/1jx45px44d+uKLL2zKcycvXn31VUnKk7x47LHH9MMPP6hTp07y9/fXuHHj1L59e5u7elz53+l6x/LqNuYcy3HjxhXpWPbo0UN33HGH0ZadO3dq2LBh+v3331W5cmWZTCaXeO8VVO4K4+mVV15RXFycOnbsKEnq3bu3XnzxRZlMJr3xxhuSpE8//dSoP2PG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PsbVn5UrV1bTpk3VoEED1alTx5FNB5yG2WxWxYoVtXHjRrm7u6tTp066//77ZbVatXHjRpnNZnXt2pVpXYD/79y5c5o6dar69++vO++8U2lpaVq3bp0kycPDQ9KV558sWrRIJ06c0MiRIxUSEuLIJgNwUsR8wPUR8wE3jpgPKDziPeSHS+1gF56enoqMjNQff/yhQ4cOKSAgQA899JDq1q2rZcuWadCgQfr222+VkZGh0aNHGw+jJvhDWZH7/X7mzBmNGTNGP/74oySpXbt26tSpk9LT0zVjxgzt3btXSUlJWrt2rerVq6cePXrIbDYbV4wCZVmtWrXUp08fBQYGatWqVVq9erUkqUePHmrfvr22bt2qVatWKTs728EtBZxDSkqKKleurDvvvFMXLlzQyy+/rE6dOumRRx6RJMXExCg0NFT33HOP3nnnHYWGhjq2wQCcFjEfcG3EfIB9EPMBhUe8h/zwTD8U2bWu1Pz666+Vnp6u559/XuXKlVNqaqpSU1N18uRJVa1aVTVq1OAB7ihzco+ZxYsX6++//9b27dt1+fJl3X333RowYIAkacuWLdq4caO2bdum6tWry83NTZ9++qnc3Ny4QhplUs77PiYmRsnJyfL19VVAQIDc3d114sQJLVy4UNHR0ercubM6deokSVqyZIlatmypqlWrOrj1gGPkjJs9e/bI19dXFotFX331lV566SWNHz9eTZo00TPPPCOz2ayDBw9qwYIFevbZZ41npgCARMwHFBUxH1A8xHxA0RDvoTCY3hNFlnMSOnfuXFWoUEF169Y1pqZo1qyZfv31V12+fFnlypWTl5eXfHx8bD5YLBYLwR/KhJwv4pwx88svv+i3337Ts88+q+bNm+vAgQNav369srOzNXDgQN16660KCwtT165dlZKSolatWhlXe/IMFJQ1OeNn27ZtmjVrlhITExUUFKTatWvr0UcfVe3atXX//fdr4cKFWrt2rTIzM9W1a1fde++9jm464FA5D3H/7LPPNHDgQDVr1kzBwcF6//331bJlSz377LPG80/++OMPpaeny92dkACALWI+oHCI+YDiI+YDio54D4XBvziKxWq16tKlS9q0aZMyMjIUGRmpzp076/bbb9eKFSv0yy+/aMiQIfmetHIii7Lg8uXLKl++vLGckpKigwcPqk+fPrr11lslSeHh4apRo4am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\n"},"metadata":{}}],"source":["# Créer la visualisation\n","display_metrics_subplot(results_df)"]},{"cell_type":"markdown","metadata":{"id":"u83ZVCLJWxlQ"},"source":["### Identifier le meilleur modèle selon `Precision`"]},{"cell_type":"markdown","source":["Le contexte métier est le suivant : on souhaite éviter à tout prix qu'un tweet qui serait reçu négativement soit à tort prédit comme positif. La variable \"precision\" (basée sur la modalité 1 = tweet positif) est donc la plus pertinente."],"metadata":{"id":"eHr3Z6btZm2E"}},{"cell_type":"code","source":["# Identifier le meilleur modèle selon la précision\n","best_model_row = results_df.loc[results_df['Precision'].idxmax()]\n","best_model_name = best_model_row['Modèle'].replace(\" \", \"_\")\n","best_vectorizer = best_model_row['Vectorisation']\n","\n","print(f\"\\nMeilleur modèle (selon la précision): {best_model_row['Modèle']} avec {best_vectorizer}\")\n","print(f\"Precision: {best_model_row['Precision']:.4f}\")\n","print(f\"F1 Score: {best_model_row['F1 Score']:.4f}\")\n","print(f\"ROC AUC: {best_model_row['ROC AUC']:.4f}\")\n","print(f\"Meilleurs paramètres: {best_model_row['Meilleurs paramètres']}\")\n","print(f\"\\nRun ID du meilleur modèle: {best_model_row['Run ID']}\")\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"f07BiYp_ZgDh","executionInfo":{"status":"ok","timestamp":1751526852512,"user_tz":-120,"elapsed":5,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"aff7d4cc-ebf4-47b3-971c-e81cc4b5cb8b"},"execution_count":34,"outputs":[{"output_type":"stream","name":"stdout","text":["\n","Meilleur modèle (selon la précision): Naive Bayes avec TF-IDF\n","Precision: 0.7776\n","F1 Score: 0.7674\n","ROC AUC: 0.8511\n","Meilleurs paramètres: {'alpha': '2.0'}\n","\n","Run ID du meilleur modèle: 64430125306243afab3cfa643aac487e\n"]}]},{"cell_type":"markdown","metadata":{"id":"lv6SEBguWxlQ"},"source":["## Charger le meilleur modèle et son vectoriseur depuis MLflow"]},{"cell_type":"code","execution_count":35,"metadata":{"id":"4n3rWdQ4WxlQ","executionInfo":{"status":"ok","timestamp":1751526852515,"user_tz":-120,"elapsed":2,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"outputs":[],"source":["def load_and_save_best_model(run_id, folder_path=\"content/simple-model/best\"):\n"," \"\"\"\n"," Charge le meilleur modèle et son vectoriseur depuis MLflow et les sauvegarde localement\n","\n"," Parameters:\n"," -----------\n"," run_id : str\n"," L'identifiant du run MLflow contenant le meilleur modèle\n"," folder_path : str, optional\n"," Le chemin où sauvegarder le modèle et le vectoriseur\n","\n"," Returns:\n"," --------\n"," tuple\n"," (modèle chargé, vectoriseur chargé)\n"," \"\"\"\n"," # Créer le dossier cible s'il n'existe pas\n"," try:\n"," os.makedirs(folder_path, exist_ok=True)\n"," except PermissionError:\n"," print(f\"Erreur de permission pour le dossier {folder_path}\")\n"," print(\"Tentative avec un dossier temporaire...\")\n"," import tempfile\n"," temp_dir = tempfile.mkdtemp()\n"," print(f\"Utilisation du dossier temporaire : {temp_dir}\")\n"," folder_path = temp_dir\n","\n"," # Créer un client MLflow\n"," client = MlflowClient()\n","\n"," print(f\"Chargement du modèle depuis le run {run_id}...\")\n","\n"," # Charger le modèle depuis MLflow\n"," best_model = mlflow.sklearn.load_model(f\"runs:/{run_id}/model\")\n","\n"," print(f\"Modèle chargé avec succès : {type(best_model).__name__}\")\n","\n"," # Récupérer les paramètres du run pour vérifier le type de vectoriseur\n"," run = client.get_run(run_id)\n"," vectorizer_type = run.data.params.get(\"vectorizer_type\", \"\").lower()\n","\n"," print(f\"Type de vectoriseur utilisé dans ce run : {vectorizer_type}\")\n","\n"," # Récupérer les artefacts du run\n"," artifacts = client.list_artifacts(run_id)\n","\n"," # Chercher le vectoriseur en privilégiant BoW ou CountVectorizer\n"," vectorizer_path = None\n","\n"," # Afficher les artefacts disponibles\n"," print(\"Artefacts disponibles :\")\n"," for artifact in artifacts:\n"," print(f\" - {artifact.path}\")\n","\n"," # Priorité 1: Chercher un vectoriseur correspondant au type attendu (BoW ou CountVectorizer)\n"," for artifact in artifacts:\n"," path_lower = artifact.path.lower()\n"," if \"vectorizer\" in path_lower and (\"bow\" in path_lower or \"countvectorizer\" in path_lower):\n"," vectorizer_path = artifact.path\n"," print(f\"Vectoriseur de type BoW/CountVectorizer trouvé : {artifact.path}\")\n"," break\n","\n"," # Priorité 2: Chercher n'importe quel vectoriseur\n"," if not vectorizer_path:\n"," for artifact in artifacts:\n"," if \"vectorizer\" in artifact.path.lower():\n"," vectorizer_path = artifact.path\n"," print(f\"Vectoriseur générique trouvé : {artifact.path}\")\n"," break\n","\n"," # Télécharger et charger le vectoriseur\n"," if vectorizer_path:\n"," local_path = client.download_artifacts(run_id, vectorizer_path)\n"," print(f\"Vectoriseur téléchargé dans : {local_path}\")\n","\n"," # Charger le vectoriseur depuis le fichier local\n"," with open(local_path, \"rb\") as f:\n"," vectorizer = pickle.load(f)\n","\n"," print(f\"Vectoriseur chargé avec succès : {type(vectorizer).__name__}\")\n"," else:\n"," print(\"Aucun fichier vectoriseur trouvé dans les artefacts, tentative de chargement direct...\")\n","\n"," # Tenter de charger le vectoriseur directement depuis MLflow\n"," try:\n"," vectorizer = mlflow.sklearn.load_model(f\"runs:/{run_id}/vectorizer\")\n"," print(f\"Vectoriseur chargé directement depuis MLflow : {type(vectorizer).__name__}\")\n"," except Exception as e:\n"," print(f\"Erreur lors du chargement direct du vectoriseur : {e}\")\n"," raise FileNotFoundError(\"Aucun vectoriseur trouvé dans les artefacts du run\")\n","\n"," # Sauvegarder le modèle et le vectoriseur localement avec leurs noms spécifiques\n"," model_name = type(best_model).__name__\n"," vectorizer_name = type(vectorizer).__name__\n"," model_save_path = os.path.join(folder_path, f\"{model_name}_model.pkl\")\n"," vectorizer_save_path = os.path.join(folder_path, f\"{vectorizer_name}_vectorizer.pkl\")\n","\n"," # Sauvegarder le modèle\n"," with open(model_save_path, \"wb\") as f:\n"," pickle.dump(best_model, f)\n","\n"," # Sauvegarder le vectoriseur\n"," with open(vectorizer_save_path, \"wb\") as f:\n"," pickle.dump(vectorizer, f)\n","\n"," print(f\"Modèle et vectoriseur sauvegardés avec succès dans {folder_path}\")\n"," print(f\"Chemins des fichiers :\")\n"," print(f\" - Modèle : {os.path.abspath(model_save_path)}\")\n"," print(f\" - Vectoriseur : {os.path.abspath(vectorizer_save_path)}\")\n","\n"," return best_model, vectorizer"]},{"cell_type":"code","execution_count":36,"metadata":{"id":"aGDo4_KJWxlR","colab":{"base_uri":"https://localhost:8080/","height":411,"referenced_widgets":["a4dbcce774844b00886b89cefd6e5973","7f6ee4adac484ab18a3d9e2cc99c2960","645949c22a9945a280c58bf443f2f74e","80b320e767ad4a0a99e33a4e4f58dd82","f481c828615e43318f91f79733f2572b","dc4b7bb2c64147df8292b4a711ed9c29","485fd1fc625540e8b2bccd70cb161c23","68615f77aef14811bf26848a5b99a374","d036fd1ac6f840f09811b130199778d8","97fc75af209c4437a96aeaad43e1bf29","7c639cf28ad34f51b48b7d1ec2e3c761","bbf74e1712bc403982416401dd9811ee","cff66c1bff964184920eef6bff0894b4","9b81458f402e4644b9aa36a8cdc47ece","29ea6f5542664cb8a1fa661de60b8ffb","9a8b5bfe0b2d4e1dba5f97a33a4b8236","520ae10b4ce34fd7ac4491f0dc4af041","fc7c4213c508460a850122c400b848df","3e4ffe9c1db746f699a1ea9dab1c1c38","530120ee1a544ed79cd69fbd9c80c404","912f830ec548489aace9f28c1d69c45e","9dc935e432e5491885a25b7ea1b38f49","bf6b7f963a784a00a39de176d03cffc6","f7aae87b7b494005acb70a90f3ba9d79","efb18be71be344fb855e9ea821c63c57","b3b9e4f187cb4589b93077e875633972","69e90cf85e394eee9e028501a8e61d4d","612a645744d447f5abe95ae0fd244486","9e6bb79026644f1b850266d1202ad366","fa5d79c7a14242f18c3f63de034f50bd","d8866027571c460c8ed0a7885402f38d","bb0babb23c1840c18b82beb7fe8a9357","92233ca5481d48dbb6b05bf8cb580c8d"]},"executionInfo":{"status":"ok","timestamp":1751526856311,"user_tz":-120,"elapsed":3795,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"875c258a-4537-4589-a2d3-dee23471447c"},"outputs":[{"output_type":"stream","name":"stdout","text":["Chargement du modèle depuis le run 64430125306243afab3cfa643aac487e...\n"]},{"output_type":"display_data","data":{"text/plain":["Downloading artifacts: 0%| | 0/1 [00:00<?, ?it/s]"],"application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"a4dbcce774844b00886b89cefd6e5973"}},"metadata":{}},{"output_type":"display_data","data":{"text/plain":["Downloading artifacts: 0%| | 0/5 [00:00<?, ?it/s]"],"application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"bbf74e1712bc403982416401dd9811ee"}},"metadata":{}},{"output_type":"stream","name":"stdout","text":["Modèle chargé avec succès : MultinomialNB\n","Type de vectoriseur utilisé dans ce run : tf-idf\n","Artefacts disponibles :\n"," - confusion_matrix.png\n"," - cv_results.csv\n"," - cv_results_alpha.png\n"," - roc_curve.png\n"," - vectorizer_TF-IDF.pkl\n","Vectoriseur générique trouvé : vectorizer_TF-IDF.pkl\n"]},{"output_type":"display_data","data":{"text/plain":["Downloading artifacts: 0%| | 0/1 [00:00<?, ?it/s]"],"application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"bf6b7f963a784a00a39de176d03cffc6"}},"metadata":{}},{"output_type":"stream","name":"stdout","text":["Vectoriseur téléchargé dans : /tmp/tmph5bfv08k/vectorizer_TF-IDF.pkl\n","Vectoriseur chargé avec succès : TfidfVectorizer\n","Modèle et vectoriseur sauvegardés avec succès dans content/simple-model/best\n","Chemins des fichiers :\n"," - Modèle : /content/drive/MyDrive/Colab_Notebooks/Project_7/notebooks/content/simple-model/best/MultinomialNB_model.pkl\n"," - Vectoriseur : /content/drive/MyDrive/Colab_Notebooks/Project_7/notebooks/content/simple-model/best/TfidfVectorizer_vectorizer.pkl\n"]}],"source":["# Charger et sauvegarder le meilleur modèle et son vectoriseur\n","best_model, vectorizer = load_and_save_best_model(run_id=best_model_row['Run ID'])"]},{"cell_type":"markdown","metadata":{"id":"Psby_wbGWxlR"},"source":["## Fonction de prédiction pour l'API\n","\n","Cette fonction constitue **le cœur de notre solution d'analyse de sentiment**. Elle prend **un tweet en entrée**, le prétraite, le vectorise et utilise notre modèle pour **prédire son sentiment**. Elle retourne un dictionnaire contenant le résultat (positif/négatif), un score de confiance et des métadonnées sur le modèle utilisé, **prêt à être exposé via l'API RESTful**."]},{"cell_type":"code","execution_count":37,"metadata":{"id":"7wl2v3XLWxlR","executionInfo":{"status":"ok","timestamp":1751526856318,"user_tz":-120,"elapsed":3,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"outputs":[],"source":["def predict_sentiment(text, model=best_model, vect=vectorizer):\n"," \"\"\"\n"," Fonction qui prend un texte en entrée et retourne la prédiction du sentiment\n"," Cette fonction pourra être utilisée dans l'API\n"," \"\"\"\n"," # Prétraiter le texte\n"," processed_text = preprocess_tweet(text)\n","\n"," # Vectoriser\n"," text_vectorized = vect.transform([processed_text])\n","\n"," # Prédire\n"," prediction = model.predict(text_vectorized)[0]\n","\n"," # Récupérer la probabilité si le modèle le permet\n"," if hasattr(model, 'predict_proba'):\n"," probas = model.predict_proba(text_vectorized)[0]\n"," confidence = probas[1] if prediction == 1 else probas[0]\n"," else:\n"," # Pour les modèles sans predict_proba, comme SVM\n"," decision = model.decision_function(text_vectorized)[0] if hasattr(model, 'decision_function') else 0\n"," confidence = abs(decision) / 2 # Normaliser d'une certaine façon\n","\n"," return {\n"," 'sentiment': 'positif' if prediction == 1 else 'négatif',\n"," 'score': float(confidence),\n"," 'model': best_model_name,\n"," 'vectorizer': best_vectorizer\n"," }"]},{"cell_type":"markdown","metadata":{"id":"HUpwhmfIWxlR"},"source":["## Test de la fonction de prédiction sur quelques exemples\n","\n","Nous avons constitué un **ensemble diversifié de tweets tests** incluant différentes caractéristiques linguistiques des réseaux sociaux pour évaluer notre modèle de détection de sentiment. Les résultats sont présentés dans un **DataFrame** avec des indicateurs visuels (💚/❌) permettant d'identifier rapidement les prédictions et leur **niveau de confiance**, validant ainsi l'efficacité de notre solution pour **anticiper les bad buzz**."]},{"cell_type":"code","execution_count":38,"metadata":{"id":"b86qIdD3WxlR","executionInfo":{"status":"ok","timestamp":1751526856332,"user_tz":-120,"elapsed":12,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}}},"outputs":[],"source":["# Liste améliorée de tweets pour tester le modèle\n","test_tweets_improved = [\n"," # Tweets positifs avec différentes caractéristiques\n"," \"I absolutely love flying with @AirParadis! Their service is amazing and their staff is so helpful :) #bestairline #travel\",\n"," \"Just landed after a wonderful flight... The crew was totally awesome and the food was perfect!!! Can't wait to fly with them again :D\",\n"," \"OMG! You really have to try @AirParadis. Best. Flight. Ever. Their new seats are extremely comfortable. http://airparadis.com/newseats #travel #comfort\",\n"," \"We had a very pleasant experience with our flight today. The staff completely exceeded our expectations ;) #happy #AirParadis\",\n"," \"My first time flying business class and I'm absolutely amazed!!! The service is 100% worth it... @AirParadis never disappoints :)\",\n","\n"," # Tweets négatifs avec différentes caractéristiques\n"," \"I hate how @AirParadis always delays their flights... This is the third time this month!!! :( #disappointed #travel\",\n"," \"The worst flight experience of my life? Definitely today with @AirParadis. Their customer service won't even respond to my complaints... #terrible\",\n"," \"Really @AirParadis??? Flight cancelled and no compensation??? That's how you treat your customers? SMH :(\",\n"," \"Our baggage was lost and nobody at @AirParadis seems to care! Don't they understand that we can't enjoy our vacation without our stuff??? http://badservice.com/complaint :-(\",\n"," \"Food was terrible, seats were uncomfortable, and the staff was not helpful at all... Never flying with @AirParadis again! #worstairline\",\n","\n"," # Tweets mixtes et nuancés\n"," \"The flight was good but the food wasn't really what I expected... @AirParadis can do better! #mixedfeelings\",\n"," \"IDK what to think about my @AirParadis experience? The crew was nice but the flight was delayed for 2 hours... #confused\",\n"," \"My husband loved the flight but I didn't... Too bad they can't make everyone happy :-) #AirParadis\",\n"," \"TBH, @AirParadis has improved their service since last year! Not perfect yet, but they're trying... #progress\",\n"," \"We were so excited for our trip but then our flight got delayed... at least the staff was very apologetic and gave us free drinks! @AirParadis\",\n","\n"," # Tweets spécifiquement pour tester les caractéristiques spéciales\n"," \"This is a tweet with many!!! exclamation!!! marks!!! to test how they affect sentiment analysis :)\",\n"," \"How does the model handle multiple??? question??? marks??? in a single tweet? @AirParadis\",\n"," \"Testing ellipses... many... many... ellipses... in... one... tweet... @AirParadis #test\",\n"," \"#many #hashtags #in #one #tweet #to #see #how #they #affect #the #analysis #AirParadis\",\n"," \"@mention1 @mention2 @mention3 @mention4 @mention5 multiple mentions in one tweet\",\n"," \"Multiple URLs in one tweet: http://example1.com http://example2.com http://example3.com @AirParadis\",\n"," \"Let's try all emoticons :) :( :D ;) :-) :-( :-D ;-) in a single tweet to see the impact\"\n","]"]},{"cell_type":"code","execution_count":39,"metadata":{"id":"HYemSzp2WxlR","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1751526861275,"user_tz":-120,"elapsed":4941,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"a927b8c4-1c10-4498-ce38-6f74654312b3"},"outputs":[{"output_type":"stream","name":"stdout","text":["\n","Test du modèle sur les exemples:\n","==================================================\n","Résumé: 22 tweets analysés\n","Tweets positifs: 13 (59.1%)\n","Tweets négatifs: 9 (40.9%)\n"]}],"source":["def test_model_on_examples(model, vectorizer, test_tweets):\n"," \"\"\"\n"," Teste le modèle sur une liste de tweets et retourne un DataFrame avec les résultats des prédictions.\n"," \"\"\"\n","\n"," results = {\n"," \"positif\": 0,\n"," \"négatif\": 0\n"," }\n","\n"," # Créer un DataFrame pour stocker les résultats\n"," predictions_data = []\n","\n"," for i, tweet in enumerate(test_tweets):\n"," result = predict_sentiment(tweet, model, vectorizer)\n","\n"," # Ajouter l'emoji approprié pour le sentiment\n"," emoji = \"💚\" if result['sentiment'] == \"positif\" else \"❌\"\n","\n"," # Ajouter les données au DataFrame\n"," predictions_data.append({\n"," \"Tweet\": tweet,\n"," \"Sentiment\": result['sentiment'],\n"," \"Emoji\": emoji,\n"," \"Score de confiance\": result['score'],\n"," \"Index\": i+1\n"," })\n","\n"," # Comptage des résultats\n"," results[result['sentiment']] += 1\n","\n"," # Créer le DataFrame\n"," df_predictions = pd.DataFrame(predictions_data)\n","\n"," # Afficher un résumé\n"," print(\"\\nTest du modèle sur les exemples:\")\n"," print(\"=\"*50)\n"," print(f\"Résumé: {len(test_tweets)} tweets analysés\")\n"," print(f\"Tweets positifs: {results['positif']} ({(results['positif']/len(test_tweets)*100):.1f}%)\")\n"," print(f\"Tweets négatifs: {results['négatif']} ({(results['négatif']/len(test_tweets)*100):.1f}%)\")\n","\n"," # Retourner le DataFrame\n"," return df_predictions\n","\n","# Exemple d'utilisation:\n","if best_model is not None and vectorizer is not None:\n"," # Obtenir le DataFrame des prédictions\n"," df_results = test_model_on_examples(best_model, vectorizer, test_tweets_improved)\n"," # Optionnel: sauvegarder les résultats dans un fichier CSV\n"," df_results.to_csv(\"content/simple-model/best/predictions_results.csv\", index=False)"]},{"cell_type":"code","execution_count":40,"metadata":{"id":"P40YQzXDWxlR","colab":{"base_uri":"https://localhost:8080/","height":1000},"executionInfo":{"status":"ok","timestamp":1751526861306,"user_tz":-120,"elapsed":16,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"c86fdff4-25e9-4cc4-e9bd-b8c73dd5476c"},"outputs":[{"output_type":"execute_result","data":{"text/plain":[" Tweet Sentiment Emoji \\\n","0 I absolutely love flying with @AirParadis! The... positif 💚 \n","1 Just landed after a wonderful flight... The cr... positif 💚 \n","2 OMG! You really have to try @AirParadis. Best.... positif 💚 \n","3 We had a very pleasant experience with our fli... positif 💚 \n","4 My first time flying business class and I'm ab... positif 💚 \n","5 I hate how @AirParadis always delays their fli... négatif ❌ \n","6 The worst flight experience of my life? Defini... négatif ❌ \n","7 Really @AirParadis??? Flight cancelled and no ... négatif ❌ \n","8 Our baggage was lost and nobody at @AirParadis... négatif ❌ \n","9 Food was terrible, seats were uncomfortable, a... négatif ❌ \n","10 The flight was good but the food wasn't really... positif 💚 \n","11 IDK what to think about my @AirParadis experie... négatif ❌ \n","12 My husband loved the flight but I didn't... To... négatif ❌ \n","13 TBH, @AirParadis has improved their service si... négatif ❌ \n","14 We were so excited for our trip but then our f... positif 💚 \n","15 This is a tweet with many!!! exclamation!!! ma... négatif ❌ \n","16 How does the model handle multiple??? question... positif 💚 \n","17 Testing ellipses... many... many... ellipses..... positif 💚 \n","18 #many #hashtags #in #one #tweet #to #see #how ... positif 💚 \n","19 @mention1 @mention2 @mention3 @mention4 @menti... positif 💚 \n","20 Multiple URLs in one tweet: http://example1.co... positif 💚 \n","21 Let's try all emoticons :) :( :D ;) :-) :-( :-... positif 💚 \n","\n"," Score de confiance Index \n","0 0.755137 1 \n","1 0.847082 2 \n","2 0.670729 3 \n","3 0.711088 4 \n","4 0.700775 5 \n","5 0.751911 6 \n","6 0.774884 7 \n","7 0.769952 8 \n","8 0.773392 9 \n","9 0.746100 10 \n","10 0.658434 11 \n","11 0.677109 12 \n","12 0.706524 13 \n","13 0.527076 14 \n","14 0.525280 15 \n","15 0.565299 16 \n","16 0.638518 17 \n","17 0.604475 18 \n","18 0.526669 19 \n","19 0.733951 20 \n","20 0.793815 21 \n","21 0.683887 22 "],"text/html":["\n"," <div id=\"df-27bd3bb7-fe42-4d57-9766-7b4c233c9f7d\" class=\"colab-df-container\">\n"," <div>\n","<style scoped>\n"," .dataframe tbody tr th:only-of-type {\n"," vertical-align: middle;\n"," }\n","\n"," .dataframe tbody tr th {\n"," vertical-align: top;\n"," }\n","\n"," .dataframe thead th {\n"," text-align: right;\n"," }\n","</style>\n","<table border=\"1\" class=\"dataframe\">\n"," <thead>\n"," <tr style=\"text-align: right;\">\n"," <th></th>\n"," <th>Tweet</th>\n"," <th>Sentiment</th>\n"," <th>Emoji</th>\n"," <th>Score de confiance</th>\n"," <th>Index</th>\n"," </tr>\n"," </thead>\n"," <tbody>\n"," <tr>\n"," <th>0</th>\n"," <td>I absolutely love flying with @AirParadis! The...</td>\n"," <td>positif</td>\n"," <td>💚</td>\n"," <td>0.755137</td>\n"," <td>1</td>\n"," </tr>\n"," <tr>\n"," <th>1</th>\n"," <td>Just landed after a wonderful flight... The cr...</td>\n"," <td>positif</td>\n"," <td>💚</td>\n"," <td>0.847082</td>\n"," <td>2</td>\n"," </tr>\n"," <tr>\n"," <th>2</th>\n"," <td>OMG! You really have to try @AirParadis. Best....</td>\n"," <td>positif</td>\n"," <td>💚</td>\n"," <td>0.670729</td>\n"," <td>3</td>\n"," </tr>\n"," <tr>\n"," <th>3</th>\n"," <td>We had a very pleasant experience with our fli...</td>\n"," <td>positif</td>\n"," <td>💚</td>\n"," <td>0.711088</td>\n"," <td>4</td>\n"," </tr>\n"," <tr>\n"," <th>4</th>\n"," <td>My first time flying business class and I'm ab...</td>\n"," <td>positif</td>\n"," <td>💚</td>\n"," <td>0.700775</td>\n"," <td>5</td>\n"," </tr>\n"," <tr>\n"," <th>5</th>\n"," <td>I hate how @AirParadis always delays their fli...</td>\n"," <td>négatif</td>\n"," <td>❌</td>\n"," <td>0.751911</td>\n"," <td>6</td>\n"," </tr>\n"," <tr>\n"," <th>6</th>\n"," <td>The worst flight experience of my life? Defini...</td>\n"," <td>négatif</td>\n"," <td>❌</td>\n"," <td>0.774884</td>\n"," <td>7</td>\n"," </tr>\n"," <tr>\n"," <th>7</th>\n"," <td>Really @AirParadis??? Flight cancelled and no ...</td>\n"," <td>négatif</td>\n"," <td>❌</td>\n"," <td>0.769952</td>\n"," <td>8</td>\n"," </tr>\n"," <tr>\n"," <th>8</th>\n"," <td>Our baggage was lost and nobody at @AirParadis...</td>\n"," <td>négatif</td>\n"," <td>❌</td>\n"," <td>0.773392</td>\n"," <td>9</td>\n"," </tr>\n"," <tr>\n"," <th>9</th>\n"," <td>Food was terrible, seats were uncomfortable, a...</td>\n"," <td>négatif</td>\n"," <td>❌</td>\n"," <td>0.746100</td>\n"," <td>10</td>\n"," </tr>\n"," <tr>\n"," <th>10</th>\n"," <td>The flight was good but the food wasn't really...</td>\n"," <td>positif</td>\n"," <td>💚</td>\n"," <td>0.658434</td>\n"," <td>11</td>\n"," </tr>\n"," <tr>\n"," <th>11</th>\n"," <td>IDK what to think about my @AirParadis experie...</td>\n"," <td>négatif</td>\n"," <td>❌</td>\n"," <td>0.677109</td>\n"," <td>12</td>\n"," </tr>\n"," <tr>\n"," <th>12</th>\n"," <td>My husband loved the flight but I didn't... To...</td>\n"," <td>négatif</td>\n"," <td>❌</td>\n"," <td>0.706524</td>\n"," <td>13</td>\n"," </tr>\n"," <tr>\n"," <th>13</th>\n"," <td>TBH, @AirParadis has improved their service si...</td>\n"," <td>négatif</td>\n"," <td>❌</td>\n"," <td>0.527076</td>\n"," <td>14</td>\n"," </tr>\n"," <tr>\n"," <th>14</th>\n"," <td>We were so excited for our trip but then our f...</td>\n"," <td>positif</td>\n"," <td>💚</td>\n"," <td>0.525280</td>\n"," <td>15</td>\n"," </tr>\n"," <tr>\n"," <th>15</th>\n"," <td>This is a tweet with many!!! exclamation!!! ma...</td>\n"," <td>négatif</td>\n"," <td>❌</td>\n"," <td>0.565299</td>\n"," <td>16</td>\n"," </tr>\n"," <tr>\n"," <th>16</th>\n"," <td>How does the model handle multiple??? question...</td>\n"," <td>positif</td>\n"," <td>💚</td>\n"," <td>0.638518</td>\n"," <td>17</td>\n"," </tr>\n"," <tr>\n"," <th>17</th>\n"," <td>Testing ellipses... many... many... ellipses.....</td>\n"," <td>positif</td>\n"," <td>💚</td>\n"," <td>0.604475</td>\n"," <td>18</td>\n"," </tr>\n"," <tr>\n"," <th>18</th>\n"," <td>#many #hashtags #in #one #tweet #to #see #how ...</td>\n"," <td>positif</td>\n"," <td>💚</td>\n"," <td>0.526669</td>\n"," <td>19</td>\n"," </tr>\n"," <tr>\n"," <th>19</th>\n"," <td>@mention1 @mention2 @mention3 @mention4 @menti...</td>\n"," <td>positif</td>\n"," <td>💚</td>\n"," <td>0.733951</td>\n"," <td>20</td>\n"," </tr>\n"," <tr>\n"," <th>20</th>\n"," <td>Multiple URLs in one tweet: http://example1.co...</td>\n"," <td>positif</td>\n"," <td>💚</td>\n"," <td>0.793815</td>\n"," <td>21</td>\n"," </tr>\n"," <tr>\n"," <th>21</th>\n"," <td>Let's try all emoticons :) :( :D ;) :-) :-( :-...</td>\n"," <td>positif</td>\n"," <td>💚</td>\n"," <td>0.683887</td>\n"," <td>22</td>\n"," </tr>\n"," </tbody>\n","</table>\n","</div>\n"," <div class=\"colab-df-buttons\">\n","\n"," <div class=\"colab-df-container\">\n"," <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-27bd3bb7-fe42-4d57-9766-7b4c233c9f7d')\"\n"," title=\"Convert this dataframe to an interactive table.\"\n"," style=\"display:none;\">\n","\n"," <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n"," <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n"," </svg>\n"," </button>\n","\n"," <style>\n"," .colab-df-container {\n"," display:flex;\n"," gap: 12px;\n"," }\n","\n"," .colab-df-convert {\n"," background-color: #E8F0FE;\n"," border: none;\n"," border-radius: 50%;\n"," cursor: pointer;\n"," display: none;\n"," fill: #1967D2;\n"," height: 32px;\n"," padding: 0 0 0 0;\n"," width: 32px;\n"," }\n","\n"," .colab-df-convert:hover {\n"," background-color: #E2EBFA;\n"," box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n"," fill: #174EA6;\n"," }\n","\n"," .colab-df-buttons div {\n"," margin-bottom: 4px;\n"," }\n","\n"," [theme=dark] .colab-df-convert {\n"," background-color: #3B4455;\n"," fill: #D2E3FC;\n"," }\n","\n"," [theme=dark] .colab-df-convert:hover {\n"," background-color: #434B5C;\n"," box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n"," filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n"," fill: #FFFFFF;\n"," }\n"," </style>\n","\n"," <script>\n"," const buttonEl =\n"," document.querySelector('#df-27bd3bb7-fe42-4d57-9766-7b4c233c9f7d button.colab-df-convert');\n"," buttonEl.style.display =\n"," google.colab.kernel.accessAllowed ? 'block' : 'none';\n","\n"," async function convertToInteractive(key) {\n"," const element = document.querySelector('#df-27bd3bb7-fe42-4d57-9766-7b4c233c9f7d');\n"," const dataTable =\n"," await google.colab.kernel.invokeFunction('convertToInteractive',\n"," [key], {});\n"," if (!dataTable) return;\n","\n"," const docLinkHtml = 'Like what you see? Visit the ' +\n"," '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n"," + ' to learn more about interactive tables.';\n"," element.innerHTML = '';\n"," dataTable['output_type'] = 'display_data';\n"," await google.colab.output.renderOutput(dataTable, element);\n"," const docLink = document.createElement('div');\n"," docLink.innerHTML = docLinkHtml;\n"," element.appendChild(docLink);\n"," }\n"," </script>\n"," </div>\n","\n","\n"," <div id=\"df-7a8eeb9c-d0f4-42ac-a699-0e790668ce40\">\n"," <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-7a8eeb9c-d0f4-42ac-a699-0e790668ce40')\"\n"," title=\"Suggest charts\"\n"," style=\"display:none;\">\n","\n","<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n"," width=\"24px\">\n"," <g>\n"," <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n"," </g>\n","</svg>\n"," </button>\n","\n","<style>\n"," .colab-df-quickchart {\n"," --bg-color: #E8F0FE;\n"," --fill-color: #1967D2;\n"," --hover-bg-color: #E2EBFA;\n"," --hover-fill-color: #174EA6;\n"," --disabled-fill-color: #AAA;\n"," --disabled-bg-color: #DDD;\n"," }\n","\n"," [theme=dark] .colab-df-quickchart {\n"," --bg-color: #3B4455;\n"," --fill-color: #D2E3FC;\n"," --hover-bg-color: #434B5C;\n"," --hover-fill-color: #FFFFFF;\n"," --disabled-bg-color: #3B4455;\n"," --disabled-fill-color: #666;\n"," }\n","\n"," .colab-df-quickchart {\n"," background-color: var(--bg-color);\n"," border: none;\n"," border-radius: 50%;\n"," cursor: pointer;\n"," display: none;\n"," fill: var(--fill-color);\n"," height: 32px;\n"," padding: 0;\n"," width: 32px;\n"," }\n","\n"," .colab-df-quickchart:hover {\n"," background-color: var(--hover-bg-color);\n"," box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n"," fill: var(--button-hover-fill-color);\n"," }\n","\n"," .colab-df-quickchart-complete:disabled,\n"," .colab-df-quickchart-complete:disabled:hover {\n"," background-color: var(--disabled-bg-color);\n"," fill: var(--disabled-fill-color);\n"," box-shadow: none;\n"," }\n","\n"," .colab-df-spinner {\n"," border: 2px solid var(--fill-color);\n"," border-color: transparent;\n"," border-bottom-color: var(--fill-color);\n"," animation:\n"," spin 1s steps(1) infinite;\n"," }\n","\n"," @keyframes spin {\n"," 0% {\n"," border-color: transparent;\n"," border-bottom-color: var(--fill-color);\n"," border-left-color: var(--fill-color);\n"," }\n"," 20% {\n"," border-color: transparent;\n"," border-left-color: var(--fill-color);\n"," border-top-color: var(--fill-color);\n"," }\n"," 30% {\n"," border-color: transparent;\n"," border-left-color: var(--fill-color);\n"," border-top-color: var(--fill-color);\n"," border-right-color: var(--fill-color);\n"," }\n"," 40% {\n"," border-color: transparent;\n"," border-right-color: var(--fill-color);\n"," border-top-color: var(--fill-color);\n"," }\n"," 60% {\n"," border-color: transparent;\n"," border-right-color: var(--fill-color);\n"," }\n"," 80% {\n"," border-color: transparent;\n"," border-right-color: var(--fill-color);\n"," border-bottom-color: var(--fill-color);\n"," }\n"," 90% {\n"," border-color: transparent;\n"," border-bottom-color: var(--fill-color);\n"," }\n"," }\n","</style>\n","\n"," <script>\n"," async function quickchart(key) {\n"," const quickchartButtonEl =\n"," document.querySelector('#' + key + ' button');\n"," quickchartButtonEl.disabled = true; // To prevent multiple clicks.\n"," quickchartButtonEl.classList.add('colab-df-spinner');\n"," try {\n"," const charts = await google.colab.kernel.invokeFunction(\n"," 'suggestCharts', [key], {});\n"," } catch (error) {\n"," console.error('Error during call to suggestCharts:', error);\n"," }\n"," quickchartButtonEl.classList.remove('colab-df-spinner');\n"," quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n"," }\n"," (() => {\n"," let quickchartButtonEl =\n"," document.querySelector('#df-7a8eeb9c-d0f4-42ac-a699-0e790668ce40 button');\n"," quickchartButtonEl.style.display =\n"," google.colab.kernel.accessAllowed ? 'block' : 'none';\n"," })();\n"," </script>\n"," </div>\n","\n"," <div id=\"id_798049cc-8136-4d80-9199-347920dcab77\">\n"," <style>\n"," .colab-df-generate {\n"," background-color: #E8F0FE;\n"," border: none;\n"," border-radius: 50%;\n"," cursor: pointer;\n"," display: none;\n"," fill: #1967D2;\n"," height: 32px;\n"," padding: 0 0 0 0;\n"," width: 32px;\n"," }\n","\n"," .colab-df-generate:hover {\n"," background-color: #E2EBFA;\n"," box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n"," fill: #174EA6;\n"," }\n","\n"," [theme=dark] .colab-df-generate {\n"," background-color: #3B4455;\n"," fill: #D2E3FC;\n"," }\n","\n"," [theme=dark] .colab-df-generate:hover {\n"," background-color: #434B5C;\n"," box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n"," filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n"," fill: #FFFFFF;\n"," }\n"," </style>\n"," <button class=\"colab-df-generate\" onclick=\"generateWithVariable('df_results')\"\n"," title=\"Generate code using this dataframe.\"\n"," style=\"display:none;\">\n","\n"," <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n"," width=\"24px\">\n"," <path d=\"M7,19H8.4L18.45,9,17,7.55,7,17.6ZM5,21V16.75L18.45,3.32a2,2,0,0,1,2.83,0l1.4,1.43a1.91,1.91,0,0,1,.58,1.4,1.91,1.91,0,0,1-.58,1.4L9.25,21ZM18.45,9,17,7.55Zm-12,3A5.31,5.31,0,0,0,4.9,8.1,5.31,5.31,0,0,0,1,6.5,5.31,5.31,0,0,0,4.9,4.9,5.31,5.31,0,0,0,6.5,1,5.31,5.31,0,0,0,8.1,4.9,5.31,5.31,0,0,0,12,6.5,5.46,5.46,0,0,0,6.5,12Z\"/>\n"," </svg>\n"," </button>\n"," <script>\n"," (() => {\n"," const buttonEl =\n"," document.querySelector('#id_798049cc-8136-4d80-9199-347920dcab77 button.colab-df-generate');\n"," buttonEl.style.display =\n"," google.colab.kernel.accessAllowed ? 'block' : 'none';\n","\n"," buttonEl.onclick = () => {\n"," google.colab.notebook.generateWithVariable('df_results');\n"," }\n"," })();\n"," </script>\n"," </div>\n","\n"," </div>\n"," </div>\n"],"application/vnd.google.colaboratory.intrinsic+json":{"type":"dataframe","variable_name":"df_results","summary":"{\n \"name\": \"df_results\",\n \"rows\": 22,\n \"fields\": [\n {\n \"column\": \"Tweet\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 22,\n \"samples\": [\n \"I absolutely love flying with @AirParadis! Their service is amazing and their staff is so helpful :) #bestairline #travel\",\n \"TBH, @AirParadis has improved their service since last year! Not perfect yet, but they're trying... #progress\",\n \"Our baggage was lost and nobody at @AirParadis seems to care! Don't they understand that we can't enjoy our vacation without our stuff??? http://badservice.com/complaint :-(\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Sentiment\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 2,\n \"samples\": [\n \"n\\u00e9gatif\",\n \"positif\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Emoji\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 2,\n \"samples\": [\n \"\\u274c\",\n \"\\ud83d\\udc9a\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Score de confiance\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.09190261007951528,\n \"min\": 0.5252796269034624,\n \"max\": 0.8470821783062017,\n \"num_unique_values\": 22,\n \"samples\": [\n 0.7551366186868385,\n 0.527076110678706\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Index\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 6,\n \"min\": 1,\n \"max\": 22,\n \"num_unique_values\": 22,\n \"samples\": [\n 1,\n 14\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}"}},"metadata":{},"execution_count":40}],"source":["df_results"]},{"cell_type":"code","execution_count":41,"metadata":{"id":"5g5IagpMWxlR","colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"status":"ok","timestamp":1751526861327,"user_tz":-120,"elapsed":20,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"173b7aa8-9b7a-49ce-d235-686b1d544c36"},"outputs":[{"output_type":"execute_result","data":{"text/plain":["Index(['Tweet', 'Sentiment', 'Emoji', 'Score de confiance', 'Index'], dtype='object')"]},"metadata":{},"execution_count":41}],"source":["df_results.columns"]},{"cell_type":"markdown","metadata":{"id":"2NbWQCrKWxlS"},"source":["## Conclusion de l'approche \"Modèle Simple\"\n","\n","Nous avons développé plusieurs modèles classiques pour la détection de sentiment dans les tweets,\n","en utilisant une **optimisation des hyperparamètres via GridSearchCV**, avec une attention particulière portée à la **précision** :\n","\n","- En effet, dans notre contexte métier, **le principal risque est de prédire à tort un tweet négatif comme étant positif** (faux positif), ce qui pourrait nuire à la réputation de l'entreprise.\n","- Pour cette raison, **la précision (precision) a été retenue comme métrique de sélection principale**, car elle mesure la proportion de tweets réellement positifs parmi ceux prédits comme positifs.\n","\n","Les modèles testés sont :\n","\n","1. Régression Logistique \n","2. SVM Linéaire \n","3. Random Forest \n","4. Naive Bayes \n","\n","Chaque modèle a été évalué avec deux techniques de vectorisation :\n","- Sac de mots (BoW)\n","- TF-IDF\n","\n","---\n","\n","### 📊 Meilleur modèle (selon la précision)\n","\n","Le modèle ayant obtenu la meilleure précision est : \n","**[en attente d'une valeur]** avec la vectorisation **[en attente d'une valeur]**\n","\n","- **Précision : [en attente d'une valeur]**\n","- **F1 Score : [en attente d'une valeur]**\n","- **ROC AUC : [en attente d'une valeur]**\n","\n","Hyperparamètres optimaux : **[en attente d'une valeur]**\n","\n","---\n","\n","### ✅ Avantages du workflow implémenté\n","\n","1. **Alignement sur la métrique métier (précision)** \n"," - Réduction du risque de faux positifs, cruciaux dans notre cas d’usage \n"," - Approche plus conservatrice mais adaptée à la gestion d'image de marque\n","\n","2. **Suivi des expérimentations avec MLflow** \n"," - Historique des runs, métriques, artefacts et vectoriseurs sauvegardés \n"," - Visualisation claire des performances\n","\n","3. **Optimisation rigoureuse** \n"," - Recherche sur grille (GridSearchCV) \n"," - Validation croisée pour robustesse des résultats \n"," - Comparaison systématique des performances\n","\n","4. **Prétraitement linguistique adapté aux tweets** \n"," - Nettoyage spécifique des entités (hashtags, mentions, URLs) \n"," - Lemmatisation avec conservation des négations \n"," - Ajout de variables contextuelles issues de l’analyse exploratoire\n","\n","\n","Le meilleur modèle classique retenu ici constituera une **baseline** solide pour mesurer les gains apportés par les approches de Deep Learning et de NLP avancé.\n"]},{"cell_type":"markdown","metadata":{"id":"jFI45SpVWxlS"},"source":["## Explications détaillées\n","\n","Le code complet intègre plusieurs pratiques MLOps avancées:\n","\n","### 1. Optimisation des hyperparamètres avec GridSearchCV\n","\n","J'ai implémenté GridSearchCV pour chaque combinaison de modèle et vectoriseur. Cela permet d'explorer systématiquement l'espace des hyperparamètres pour trouver la configuration optimale. Pour chaque modèle, j'ai défini une grille de paramètres pertinents:\n","\n","- **Régression Logistique**: différentes valeurs de régularisation (C), types de solveurs\n","- **SVM**: différentes valeurs de C, options de dualité\n","- **Random Forest**: nombre d'arbres, profondeur maximale, critères de division\n","- **Naive Bayes**: différentes valeurs pour le paramètre de lissage alpha\n","\n","L'optimisation est effectuée avec validation croisée à 5 plis (5-fold) pour garantir la robustesse des résultats.\n","\n","### 2. Tracking complet avec MLflow\n","\n","Pour chaque expérience, j'enregistre dans MLflow:\n","\n","- **Paramètres**: tous les hyperparamètres utilisés, y compris les meilleurs trouvés par GridSearchCV\n","- **Métriques**: accuracy, precision, recall, F1 score, ROC AUC, temps d'entraînement\n","- **Artifacts**:\n"," - Le modèle optimisé avec sa signature d'entrée/sortie\n"," - Le vectoriseur utilisé (nouveauté demandée)\n"," - La matrice de confusion et la courbe ROC\n"," - Les résultats détaillés de la validation croisée\n"," - Les features les plus importantes (pour les modèles qui le permettent)\n"," - Des graphiques d'analyse de l'influence des hyperparamètres\n","\n","### 3. Sauvegarde et utilisation du meilleur modèle\n","\n","J'ai implémenté une méthode pour:\n","\n","1. Identifier le meilleur modèle dans l'historique MLflow\n","2. Le récupérer avec son vectoriseur\n","3. Sauvegarder les deux dans un dossier local spécifié (\"content/simple-model/best\")\n","4. Créer une fonction de prédiction prête pour l'API\n","\n","### 4. Visualisations avancées\n","\n","Pour faciliter l'analyse:\n","\n","- Matrices de confusion pour chaque modèle\n","- Courbes ROC avec AUC calculé\n","- Graphiques des features les plus importantes\n","- Graphiques d'évolution des scores en fonction des hyperparamètres"]},{"cell_type":"markdown","source":["# Enregistrement de dépendances"],"metadata":{"id":"hJSt92gut0Vu"}},{"cell_type":"code","source":["!pip freeze > requirements_modele_simple.txt"],"metadata":{"id":"LeieF6LStjLc"},"execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.12"},"colab":{"provenance":[],"toc_visible":true},"widgets":{"application/vnd.jupyter.widget-state+json":{"a4dbcce774844b00886b89cefd6e5973":{"model_module":"@jupyter-widgets/controls","model_name":"HBoxModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_7f6ee4adac484ab18a3d9e2cc99c2960","IPY_MODEL_645949c22a9945a280c58bf443f2f74e","IPY_MODEL_80b320e767ad4a0a99e33a4e4f58dd82"],"layout":"IPY_MODEL_f481c828615e43318f91f79733f2572b"}},"7f6ee4adac484ab18a3d9e2cc99c2960":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_dc4b7bb2c64147df8292b4a711ed9c29","placeholder":"​","style":"IPY_MODEL_485fd1fc625540e8b2bccd70cb161c23","value":"Downloading artifacts:   0%"}},"645949c22a9945a280c58bf443f2f74e":{"model_module":"@jupyter-widgets/controls","model_name":"FloatProgressModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"danger","description":"","description_tooltip":null,"layout":"IPY_MODEL_68615f77aef14811bf26848a5b99a374","max":1,"min":0,"orientation":"horizontal","style":"IPY_MODEL_d036fd1ac6f840f09811b130199778d8","value":0}},"80b320e767ad4a0a99e33a4e4f58dd82":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_97fc75af209c4437a96aeaad43e1bf29","placeholder":"​","style":"IPY_MODEL_7c639cf28ad34f51b48b7d1ec2e3c761","value":" 0/1 [00:00&lt;?, ?it/s]"}},"f481c828615e43318f91f79733f2572b":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"dc4b7bb2c64147df8292b4a711ed9c29":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"485fd1fc625540e8b2bccd70cb161c23":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"68615f77aef14811bf26848a5b99a374":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"d036fd1ac6f840f09811b130199778d8":{"model_module":"@jupyter-widgets/controls","model_name":"ProgressStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"97fc75af209c4437a96aeaad43e1bf29":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"7c639cf28ad34f51b48b7d1ec2e3c761":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"bbf74e1712bc403982416401dd9811ee":{"model_module":"@jupyter-widgets/controls","model_name":"HBoxModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_cff66c1bff964184920eef6bff0894b4","IPY_MODEL_9b81458f402e4644b9aa36a8cdc47ece","IPY_MODEL_29ea6f5542664cb8a1fa661de60b8ffb"],"layout":"IPY_MODEL_9a8b5bfe0b2d4e1dba5f97a33a4b8236"}},"cff66c1bff964184920eef6bff0894b4":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_520ae10b4ce34fd7ac4491f0dc4af041","placeholder":"​","style":"IPY_MODEL_fc7c4213c508460a850122c400b848df","value":"Downloading artifacts: 100%"}},"9b81458f402e4644b9aa36a8cdc47ece":{"model_module":"@jupyter-widgets/controls","model_name":"FloatProgressModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_3e4ffe9c1db746f699a1ea9dab1c1c38","max":5,"min":0,"orientation":"horizontal","style":"IPY_MODEL_530120ee1a544ed79cd69fbd9c80c404","value":5}},"29ea6f5542664cb8a1fa661de60b8ffb":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_912f830ec548489aace9f28c1d69c45e","placeholder":"​","style":"IPY_MODEL_9dc935e432e5491885a25b7ea1b38f49","value":" 5/5 [00:00&lt;00:00,  7.16it/s]"}},"9a8b5bfe0b2d4e1dba5f97a33a4b8236":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"520ae10b4ce34fd7ac4491f0dc4af041":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"fc7c4213c508460a850122c400b848df":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"3e4ffe9c1db746f699a1ea9dab1c1c38":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"530120ee1a544ed79cd69fbd9c80c404":{"model_module":"@jupyter-widgets/controls","model_name":"ProgressStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"912f830ec548489aace9f28c1d69c45e":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"9dc935e432e5491885a25b7ea1b38f49":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"bf6b7f963a784a00a39de176d03cffc6":{"model_module":"@jupyter-widgets/controls","model_name":"HBoxModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_f7aae87b7b494005acb70a90f3ba9d79","IPY_MODEL_efb18be71be344fb855e9ea821c63c57","IPY_MODEL_b3b9e4f187cb4589b93077e875633972"],"layout":"IPY_MODEL_69e90cf85e394eee9e028501a8e61d4d"}},"f7aae87b7b494005acb70a90f3ba9d79":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_612a645744d447f5abe95ae0fd244486","placeholder":"​","style":"IPY_MODEL_9e6bb79026644f1b850266d1202ad366","value":"Downloading artifacts: 100%"}},"efb18be71be344fb855e9ea821c63c57":{"model_module":"@jupyter-widgets/controls","model_name":"FloatProgressModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_fa5d79c7a14242f18c3f63de034f50bd","max":1,"min":0,"orientation":"horizontal","style":"IPY_MODEL_d8866027571c460c8ed0a7885402f38d","value":1}},"b3b9e4f187cb4589b93077e875633972":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_bb0babb23c1840c18b82beb7fe8a9357","placeholder":"​","style":"IPY_MODEL_92233ca5481d48dbb6b05bf8cb580c8d","value":" 1/1 [00:00&lt;00:00,  2.79it/s]"}},"69e90cf85e394eee9e028501a8e61d4d":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"612a645744d447f5abe95ae0fd244486":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"9e6bb79026644f1b850266d1202ad366":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"fa5d79c7a14242f18c3f63de034f50bd":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"d8866027571c460c8ed0a7885402f38d":{"model_module":"@jupyter-widgets/controls","model_name":"ProgressStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"bb0babb23c1840c18b82beb7fe8a9357":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"92233ca5481d48dbb6b05bf8cb580c8d":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}}}}},"nbformat":4,"nbformat_minor":0}