Skip to content
Guides8 min read

Crowdsourced एनोटेशन में गुणवत्ता नियंत्रण

एनोटेशन परियोजनाओं में गुणवत्ता बनाए रखने के व्यावहारिक तरीक़े, जिनमें Potato के भीतर और उसके बाहर, दोनों जगह अपनाई जा सकने वाली रणनीतियाँ शामिल हैं।

Potato Team

काम के एनोटेशन और शोर के बीच का फ़र्क़ गुणवत्ता नियंत्रण ही तय करता है। यह मार्गदर्शिका उन तरीक़ों को समेटती है जो crowdsourced और भीतरी, दोनों तरह की एनोटेशन परियोजनाओं में असल में टिकते हैं। इनके पीछे की सुविधाओं के लिए गुणवत्ता नियंत्रण दस्तावेज़ देखें।

परियोजना की पूरी अवधि में गुणवत्ता नियंत्रण: एनोटेशन से पहले, उसके दौरान, और बाद की जाँचेंसमय के साथ गुणवत्ता नियंत्रण

गुणवत्ता नियंत्रण का खाका

अकेली कोई जाँच काफ़ी नहीं पड़ती, इसलिए ज़्यादातर परियोजनाएँ कई परतें एक साथ लगाती हैं:

  1. Attention check: यह पक्का करना कि एनोटेटर कार्य में लगे हुए हैं
  2. दोहराव: हर आइटम पर एक से ज़्यादा एनोटेशन इकट्ठा करना
  3. सहमति के माप: एनोटेटरों के बीच एकरूपता नापना
  4. प्रशिक्षण और दिशानिर्देश: यह सुनिश्चित करना कि एनोटेटर कार्य समझ चुके हैं
  5. मैनुअल समीक्षा: नमूना लेकर एनोटेशन की गुणवत्ता जाँचना

Surveyflow से attention check

Potato में बुनियादी attention check surveyflow के ज़रिए होते हैं। आप एनोटेशन के बैचों के बीच सर्वे पेज डाल सकते हैं जो एनोटेटर से पुष्टि माँगें कि वे ध्यान दे रहे हैं।

yaml
annotation_task_name: "Sentiment Annotation with Checks"
 
surveyflow:
  on: true
  order:
    - survey_instructions
    - annotation
    - survey_attention_check
    - annotation
    - survey_completion

attention check के सवाल एक सर्वे पेज के रूप में परिभाषित कीजिए:

yaml
# In your surveyflow survey definitions
survey_attention_check:
  - question: "To confirm you're paying attention, please select 'Strongly Agree'."
    type: radio
    options:
      - Strongly Disagree
      - Disagree
      - Neutral
      - Agree
      - Strongly Agree

Potato में attention check का अपना समर्थन सीमित है। अगर आपको अपने आप विफलता पकड़नी है, एनोटेटर हटाने हैं, या इस तरह का कोई तर्क चाहिए, तो या तो post-processing स्क्रिप्ट लिखनी पड़ेंगी या अपने crowdsourcing प्लेटफ़ॉर्म की गुणवत्ता सुविधाएँ इस्तेमाल करनी पड़ेंगी।

दोहराव: हर आइटम पर कई एनोटेशन

हर आइटम पर कई एनोटेशन इकट्ठा करना गुणवत्ता नियंत्रण के भरोसेमंद तरीक़ों में से है। इसे अपने डेटा सेटअप में कॉन्फ़िगर कीजिए:

yaml
annotation_task_name: "Multi-Annotator Sentiment Task"
 
data_files:
  - path: data.json
    list_as_text: false
    sampling: random
 
# Control how many annotators see each item through assignment logic
# This is typically managed through your annotator assignment system

Prolific जैसे crowdsourcing प्लेटफ़ॉर्म पर आप:

  • एक ही HIT कई बार पोस्ट करके दोहराए हुए एनोटेशन ले सकते हैं
  • एक ही डेटा पर worker के अलग-अलग बैच लगा सकते हैं
  • अपनी डेटा पाइपलाइन में असाइनमेंट का अपना तर्क लिख सकते हैं

एनोटेटरों के बीच सहमति नापना

सहमति की गणना Potato ख़ुद कर देता है। agreement_metrics: enabled: true सेट कीजिए और जैसे-जैसे एनोटेशन आते जाएँगे, admin डैशबोर्ड में Krippendorff's alpha दिखने लगेगा। नीचे का कोड फिर भी जानने लायक़ है, उन मौक़ों के लिए जब आपको ऐसा कोई माप चाहिए जो Potato नहीं देता, या जब आप एक्सपोर्ट किए हुए डेटासेट का विश्लेषण कर रहे हों:

