Home▸Articles▸Data-Centric AI and Dataset Quality

Data Labeling

Building high-quality labeled datasets - annotation workflows, quality control, consensus methods, and active learning.

mysimulator teamUpdated 2026-01≈ 6 min read▶ Open the simulation

Data labeling creates the ground truth that ML models learn from. Label quality directly determines model quality - garbage in, garbage out. Effective labeling requires clear guidelines, quality control processes, and often iterative refinement. For many projects, improving labels yields more gains than improving models.

Where It Is Used

Data labeling powers supervised learning across domains:

Industry: Data labeling market is $1B+ and growing rapidly.

Types of Labels

Type Description Example
Classification Single label per item Spam / not spam
Multi-label Multiple labels per item Image tags
Bounding box Object location Object detection
Polygon/Segmentation Pixel-level boundaries Instance segmentation
Keypoints Landmark locations Pose estimation
Sequence labeling Labels per token NER
Pairwise Relationship between items Similarity judgments
Ranking Ordering of items Search relevance

Typical Data You Will See

Aspect Typical Values
Dataset size 1K to 10M items
Labels per item 1 to 100+ (for complex tasks)
Annotators per item 1 to 5 (for quality)
Agreement rate 70% to 95%
Cost per label $0.01 to $10+

Labeling sources: - Crowdsourcing: MTurk, Scale, Labelbox workers - Internal teams: Domain experts, QA teams - Synthetic: Rule-based, model-generated - Weak supervision: Programmatic labeling functions

What You Do in Practice

  1. Define the task clearly - What exactly should be labeled?
  2. Create annotation guidelines - Detailed instructions with examples
  3. Build annotation interface - Tools that make labeling efficient
  4. Pilot and iterate - Test with small batch, refine guidelines
  5. Train annotators - Qualification tests, feedback loops
  6. Implement quality control - Consensus, review, metrics
  7. Scale labeling - Crowdsource or hire team
  8. Aggregate labels - Combine multiple annotators
  9. Analyze disagreements - Understand edge cases
  10. Continuous improvement - Update guidelines as needed

Baseline First

Start with clear guidelines and simple quality checks:

# Simple majority voting for label aggregation
def majority_vote(annotations):
    """
    annotations: list of labels from different annotators
    """
    from collections import Counter
    counts = Counter(annotations)
    return counts.most_common(1)[0][0]

# Inter-annotator agreement
def cohens_kappa(annotator1, annotator2):
    """Measure agreement between two annotators."""
    from sklearn.metrics import cohen_kappa_score
    return cohen_kappa_score(annotator1, annotator2)

# Quality score per annotator
def annotator_accuracy(annotator_labels, gold_labels):
    """Compare annotator to gold standard."""
    matches = sum(a == g for a, g in zip(annotator_labels, gold_labels))
    return matches / len(gold_labels)

Why start simple: - Guidelines are the bottleneck, not tools - Pilot testing reveals issues early - Simple aggregation often sufficient - Focus on clarity over complexity

Annotation Guidelines Best Practices

Structure of good guidelines: 1. Task definition (what are we labeling?) 2. Label definitions (what does each label mean?) 3. Examples (clear positive and negative examples) 4. Edge cases (how to handle ambiguous situations) 5. Decision tree (if unsure, follow this process)

# Sentiment Classification Guidelines

## Task
Label customer reviews as Positive, Negative, or Neutral.

## Definitions
- **Positive**: Customer expresses satisfaction, recommends product
- **Negative**: Customer expresses dissatisfaction, complaints
- **Neutral**: Factual description without clear sentiment

## Examples
### Positive
- "Love this product! Works great." ✓
- "Better than expected, would buy again." ✓

### Negative
- "Broke after one week, very disappointed." ✓
- "Would not recommend, waste of money." ✓

### Neutral
- "Arrived in 3 days. Standard packaging." ✓
- "Product as described." ✓

## Edge Cases
- Mixed sentiment ("Good quality but expensive") → Label dominant sentiment
- Sarcasm ("Great, another broken product") → Label true sentiment (Negative)
- Questions ("Does this work with iPhone?") → Neutral

Quality Control Methods

Consensus labeling:

def consensus_label(annotations, threshold=0.7):
    """Require agreement above threshold."""
    from collections import Counter
    counts = Counter(annotations)
    total = len(annotations)
    top_label, top_count = counts.most_common(1)[0]

    if top_count / total >= threshold:
        return top_label, 'consensus'
    else:
        return None, 'needs_review'

