Dans ce guide, vous apprendrez :
- Qu’est-ce que la classification “zero-shot” et comment fonctionne-t-elle ?
- Avantages et inconvénients de son utilisation
- Pertinence de cette pratique dans le cadre du web scraping
- Tutoriel étape par étape pour la mise en œuvre de la classification “zero-shot” dans un scénario de “web scraping”.
Plongeons dans l’aventure !
Qu’est-ce que la classification “Zero-Shot” ?
La classification zéro-coup (ZSC) est la capacité de prédire une classe qu’un modèle d’apprentissage automatique n’a jamais vue au cours de sa phase de formation. Une classe est une catégorie ou une étiquette spécifique que le modèle attribue à un élément de données. Par exemple, il peut attribuer la classe “spam” au texte d’un courrier électronique ou la classe “chat” à une image.
ZSC peut être considéré comme un exemple d’apprentissage par transfert. L’apprentissage par transfert est une technique d’apprentissage automatique qui consiste à appliquer les connaissances acquises lors de la résolution d’un problème pour aider à résoudre un problème différent, mais connexe.
L’idée centrale de la ZSC a été explorée et mise en œuvre dans plusieurs types de réseaux neuronaux et de modèles d’apprentissage automatique depuis un certain temps. Elle peut être appliquée à différentes modalités, notamment :
- Texte: Imaginez que vous disposiez d’un modèle formé à la compréhension générale du langage, mais que vous ne lui ayez jamais montré un exemple de “critique de produit pour un emballage durable”. Avec ZSC, vous pouvez lui demander d’identifier de telles critiques à partir d’une pile de texte. Pour ce faire, il comprend la signification des catégories souhaitées (étiquettes) et les fait correspondre au texte d’entrée, plutôt que de s’appuyer sur des exemples préappris pour chaque étiquette spécifique.
- Images: Un modèle formé sur un ensemble d’images d’animaux (chats, chiens, chevaux, etc.) peut être capable de classer une image de zèbre comme un “animal” ou même un “animal rayé ressemblant à un cheval” sans avoir jamais vu de zèbre pendant la formation.
- Audio: Un modèle peut être entraîné à reconnaître des sons urbains courants tels que “klaxon de voiture”, “sirène” et “aboiement de chien”. Grâce à ZSC, un modèle peut identifier un son sur lequel il n’a jamais été explicitement formé, tel que “marteau-piqueur”, en comprenant ses propriétés acoustiques et en les mettant en relation avec des sons connus.
- Données multimodales: Le ZSC peut travailler sur différents types de données, par exemple en classant une image sur la base d’une description textuelle d’une classe qu’il n’a jamais vue, ou vice versa.
Comment fonctionne ZSC ?
La classification zéro-coup gagne en intérêt grâce à la popularité des LLM pré-entraînés. Ces modèles sont entraînés sur des quantités massives de données orientées vers l’IA, ce qui leur permet de développer une compréhension approfondie du langage, de la sémantique et du contexte.
Pour ZSC, les modèles pré-entraînés sont souvent affinés dans le cadre d’une tâche appelée NLI(Natural Language Inference). La NLI consiste à déterminer la relation entre deux morceaux de texte : une “prémisse” et une “hypothèse”. Le modèle décide si l’hypothèse est une implication (vraie compte tenu de la prémisse), une contradiction (fausse compte tenu de la prémisse) ou neutre (sans rapport).
Dans une configuration de classification à zéro coup, le texte d’entrée sert de prémisse. Les étiquettes des catégories candidates sont traitées comme des hypothèses. Le modèle calcule quelle “hypothèse” (étiquette) est la plus susceptible de correspondre à la “prémisse” (texte d’entrée). L’étiquette ayant le score d’implication le plus élevé est choisie pour la classification.
Avantages et limites de l’utilisation de la classification “Zero-Shot”.
Il est temps d’explorer les avantages et les inconvénients de ZSC.
Avantages
Le ZSC présente plusieurs avantages opérationnels, notamment
- Adaptabilité aux nouvelles classes: ZSC ouvre la voie à la classification des données dans des catégories inédites. Pour ce faire, il définit de nouvelles étiquettes sans nécessiter le recyclage du modèle ou la collecte d’exemples de formation spécifiques pour les nouvelles classes.
- Exigence réduite en matière de données étiquetées: La méthode réduit la dépendance à l’égard de vastes ensembles de données étiquetées pour les classes cibles. Cela permet de réduire l’étiquetage des données, ungoulot d’étranglement courant dans les délais et les coûts des projets d’apprentissage automatique.
- Mise en œuvre efficace des classificateurs: Les nouveaux systèmes de classification peuvent être configurés et évalués rapidement. Cela permet d’accélérer les cycles d’itération en réponse à l’évolution des besoins.
Limites
Bien qu’elle soit puissante, la classification “zero-shot” présente des limites, telles que
- Variabilité des performances: Les modèles alimentés par ZSC peuvent présenter une précision inférieure à celle des modèles supervisés formés de manière intensive sur des ensembles de classes fixes. Cela s’explique par le fait que le ZSC repose sur l’inférence sémantique plutôt que sur la formation directe à partir d’exemples de classes cibles.
- Dépendance à l’égard de la qualité du modèle: Les performances du ZSC dépendent de la qualité et des capacités du modèle linguistique pré-entraîné sous-jacent. Un modèle de base performant permet généralement d’obtenir de meilleurs résultats en matière de ZSC.
- Ambiguïté et formulation des étiquettes: La clarté et le caractère distinctif des étiquettes candidates influencent la précision. Des étiquettes ambiguës ou mal définies peuvent entraîner des performances sous-optimales.
L’importance de la classification par point zéro dans le domaine du décryptage de sites Web
L’émergence continue de nouvelles informations, de nouveaux produits et de nouveaux sujets sur le web exige des méthodes de traitement des données adaptables. Tout commence par le “web scraping”, c’est-à-dire leprocessus automatisé d’extraction de données à partir de pages web.
Les méthodes traditionnelles d’apprentissage automatique nécessitent une catégorisation manuelle ou un recyclage fréquent pour traiter les nouvelles classes dans les données récupérées, ce qui est inefficace à grande échelle. Au lieu de cela, la classification “zero-shot” relève les défis posés par la nature dynamique du contenu web en permettant :
- Catégorisation dynamique de données hétérogènes: Les données extraites de diverses sources peuvent être classées en temps réel à l’aide d’un ensemble d’étiquettes définies par l’utilisateur et pertinentes pour les objectifs analytiques actuels.
- Adaptation à l’évolution des paysages informationnels: De nouvelles catégories ou de nouveaux thèmes peuvent être incorporés immédiatement dans le schéma de classification, sans qu’il soit nécessaire de procéder à de longs cycles de redéveloppement du modèle.
Ainsi, les cas d’utilisation typiques de ZSC dans le domaine du web scraping sont les suivants :
- Catégorisation dynamique du contenu: Lors de la récupération de contenus tels que des articles d’actualité ou des listes de produits provenant de plusieurs domaines, ZSC peut automatiquement affecter les éléments à des catégories prédéfinies ou à de nouvelles catégories.
- Analyse des sentiments pour les nouveaux sujets: Pour les avis de clients sur de nouveaux produits ou les données des médias sociaux relatives à des marques émergentes, ZSC peut effectuer une analyse des sentiments sans avoir besoin de données d’entraînement spécifiques à ce produit ou à cette marque. Cela facilite la surveillance de la perception de la marque et l’évaluation du retour d’information des clients.
- Identification des tendances et des thèmes émergents: En définissant des étiquettes d’hypothèses représentant de nouvelles tendances potentielles, ZSC peut être utilisé pour analyser des textes extraits de forums, de blogs ou de médias sociaux afin d’identifier la prévalence croissante de ces thèmes.
Mise en œuvre pratique de la classification “Zero-Shot
Cette section du didacticiel vous guidera dans le processus d’application de la classification “zero-shot” aux données extraites du Web. Le site cible sera “Équipes de hockey” : Formulaires, recherche et pagination” :
Tout d’abord, un scraper web extraira les données du tableau ci-dessus. Ensuite, un LLM les classifiera en utilisant ZSC. Pour ce tutoriel, vous utiliserez le DistilBart-MNLI de Hugging Face : un LLM léger de la famille BART.
Suivez les étapes ci-dessous et voyez comment atteindre l’objectif ZSC souhaité !
Conditions préalables et dépendances
Pour reproduire ce tutoriel, vous devez avoir installé Python 3.10.1 ou une version plus récente sur votre machine.
Supposons que vous appeliez le dossier principal de votre projet zsc_project/.
À la fin de cette étape, le dossier aura la structure suivante :
zsc_project/
├── zsc_scraper.py
└── venv/
Où ?
zsc_scraper.py
est le fichier Python qui contient la logique de codage.venv/
contient l’environnement virtuel.
Vous pouvez créer le répertoire de l ‘environnement virtuel venv/ de la
manière suivante :
python -m venv venv
Pour l’activer, sous Windows, exécutez :
venv\Scripts\activate
De manière équivalente, sous macOS et Linux, exécutez :
source venv/bin/activate
Dans l’environnement virtuel activé, installez les dépendances avec :
pip install requests beautifulsoup4 transformers torch
Ces dépendances sont les suivantes :
requêtes
: Une bibliothèque pour effectuer des requêtes web HTTP.beautifulssoup4
: Une bibliothèque pour analyser des documents HTML et XML et en extraire des données. Pour en savoir plus, consultez notre guide sur le web scraping BeautifulSoup.transformateurs
: Une bibliothèque de Hugging Face qui fournit des milliers de modèles pré-entraînés.torch
: PyTorch, un cadre d’apprentissage machine open-source.
C’est formidable ! Vous avez maintenant ce qu’il vous faut pour extraire les données du site web cible et pour effectuer le ZSC.
Étape 1 : Installation et configuration initiales
Initialiser le fichier zsc_scraper.py
en important les bibliothèques nécessaires et en définissant quelques variables :
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
from transformers import pipeline
# The starting URL for scraping
BASE_URL = "https://www.scrapethissite.com/pages/forms/"
# Predefined categories for the zero-shot classification
CANDIDATE_LABELS = [
"NHL team season performance summary",
"Player biography and career stats",
"Sports news and game commentary",
"Hockey league rules and regulations",
"Fan discussions and forums",
"Historical sports data record"
]
MAX_PAGES_TO_SCRAPE = 2 # Maximum number of pages to scrape
MAX_TEAMS_PER_PAGE_FOR_ZSC = 2 # Maximum number of teams to process
Le code ci-dessus effectue les opérations suivantes :
- Définit le site web cible à analyser avec
BASE_URL
. CANDIDATES_LABELS
stocke une liste de chaînes de caractères qui définissent les catégories que le modèle de classification “zero-shot” utilisera pour classer les données extraites. Le modèle tentera de déterminer laquelle de ces étiquettes décrit le mieux chaque donnée de l’équipe.- Définit le nombre maximum de pages à extraire et le nombre maximum de données d’équipes à récupérer.
C’est parfait ! Vous avez ce qu’il faut pour commencer à utiliser la classification à partir de zéro en Python.
Étape 2 : Récupérer les URL des pages
Commencez par inspecter l’élément de pagination sur la page cible :
Ici, vous pouvez remarquer que les URL de pagination sont contenues dans un nœud HTML .pagination
.
Définir une fonction permettant de trouver toutes les URL de pages uniques dans la section “pagination” du site web :
def get_all_page_urls(base_url_to_scrape):
page_urls = [base_url_to_scrape] # Initialize with the base URL
response = requests.get(base_url_to_scrape) # Fetch content of base URL
soup = BeautifulSoup(response.content, "html.parser") # Parse the HTML content
# Tags for pagination
pagination_links = soup.select("ul.pagination li a")
discovered_urls = set() # Store unique relative URLs to avoid duplicates
for link_tag in pagination_links:
href = link_tag.get("href")
# Ensure the link is a pagination link for this site
if href and href.startswith("?page_num="):
discovered_urls.add(href)
# Sort for consistent order and construct full URLs
for relative_url in sorted(list(discovered_urls)):
full_url = urljoin(base_url_to_scrape, relative_url) # Create absolute URL
# If you want to add paginated URLs, uncomment the next line:
page_urls.append(full_url)
return page_urls
Cette fonction :
- Envoie une requête HTTP au site web cible avec la méthode
get().
- Gère la pagination avec la méthode
select()
de BeautifulSoup. - Parcourt chaque page, en veillant à ce que l’ordre soit cohérent, à l’aide d’une boucle
"for".
- Renvoie la liste de tous les URL uniques de pleine page.
Cool ! Vous avez créé une fonction pour récupérer les URL des pages web à partir desquelles vous souhaitez extraire des données.
Étape 3 : Récupérer les données
Commencez par inspecter l’élément de pagination sur la page cible :
Ici, vous pouvez voir que les données des équipes à récupérer sont contenues dans un nœud HTML .table.
Créez une fonction qui prend l’URL d’une page unique, récupère son contenu et extrait les statistiques de l’équipe :
def scrape_page(url):
page_data = [] # List to store data scraped from this page
response = requests.get(url) # Fetch the content of the page
soup = BeautifulSoup(response.content, "html.parser") # Parse the HTML
# Select all table rows with class "team" inside a table with class "table"
table_rows = soup.select("table.table tr.team")
for row in table_rows:
# Extract text from each row (name, year, wins, losses)
team_stats = {
"name": row.select_one("td.name").get_text(strip=True),
"year": row.select_one("td.year").get_text(strip=True),
"wins": row.select_one("td.wins").get_text(strip=True),
"losses": row.select_one("td.losses").get_text(strip=True),
}
page_data.append(team_stats) # Add the scraped team data to the list
return page_data
Cette fonction :
- Récupère les données des lignes du tableau à l’aide de la méthode
select().
- Traite chaque ligne de l’équipe avec la boucle
for row in table_rows :.
- Renvoie les données extraites dans une liste.
Bravo ! Vous avez créé une fonction pour récupérer les données du site web cible.
Étape 4 : Orchestrer le processus
Coordonnez l’ensemble du flux de travail en suivant les étapes suivantes :
- Charger le modèle de classification
- Récupérer les URLs des pages à scraper
- Récupérer les données de chaque page
- Classifier le texte scrappé avec ZSC
Pour ce faire, il suffit d’utiliser le code suivant :
# Initialize the zero-shot classification pipeline
classifier = pipeline("zero-shot-classification", model="valhalla/distilbart-mnli-12-3")
# Get all URLs to scrape (base URL + paginated URLs)
all_page_urls = get_all_page_urls(BASE_URL)
all_team_data_for_zsc = [] # List to store team data selected for classification
# Loop through the page URLs
for page_url in all_page_urls[:MAX_PAGES_TO_SCRAPE]:
current_page_team_data = scrape_page(page_url) # Scrape data from the current page
# Maximum teams per page to scrape
all_team_data_for_zsc.extend(current_page_team_data[:MAX_TEAMS_PER_PAGE_FOR_ZSC])
# Start classification
print(f"\n--- Classifying {len(all_team_data_for_zsc)} Scraped Hockey Team Snippets ---")
# Loop through the collected team data to classify each one
for i, team_info_dict in enumerate(all_team_data_for_zsc):
name = team_info_dict["name"]
year = team_info_dict["year"]
wins = team_info_dict["wins"]
losses = team_info_dict["losses"]
# Construct a text snippet from the team data for classification
text_snippet = f"Team: {name}, Year: {year}, Wins: {wins}, Losses: {losses}."
print(f"\nData Snippet {i+1}: \"{text_snippet}\"")
# Perform zero-shot classification
result = classifier(text_snippet, CANDIDATE_LABELS, multi_label=False)
# Print the predicted category and its confidence score
print(f"Predicted Category: {result['labels'][0]}")
print(f"Confidence Score: {result['scores'][0]:.4f}")
Ce code :
- Charge le modèle pré-entraîné avec la méthode
pipeline()
et spécifie sa tâche avec"zero-shot-classification"
. - Appelle les fonctions précédentes et effectue le ZSC proprement dit.
C’est parfait ! Vous avez créé une fonction qui orchestre toutes les étapes précédentes et effectue la classification zéro.
Étape 5 : Assembler le tout et exécuter le code
Voici ce que le fichier zsc_scraper.py
devrait maintenant contenir :
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
from transformers import pipeline
# The starting URL for scraping
BASE_URL = "https://www.scrapethissite.com/pages/forms/"
# Predefined categories for the zero-shot classification
CANDIDATE_LABELS = [
"NHL team season performance summary",
"Player biography and career stats",
"Sports news and game commentary",
"Hockey league rules and regulations",
"Fan discussions and forums",
"Historical sports data record"
]
MAX_PAGES_TO_SCRAPE = 2 # Maximum number of pages to scrape
MAX_TEAMS_PER_PAGE_FOR_ZSC = 2 # Maximum number of teams to process per page
# Fetch page URLs
def get_all_page_urls(base_url_to_scrape):
page_urls = [base_url_to_scrape] # Initialize with the base URL
response = requests.get(base_url_to_scrape) # Fetch content of base URL
soup = BeautifulSoup(response.content, "html.parser") # Parse the HTML content
# Tags for pagination
pagination_links = soup.select("ul.pagination li a")
discovered_urls = set() # Store unique relative URLs to avoid duplicates
for link_tag in pagination_links:
href = link_tag.get("href")
# Ensure the link is a pagination link for this site
if href and href.startswith("?page_num="):
discovered_urls.add(href)
# Sort for consistent order and construct full URLs
for relative_url in sorted(list(discovered_urls)):
full_url = urljoin(base_url_to_scrape, relative_url) # Create absolute URL
# If you want to add paginated URLs, uncomment the next line:
page_urls.append(full_url)
return page_urls
def scrape_page(url):
page_data = [] # List to store data scraped from this page
response = requests.get(url) # Fetch the content of the page
soup = BeautifulSoup(response.content, "html.parser") # Parse the HTML
# Select all table rows with class "team" inside a table with class "table"
table_rows = soup.select("table.table tr.team")
for row in table_rows:
# Extract text from each row (name, year, wins, losses)
team_stats = {
"name": row.select_one("td.name").get_text(strip=True),
"year": row.select_one("td.year").get_text(strip=True),
"wins": row.select_one("td.wins").get_text(strip=True),
"losses": row.select_one("td.losses").get_text(strip=True),
}
page_data.append(team_stats) # Add the scraped team data to the list
return page_data
# Initialize the zero-shot classification pipeline
classifier = pipeline("zero-shot-classification", model="valhalla/distilbart-mnli-12-3")
# Get all URLs to scrape (base URL + paginated URLs)
all_page_urls = get_all_page_urls(BASE_URL)
all_team_data_for_zsc = [] # List to store team data selected for classification
# Loop through the page URLs
for page_url in all_page_urls[:MAX_PAGES_TO_SCRAPE]:
current_page_team_data = scrape_page(page_url) # Scrape data from the current page
# Maximum teams per page to scrape
all_team_data_for_zsc.extend(current_page_team_data[:MAX_TEAMS_PER_PAGE_FOR_ZSC])
# Start classification
print(f"\n--- Classifying {len(all_team_data_for_zsc)} Scraped Hockey Team Snippets ---")
# Loop through the collected team data to classify each one
for i, team_info_dict in enumerate(all_team_data_for_zsc):
name = team_info_dict["name"]
year = team_info_dict["year"]
wins = team_info_dict["wins"]
losses = team_info_dict["losses"]
# Construct a text snippet from the team data for classification
text_snippet = f"Team: {name}, Year: {year}, Wins: {wins}, Losses: {losses}."
print(f"\nData Snippet {i+1}: \"{text_snippet}\"")
# Perform zero-shot classification
result = classifier(text_snippet, CANDIDATE_LABELS, multi_label=False)
# Print the predicted category and its confidence score
print(f"Predicted Category: {result['labels'][0]}")
print(f"Confidence Score: {result['scores'][0]:.4f}")
Très bien ! Vous avez réalisé votre premier projet ZSC.
Exécutez le code avec la commande suivante :
python zsc_scraper.py
C’est le résultat attendu :
Comme vous pouvez le constater, le modèle a correctement classé les données extraites dans l'”enregistrement de données sportives historiques”. Cela n’aurait pas été possible sans la classification “zero-shot”. Mission accomplie !
Conclusion
Dans cet article, vous avez appris ce qu’est la classification “zero-shot” et comment l’appliquer dans un contexte de web scraping. Les données Web sont en constante évolution et vous ne pouvez pas vous attendre à ce qu’un LLM pré-entraîné connaisse tout à l’avance. La ZSC permet de combler cette lacune en classifiant dynamiquement les nouvelles informations sans recyclage.
Cependant, le véritable défi réside dans l’obtention de données fraîches, cartous les sites Web ne sont pas faciles à récupérer. C’est là que Bright Data intervient, en proposant une série d’outils et de services puissants conçus pour surmonter les obstacles liés au scraping. Ces outils et services sont les suivants
- Web Unlocker: Une API qui contourne les protections anti-scraping et fournit du HTML propre à partir de n’importe quelle page web avec un minimum d’effort.
- Navigateur de scraping: Un navigateur contrôlable basé sur le cloud avec un rendu JavaScript. Il gère automatiquement les CAPTCHA, l’empreinte du navigateur, les tentatives, etc. pour vous. Il s’intègre parfaitement à Panther ou Selenium PHP.
- API de grattage du Web: Points d’extrémité pour l’accès programmatique à des données web structurées provenant de dizaines de domaines populaires.
Pour le scénario de l’apprentissage automatique, explorez également notre hub AI.
Inscrivez-vous à Bright Data dès maintenant et commencez votre essai gratuit pour tester nos solutions de scraping !
Aucune carte de crédit requise