Cohen's Kappa (दो एनोटेटर)

दो एनोटेटर वाले श्रेणीबद्ध एनोटेशन के लिए:

python
from sklearn.metrics import cohen_kappa_score
 
# After collecting annotations
annotator1_labels = ["Positive", "Negative", "Positive", ...]
annotator2_labels = ["Positive", "Negative", "Neutral", ...]
 
kappa = cohen_kappa_score(annotator1_labels, annotator2_labels)
print(f"Cohen's Kappa: {kappa:.3f}")

Fleiss' Kappa (कई एनोटेटर)

तीन या उससे ज़्यादा एनोटेटर के लिए:

python
from statsmodels.stats.inter_rater import fleiss_kappa
import numpy as np
 
# Build a matrix of label counts per item
# Each row is an item, each column is a label category
ratings_matrix = np.array([
    [3, 0, 0],  # Item 1: 3 Positive, 0 Negative, 0 Neutral
    [2, 1, 0],  # Item 2: 2 Positive, 1 Negative, 0 Neutral
    [0, 0, 3],  # Item 3: 0 Positive, 0 Negative, 3 Neutral
    ...
])
 
kappa = fleiss_kappa(ratings_matrix)
print(f"Fleiss' Kappa: {kappa:.3f}")

व्याख्या के दिशानिर्देश

Kappa का मानव्याख्या
< 0.20कमज़ोर सहमति
0.21 - 0.40ठीक-ठाक सहमति
0.41 - 0.60मध्यम सहमति
0.61 - 0.80अच्छी-ख़ासी सहमति
0.81 - 1.00लगभग पूर्ण सहमति

एनोटेशन की गुणवत्ता बनाए रखने के लिए Potato में attention check, gold आइटम, और एनोटेटरों के बीच सहमति पर नज़र रखने की सुविधा है:

Potato में Likert पैमाने का गुणवत्ता नियंत्रण

Gold standard आइटम

Gold standard आइटम वे पहले से लेबल किए हुए आइटम हैं जिनका सही जवाब आपको पता होता है और जिन्हें आप अपने डेटा में मिला देते हैं। इनसे वे एनोटेटर पकड़ में आते हैं जो अंदाज़े से काम चला रहे हैं या ध्यान नहीं दे रहे।

Gold आइटम बनाना

  1. ऐसे आइटम का एक सेट बनाइए जिनका सही जवाब साफ़ और बेझिझक तय हो
  2. इन आइटम पर विशेषज्ञों से लेबल लगवाइए
  3. इन्हें अपने आम एनोटेशन डेटा में मिला दीजिए
json
[
  {
    "id": "gold_001",
    "text": "I absolutely love this product! Best purchase ever!",
    "is_gold": true,
    "gold_label": "Positive"
  },
  {
    "id": "gold_002",
    "text": "This is terrible. Complete waste of money. Worst experience.",
    "is_gold": true,
    "gold_label": "Negative"
  },
  {
    "id": "regular_001",
    "text": "The product arrived on time and works as expected.",
    "is_gold": false
  }
]

Gold पर प्रदर्शन का विश्लेषण

डेटा इकट्ठा हो जाने के बाद देखिए कि हर एनोटेटर ने gold आइटम पर कैसा किया:

python
import json
 
def calculate_gold_accuracy(annotations_file, gold_labels):
    with open(annotations_file) as f:
        annotations = json.load(f)
 
    annotator_scores = {}
 
    for item_id, item_annotations in annotations.items():
        if item_id in gold_labels:
            expected = gold_labels[item_id]
            for annotator, label in item_annotations.items():
                if annotator not in annotator_scores:
                    annotator_scores[annotator] = {'correct': 0, 'total': 0}
                annotator_scores[annotator]['total'] += 1
                if label == expected:
                    annotator_scores[annotator]['correct'] += 1
 
    for annotator, scores in annotator_scores.items():
        accuracy = scores['correct'] / scores['total']
        print(f"{annotator}: {accuracy:.1%} gold accuracy")
 
    return annotator_scores

समय से मिलने वाले गुणवत्ता के संकेत

Potato आउटपुट फ़ाइलों में एनोटेशन का समय दर्ज करता है। इस डेटा से संदिग्ध रूप से कमज़ोर एनोटेशन चिह्नित कीजिए:

समय के डेटा का विश्लेषण

python
import json
from statistics import mean, stdev
 
def analyze_timing(annotations_file):
    with open(annotations_file) as f:
        data = json.load(f)
 
    times = []
    for item in data.values():
        if 'time_spent' in item:
            times.append(item['time_spent'])
 
    avg_time = mean(times)
    std_time = stdev(times)
 
    # Flag annotations that are too fast (< 2 std below mean)
    threshold = max(avg_time - 2 * std_time, 2)  # At least 2 seconds
 
    flagged = [t for t in times if t < threshold]
    print(f"Average time: {avg_time:.1f}s")
    print(f"Flagged as too fast: {len(flagged)} items")