Gold standard questions:

class QualityChecker:
    def __init__(self, gold_questions):
        # Known correct answers for validation
        self.gold = gold_questions  # {item_id: correct_label}
        self.annotator_scores = {}

    def check_annotator(self, annotator_id, responses):
        correct = sum(
            responses.get(item_id) == label
            for item_id, label in self.gold.items()
            if item_id in responses
        )
        total = len([i for i in self.gold if i in responses])
        score = correct / total if total > 0 else 0

        self.annotator_scores[annotator_id] = score
        return score

    def filter_low_quality(self, threshold=0.8):
        return [a for a, s in self.annotator_scores.items() if s < threshold]

Dawid-Skene for label aggregation:

# Probabilistic model accounting for annotator reliability
# Use: pip install crowd-kit
from crowdkit.aggregation import DawidSkene

# df with columns: worker, task, label
aggregator = DawidSkene()
aggregated_labels = aggregator.fit_predict(df)

Active Learning for Efficient Labeling

Label the most informative examples first:

from sklearn.ensemble import RandomForestClassifier
import numpy as np

class ActiveLearner:
    def __init__(self, model):
        self.model = model
        self.labeled_X = []
        self.labeled_y = []

    def select_next_batch(self, unlabeled_X, batch_size=10):
        if len(self.labeled_X) == 0:
            # Random selection initially
            return np.random.choice(len(unlabeled_X), batch_size, replace=False)

        # Train on current labels
        self.model.fit(np.array(self.labeled_X), np.array(self.labeled_y))

        # Uncertainty sampling: select most uncertain
        probs = self.model.predict_proba(unlabeled_X)
        uncertainty = 1 - np.max(probs, axis=1)

        return np.argsort(uncertainty)[-batch_size:]

    def add_labels(self, X, y):
        self.labeled_X.extend(X)
        self.labeled_y.extend(y)

Evaluation and Metrics

Metric Description Target
Inter-annotator agreement Kappa, Fleiss' Kappa > 0.7
Gold standard accuracy Agreement with experts > 0.9
Label coverage % of data labeled Task-dependent
Time per label Efficiency Minimize
Rework rate Labels needing correction < 10%

Failure Modes and Debugging Checklist

Production Checklist

Before labeling: - [ ] Clear task definition - [ ] Comprehensive guidelines with examples - [ ] Annotation interface tested - [ ] Pilot batch completed - [ ] Guidelines refined based on pilot - [ ] Annotator training materials ready

During labeling: - [ ] Quality metrics monitored - [ ] Gold questions embedded - [ ] Disagreements reviewed - [ ] Guidelines updated as needed - [ ] Annotator feedback collected - [ ] Progress tracked

After labeling: - [ ] Final quality audit - [ ] Label aggregation applied - [ ] Edge cases documented - [ ] Dataset versioned - [ ] Documentation complete

Tools and Stack

Category Tools
Platforms Labelbox, Scale AI, Label Studio, Prodigy
Crowdsourcing MTurk, Toloka, Appen
Quality crowd-kit, snorkel
Active learning modAL, ALiPy
Versioning DVC, LakeFS

Example Mini-Case

Scenario: E-commerce needs product category labels for 100K items.

Approach: 1. Define 50 product categories with clear guidelines 2. Pilot with 500 items, 3 annotators each 3. Measure agreement: Fleiss' Kappa = 0.65 (needs improvement) 4. Refine guidelines, add examples for confusing categories 5. Re-pilot: Kappa = 0.82 (acceptable) 6. Scale to full dataset with 2 annotators per item 7. Use Dawid-Skene aggregation for final labels 8. Expert review of low-confidence items

Results: - Total items labeled: 100K - Avg annotators per item: 2.3 - Final agreement: 85% - Expert review needed: 8% - Cost: $0.15 per item

Key learnings: - Pilot phase prevented major rework - Category hierarchy reduced confusion - Active learning reduced labeling by 30% - Regular calibration sessions maintained quality

Related Pages

Further Reading

Try it live

Everything above runs in your browser — open Dataset Label Quality Simulator and change the parameters while it is running. Nothing is installed, nothing is uploaded, the whole model lives in one tab.

▶ Open Dataset Label Quality Simulator simulation

What did you find?

Add reproduction steps (optional)