Créer une tâche d'analyse de sentiment
Construisez une tâche complète de classification de sentiment avec des boutons radio, des infobulles et des raccourcis clavier pour un étiquetage efficace.
L'analyse de sentiment est l'une des tâches de NLP les plus courantes, et collecter des étiquettes propres pour cette tâche dans Potato est simple. Ce tutoriel construit une interface d'annotation de sentiment que vous pouvez réellement mettre entre les mains des annotateurs, avec les raccourcis clavier et les contrôles qualité qui accélèrent l'étiquetage.
Aperçu du projet
Nous annotons des publications de réseaux sociaux. L'interface comprend :
- Une classification de sentiment en trois classes (Positive, Negative, Neutral)
- Une note de confiance pour chaque annotation
- Des explications textuelles optionnelles
- Des raccourcis clavier pour aller plus vite
- Des mesures de contrôle qualité
Configuration complète
Voici le fichier config.yaml complet :
annotation_task_name: "Social Media Sentiment Analysis"
# Data configuration
data_files:
- "data/tweets.json"
item_properties:
id_key: id
text_key: text
# Annotation interface
annotation_schemes:
# Primary sentiment label
- annotation_type: radio
name: sentiment
description: "What is the overall sentiment of this post?"
labels:
- name: Positive
tooltip: "Expresses happiness, satisfaction, or approval"
key_value: "1"
- name: Negative
tooltip: "Expresses sadness, frustration, or disapproval"
key_value: "2"
- name: Neutral
tooltip: "Factual, objective, or lacks emotional content"
key_value: "3"
label_requirement:
required: true
# Confidence rating
- annotation_type: likert
name: confidence
description: "How confident are you in your sentiment label?"
size: 5
min_label: "Not confident"
max_label: "Very confident"
label_requirement:
required: true
# Optional explanation
- annotation_type: text
name: explanation
description: "Why did you choose this label? (Optional)"
rows: 4
label_requirement:
required: false
placeholder: "Explain your reasoning..."
# Guidelines
annotation_instructions: |
## Sentiment Annotation Guidelines
### Your Task
Classify the sentiment expressed in each social media post.
### Labels
**Positive**: The author expresses positive emotions or opinions
- Happiness, excitement, gratitude
- Praise, recommendations, approval
- Examples: "Love this!", "Best day ever!", "Highly recommend"
**Negative**: The author expresses negative emotions or opinions
- Anger, frustration, sadness
- Complaints, criticism, disapproval
- Examples: "Terrible service", "So disappointed", "Worst experience"
**Neutral**: Factual or lacking clear sentiment
- News, announcements, questions
- Mixed or balanced opinions
- Examples: "The store opens at 9am", "Has anyone tried this?"
### Tips
- Focus on the author's sentiment, not the topic
- Sarcasm should be labeled based on intended meaning
- When unsure, lower your confidence rating
# User management
automatic_assignment:
on: true
sampling_strategy: random
labels_per_instance: 1
instance_per_annotator: 100Format des données d'exemple
Créez data/tweets.json :
{"id": "t001", "text": "Just got my new laptop and I'm absolutely loving it! Best purchase of the year! #happy"}
{"id": "t002", "text": "Waited 2 hours for customer service and they still couldn't help me. Never shopping here again."}
{"id": "t003", "text": "The new coffee shop on Main Street opens tomorrow at 7am."}
{"id": "t004", "text": "This movie was okay I guess. Some good parts, some boring parts."}
{"id": "t005", "text": "Can't believe how beautiful the sunset was tonight! Nature is amazing."}Lancer la tâche
Démarrez le serveur d'annotation :
potato start config.yamlOuvrez http://localhost:8000 et connectez-vous pour commencer à annoter.
Voici ce que voient vos annotateurs une fois le serveur lancé :
L'interface de classification de sentiment avec les étiquettes en boutons radio, l'échelle de confiance et le champ d'explication optionnel
Comprendre l'interface
Zone d'annotation principale
L'interface affiche :
- Le texte à annoter (avec les URLs, mentions et hashtags surlignés)
- Les boutons radio de sentiment avec infobulles
- L'échelle de Likert de confiance
- La zone de texte d'explication optionnelle
Flux de travail au clavier
Une fois que les annotateurs ont pris le rythme, la boucle la plus rapide est la suivante :
- Lire le texte
- Appuyer sur
1,2ou3pour le sentiment - Cliquer sur le niveau de confiance (ou utiliser la souris)
- Appuyer sur
Enterpour soumettre
Suivi de la progression
L'interface affiche :
- La progression actuelle (par ex. « 15 / 100 »)
- Le temps restant estimé
- Les statistiques de session
Format de sortie
Le travail de chaque annotateur est enregistré dans <output_annotation_dir>/<user>/user_state.json, quelle que soit la valeur de export_annotation_format. Ce paramètre ajoute un export périodique à côté, de sorte qu'avec jsonl le fichier combiné est <output_annotation_dir>/exports/jsonl/annotations.jsonl, avec un enregistrement par annotateur et par instance :
{
"instance_id": "t001",
"user_id": "john_doe",
"labels": {
"sentiment": {"Positive": "true"},
"confidence": {"5": "true"},
"explanation": {"text_box": "Clear expression of happiness with the purchase"}
},
"spans": {},
"links": {}
}Ajouter un contrôle qualité
Vérifications d'attention
Ajoutez des items de référence (gold standard) pour vérifier l'attention des annotateurs. Pour l'ensemble des options des schémas radio et likert utilisés ici, consultez la documentation source.
attention_checks:
enabled: true
frequency: 10 # Every 10th item
items_file: data/attention_checks.json
failure_handling:
warn_threshold: 2
block_threshold: 5Les items se trouvent dans items_file plutôt que directement dans la configuration, et chacun porte la réponse qu'il doit recevoir :
[
{
"id": "chk1",
"text": "I am extremely happy and satisfied! This is the best!",
"expected_answer": { "sentiment": "Positive" }
},
{
"id": "chk2",
"text": "This is absolutely terrible and I hate it completely.",
"expected_answer": { "sentiment": "Negative" }
}
]Les items gold standard utilisent gold_label au lieu de expected_answer et se placent dans gold_standards.items_file. Notez que les deux blocs se placent au niveau supérieur. Potato lit attention_checks à la racine de la configuration, donc le glisser dans un bloc quality_control: fait qu'il n'est pas lu, sans qu'aucune erreur ne soit signalée.
Accord inter-annotateurs
Pour les projets de recherche, activez les annotations multiples :
automatic_assignment:
on: true
sampling_strategy: random
labels_per_instance: 3 # Each item annotated by 3 people
instance_per_annotator: 50Analyser les résultats
Exportez et analysez vos annotations :
import json
from collections import Counter
records = []
with open('annotation_output/exports/jsonl/annotations.jsonl') as f:
for line in f:
records.append(json.loads(line))
def chosen(record, scheme):
"""The label picked for a single-choice scheme: the key whose value is "true"."""
for name, value in record["labels"].get(scheme, {}).items():
if value == "true":
return name
return None
sentiments = Counter(chosen(r, "sentiment") for r in records)
print(f"Sentiment distribution: {dict(sentiments)}")
# A likert stores its scale position the same way, as the label name
points = [int(p) for r in records if (p := chosen(r, "confidence"))]
print(f"Average confidence: {sum(points)/len(points):.2f}")Prochaines étapes
- Configurez le crowdsourcing pour l'annotation à grande échelle
- Ajoutez des suggestions IA pour accélérer l'étiquetage
- Mettez en place l'apprentissage actif pour prioriser les cas difficiles
Découvrez d'autres types d'annotation dans notre documentation.