प्लेटफ़ॉर्म के स्तर पर गुणवत्ता नियंत्रण

crowdsourcing प्लेटफ़ॉर्म इस्तेमाल कर रहे हों तो उनकी अपनी गुणवत्ता सुविधाएँ काम में लाइए:

Prolific

  • prescreening फ़िल्टर लगाइए (approval rate, पिछले अध्ययन)
  • कम से कम कितने समय में काम पूरा हो, यह तय कीजिए
  • अपने pre-survey में attention check के सवाल रखिए
  • भुगतान मंज़ूर करने से पहले जमा किए गए काम की समीक्षा कीजिए

MTurk

  • कम से कम इतनी HIT approval rate माँगिए (>95%)
  • qualification test इस्तेमाल कीजिए
  • तय शर्तों पर अपने आप मंज़ूरी/अस्वीकृति सेट कीजिए
  • गुणवत्ता जाँच में विफल worker को ब्लॉक कीजिए

बाद में की जाने वाली गुणवत्ता जाँच

इकट्ठा किए गए डेटा पर स्वचालित जाँचें चलाइए:

python
def quality_check_annotations(annotations_file):
    with open(annotations_file) as f:
        data = json.load(f)
 
    issues = []
 
    for annotator_id, items in group_by_annotator(data).items():
        labels = [item['label'] for item in items]
 
        # Check for single-label bias (always selecting same option)
        unique_labels = set(labels)
        if len(unique_labels) == 1 and len(labels) > 10:
            issues.append(f"{annotator_id}: Only used label '{labels[0]}'")
 
        # Check for position bias (always selecting first option)
        # Requires knowing option order in your schema
 
        # Check for very fast submissions
        times = [item.get('time_spent', 0) for item in items]
        avg_time = sum(times) / len(times) if times else 0
        if avg_time < 3:
            issues.append(f"{annotator_id}: Average time only {avg_time:.1f}s")
 
    return issues

बेहतर तरीक़े

असली एनोटेशन शुरू होने से पहले एनोटेटरों को Potato के training phase से गुज़ारिए। दिशानिर्देश साफ़ लिखिए, क्योंकि गोलमोल दिशानिर्देश ऐसी असहमति पैदा करते हैं जिसका एनोटेटर की गुणवत्ता से कोई लेना-देना नहीं होता। बड़े पैमाने पर उतरने से पहले एक छोटा pilot चलाइए ताकि दिक़्क़तें पहले ही सामने आ जाएँ। एक ही जाँच पर टिके रहने के बजाय कई मिलाइए: attention check, gold standard और दोहराव, तीनों अलग-अलग चीज़ें पकड़ते हैं। शुरुआत ढीली सीमाओं से कीजिए और असली डेटा देखने के बाद उन्हें कसिए। जहाँ मुमकिन हो, एनोटेटरों को फ़ीडबैक दीजिए। नज़र बनाए रखिए, क्योंकि लोग थकते हैं और गुणवत्ता खिसकती जाती है। और असामान्य मामलों को आप कैसे निपटाते हैं, यह लिखकर रखिए ताकि फ़ैसले एक जैसे रहें।

ख़ास तौर पर onboarding का क़दम सेट करने के लिए training phase का दस्तावेज़ देखें।

सारांश

एनोटेशन का गुणवत्ता नियंत्रण परतों में सबसे अच्छा काम करता है:

रणनीतिकैसे लागू करेंजाँच कब हो
Attention checkSurveyflow सर्वेएनोटेशन के दौरान
Gold standardडेटा में मिलाकरडेटा जुटने के बाद
दोहरावहर आइटम पर कई एनोटेटरडेटा जुटने के बाद
सहमति के मापPython स्क्रिप्टडेटा जुटने के बाद
समय का विश्लेषणएनोटेशन के timestampडेटा जुटने के बाद
प्लेटफ़ॉर्म की सुविधाएँProlific/MTurk सेटिंगडेटा जुटने से पहले/दौरान

इसमें से ज़्यादातर विश्लेषण डेटा जुटने के बाद, post-processing स्क्रिप्ट से होता है। वह पाइपलाइन कुछ भी इकट्ठा करने से पहले तय कर लीजिए, ताकि जो फ़ील्ड आगे चाहिए वे असल में दर्ज भी हों।

अगले क़दम


एनोटेशन वर्कफ़्लो पर और जानकारी के लिए annotation schemes का दस्तावेज़ देखें।