La recherche en IA te passionne ?
Les papers et avancées qui comptent, expliqués simplement, chaque soir. Gratuit.
Inclus dès l'inscription : notre sélection des meilleurs guides & comparatifs IA.
Choisis ton rythme
Gratuit · Pas de spam · Désabonnement en 1 clic
Scikit-LLM : pipeline d'analyse de sentiment complet
Introduction
Les pipelines d'apprentissage automatique traditionnels pour des tâches prédictives comme la classification de texte reposent généralement sur l'extraction de caractéristiques numériques structurées à partir de texte brut — par exemple, les fréquences TF-IDF ou les embeddings de tokens — pour alimenter des modèles classiques tels que la régression logistique, les ensembles ou les machines à vecteurs de support.
Avec l'émergence des grands modèles de langage (LLMs), les règles du jeu ont quelque peu changé : il est désormais possible d'exploiter le raisonnement zero-shot ou few-shot sur des modèles pré-entraînés existants pour des tâches linguistiques dans le cadre d'un framework d'apprentissage automatique. Scikit-LLM est une bibliothèque Python qui répond à ce besoin : elle fait le lien entre l'apprentissage automatique classique et les appels d'API modernes des LLM. Dans cet article, nous utiliserons Scikit-LLM avec des modèles de backend Groq pour construire un pipeline complet d'analyse de sentiment (une forme spécifique de classification de texte), atteignant des résultats d'inférence raisonnablement rapides avec des modèles open-source. De la prétraitement à l'inférence, nous utiliserons un grand ensemble de données de taille réaliste — le jeu de données des critiques de films IMDB.
Prérequis, configuration et obtention du jeu de données
Pour faire fonctionner le code présenté dans ce tutoriel, vous devez avoir installé la bibliothèque Scikit-LLM :
pip install scikit-llm
Une fois installé, la première étape consiste à le configurer et à définir les identifiants de l'API. En d'autres termes, nous devrons « connecter » Scikit-LLM à un point de terminaison — à savoir un dépôt d'API LLM comme Groq. Assurez-vous de vous inscrire sur Groq et de générer une clé API ici : vous devrez la copier et la coller dans le code ci-dessous :
from skllm.config import SKLLMConfig
# 1. Pointant vers un point de terminaison compatible Groq
SKLLMConfig.set_gpt_url("https://api.groq.com/[openai](/dossier/openai)/v1")
# 2. Définissez votre clé API Groq gratuite
# Obtenez la vôtre sur https://console.groq.com/keys
SKLLMConfig.set_openai_key("VOTRE-CLÉ-API-VA-ICI")
Scikit-LLM utilise une fonction de point de terminaison, set_gpt_url, qui est compatible avec OpenAI par défaut ; nous l'avons redirigée pour effectuer des requêtes internes vers une URL Groq personnalisée : https://api.groq.com/openai/v1.
L'étape suivante consiste à importer le jeu de données des critiques de films IMDB — qui contient environ 50 000 instances — et à le préparer pour le pipeline d'analyse de sentiment que nous allons construire. Les instances consistent en une critique textuelle étiquetée avec un sentiment, qui peut être positif ou négatif (il s'agit d'un problème de classification binaire, résoluble avec des modèles comme la régression logistique, par exemple).
Pour des raisons de commodité, nous allons lire le jeu de données à partir d'un dépôt GitHub public au format CSV :
import pandas as pd
from sklearn.model_selection import train_test_split
# Récupération d'un grand jeu de données de taille réaliste (critiques de films IMDB - 50 000 lignes)
# Nous allons lire les données à partir d'un CSV brut public pour plus de commodité
url = "https://raw.githubusercontent.com/Ankit152/IMDB-sentiment-analysis/master/IMDB-Dataset.csv"
print("Téléchargement du jeu de données...")
df = pd.read_csv(url)
print(f"Taille totale du jeu de données : {df.shape[0]} lignes")
# Dans un pipeline LLM réaliste utilisant une API gratuite, l'envoi de 50 000 requêtes
# déclenchera probablement des limites de quota. Ainsi, nous utiliserons 500 lignes pour démontrer l'exécution de notre pipeline.
# N'hésitez pas à utiliser plus de données si vous avez un accès API payant.
df_sampled = df.sample(n=500, random_state=42)
Le jeu de données IMDB contient des balises HTML et du bruit de formatage : c'est parfait pour tester notre nettoyeur
X = df_sampled["review"] y = df_sampled["sentiment"] # Les étiquettes sont 'positive' ou 'negative'
Division en ensembles d'entraînement (pour initialiser les étiquettes zero-shot) et de test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
Notez que nous avons récupéré uniquement **500** lignes à des fins de démonstration, car sinon l'inférence pourrait prendre du temps sans ressources informatiques suffisantes. Vous pouvez librement modifier cette taille d'échantillon, **n=500**, pour l'adapter à vos propres besoins.
### Construction du pipeline d'analyse de sentiment
Voici la partie la plus intéressante du processus ! Un pipeline de science des données se résume à une série d'étapes de prétraitement, de nettoyage et de préparation des données suivies de la configuration ou de l'entraînement du modèle, de l'inférence et de l'évaluation. Pour un scénario prédictif basé sur du texte comme le nôtre, le prétraitement implique généralement le nettoyage et la normalisation du texte. Scikit-learn fournit une classe élégante, **FunctionTransformer**, pour définir et encapsuler les étapes de prétraitement basées sur une fonction personnalisée :
```python
from sklearn.preprocessing import FunctionTransformer
def clean_text_data(texts):
"""Nettoie les entrées de texte brut en supprimant les balises HTML et en éliminant les espaces superflus."""
series = pd.Series(texts).astype(str)
# Supprimer les balises HTML comme <br />
cleaned = series.str.replace(r'<[^>]+>', ' ', regex=True)
# Supprimer les espaces supplémentaires
cleaned = cleaned.str.strip().str.replace(r'\s+', ' ', regex=True)
return cleaned.tolist()
# Encapsulation de la fonction de nettoyage pour permettre son utilisation dans un objet Pipeline
text_cleaner = FunctionTransformer(clean_text_data)
Nous allons maintenant assembler cet objet de prétraitement avec une instance de modèle pour créer le pipeline. Une fois défini, ce pipeline orchestre l'ensemble du processus de préparation des données et de passage au modèle tant lors des étapes d'entraînement que d'inférence — même si nous utilisons le terme « entraînement », aucun entraînement basé sur des poids n'aura lieu, car nous utilisons un modèle pré-entraîné de Groq pour la classification zero-shot. L'ajustement du modèle consiste uniquement à lui passer les étiquettes de classification à utiliser.
from sklearn.pipeline import Pipeline
from skllm.models.[gpt](/glossaire/gpt).classification.zero_shot import ZeroShotGPTClassifier
# Définir le pipeline de bout en bout
sentiment_pipeline = Pipeline([
("cleaner", text_cleaner),
# Mis à jour pour utiliser le modèle Llama 3.1 8B actif de Groq
("llm_classifier", ZeroShotGPTClassifier(model="custom_url::[llama](/dossier/meta-ia)-3.1-8b-instant"))
])
# Ajuster le pipeline
# Remarque : Pour la classification Zero-Shot, fit() n'entraîne pas le LLM.
# Il enregistre simplement les étiquettes uniques présentes dans 'y_train' (positive, negative).
print("Ajustement du pipeline...")
sentiment_pipeline.fit(X_train, y_train)
Une fois que nous avons exécuté le pipeline pour « ajuster » le modèle, nous l'utilisons à nouveau pour l'inférence. Les deux étapes utilisent une syntaxe scikit-learn familière. En plus d'évaluer la performance du pipeline, nous affichons également quelques exemples de prédictions :
from sklearn.metrics import classification_report
print(f"Exécution des prédictions sur {len(X_test)} échantillons de test...")
# Exécuter les prédictions à travers le pipeline
predictions = sentiment_pipeline.predict(X_test)
# Évaluer la performance du pipeline sur les données réalistes
print("\n--- Rapport de Classification ---")
print(classification_report(y_test, predictions))
# Afficher quelques exemples côte à côte
print("\n--- Exemples de Prédictions ---")
for review, actual, predicted in zip(X_test[:3], y_test[:3], predictions[:3]):
# Truncate review for display purposes
short_review = review[:100]



