Skip to content
Guides7 min read

पूर्ण ओवरलैप से आगे: बड़े डेटासेट के लिए अनुकूली एनोटेटर कवरेज

हर चीज़ पर दोहरी लेबलिंग महँगी पड़ती है; हर चीज़ पर एकल लेबलिंग आपको अंधा बना देती है। Potato 2.6 आपको अधिकांश आइटमों के लिए एक एनोटेटर और एक स्तरीकृत नमूने के लिए तीन एनोटेटर सौंपने देता है, साथ ही अनुकूली बूस्ट और स्वचालित निर्णयन रूटिंग।

Potato Team

किसी भी बड़े एनोटेशन प्रोजेक्ट में एक जानी-पहचानी खींचतान होती है। अगर हर आइटम को दो या तीन एनोटेटर मिलें, तो आप सहमति माप सकते हैं और अपने लेबलों पर भरोसा कर सकते हैं, मगर आपने अपना बजट दो या तीन गुना बढ़ा लिया है। अगर हर आइटम को एक ही एनोटेटर मिले, तो आप उसी पैसे में तीन गुना अधिक डेटा लेबल कर लेते हैं, पर आपको अंदाज़ा ही नहीं रहता कि उनमें से कोई कितना भरोसेमंद है।

जिसने भी कोई अध्ययन चलाया है, उसे यह सामान्य समझौता भली-भाँति पता है: कॉर्पस के अधिकांश हिस्से पर एकल एनोटेशन कीजिए, और गुणवत्ता पर नज़र रखने के लिए एक छोटे नमूने पर दोहरी या तिहरी एनोटेशन कीजिए। समस्या हमेशा यही रही है कि टूलिंग से यह काम साफ़-सुथरे ढंग से करवाया जाए, और फिर ओवरलैप हाथ में आने के बाद उसका कुछ उपयोग किया जाए। Potato 2.6 इस डिज़ाइन को मूल रूप से अंतर्निहित करता है—दो कॉन्फ़िग ब्लॉकों (num_annotators_per_item और per_annotator_quota) के साथ-साथ अनुकूली बूस्ट और निर्णयन रूटिंग के ज़रिए।

यह पोस्ट कवरेज डिज़ाइन को सरल मामले से अनुकूली मामले तक ले जाती है। पूरा संदर्भ विषम कवरेज दस्तावेज़ में मौजूद है।

डिफ़ॉल्ट एकल कवरेज, तीन एनोटेटरों पर एक स्तरीकृत ओवरलैप नमूना, असहमति पर अनुकूली बूस्ट, और निर्णयन रूटिंगPotato में अनुकूली एनोटेटर कवरेज

ओवरलैप नमूने के साथ प्रति-आइटम सीमाएँ

num_annotators_per_item एक समान सीमा के लिए एक अकेला पूर्णांक स्वीकार करता है, या जब आप अलग-अलग आइटमों को अलग-अलग तरह से कवर करना चाहें तो एक संरचित मैपिंग। आम रूप यह है कि डिफ़ॉल्ट एक हो, और एक स्तरीकृत नमूना बढ़ाकर तीन कर दिया जाए:

yaml
num_annotators_per_item:
  default: 1
  overlap_sample:
    fraction: 0.1
    count: 3
    stratify_by: domain
    seed: 42
  min: 1

overlap_sample ब्लॉक आइटमों के एक नियतात्मक उपसमुच्चय पर सीमा बढ़ा देता है। नमूनाकरण स्टार्टअप के समय एक ही बार होता है, और चुने गए आइटमों पर आंतरिक रूप से मुहर लग जाती है ताकि असाइनमेंट तर्क उसके बाद उन्हें उच्च-कवरेज मानकर चले। फ़ील्ड सीधे-सादे हैं: fraction नमूने में लिया गया अनुपात है, count बढ़ाई गई सीमा है (इसे डिफ़ॉल्ट से अधिक होना चाहिए), और seed पुनः-आरंभों के बीच चयन को पुनरुत्पादनीय बनाता है।

जिस ब्योरे पर ठहरना सार्थक है, वह है stratify_by। इसे अपने डेटा के किसी फ़ील्ड (यहाँ domain) की ओर इंगित कीजिए, और अनुपात पूरे पूल पर लागू होने के बजाय प्रति स्तर लागू होता है। हर श्रेणी ओवरलैप नमूने में अनुपात के अनुसार योगदान देती है, इसलिए आप ऐसे नमूने पर सहमति नहीं माप रहे होते जो संयोगवश 90% एक ही डोमेन का हो। अगर आपका कॉर्पस समाचार, सोशल मीडिया और क्लिनिकल टेक्स्ट को मिलाता है, तो हर एक अपने आकार के अनुपात में गुणवत्ता नमूने में नज़र आता है।

अनुकूली बूस्ट: जहाँ कठिन है, वहाँ अधिक खर्च करें

एक स्थिर ओवरलैप नमूना आँख मूँदकर चुना जाता है, इससे पहले कि किसी ने कुछ भी एनोटेट किया हो। मगर जिन आइटमों को दूसरी और तीसरी नज़र की सबसे ज़्यादा ज़रूरत होती है, वे वही हैं जिन पर एनोटेटर वाकई असहमत होते हैं, और वे कौन-से हैं यह आप पहली पास के बाद ही जान पाते हैं। अनुकूली बूस्ट ठीक इसी को संभालता है:

yaml
num_annotators_per_item:
  default: 1
  adaptive:
    enabled: true
    disagreement_threshold: 0.5
    boost_to: 3

जैसे ही किसी आइटम को कम-से-कम दो एनोटेशन मिल जाते हैं और उसका असहमति स्कोर disagreement_threshold को पार कर जाता है, उसकी सीमा बढ़ाकर boost_to कर दी जाती है और आइटम एक और पास के लिए असाइनमेंट क़तार में दोबारा आ जाता है। बूस्ट प्रति आइटम एक ही बार होता है, इसलिए कोई विवादास्पद आइटम बेलगाम होने के बजाय एक ही बार बढ़ाया जाता है। यह ऐसी कवरेज है जो डेटा की कठिनाई का पहले से अनुमान लगाने के बजाय उसका अनुसरण करती है।

प्रति-एनोटेटर कोटा

कवरेज सीमाएँ यह नियंत्रित करती हैं कि हर आइटम को कितने एनोटेटर मिलें। एक अलग ब्लॉक यह नियंत्रित करता है कि हर एनोटेटर को कितने आइटम मिलें, जिसे आप आम तौर पर विशेषज्ञता या अनुबंध के अनुसार बदलना चाहते हैं:

yaml
per_annotator_quota:
  default: 100
  by_user:
    alice: 30
  by_user_role:
    expert: 30
    novice: 200
 
user_roles:
  alice: expert
  carol: novice

समाधान सबसे विशिष्ट से शुरू होकर चलता है: पहले by_user[uid], फिर by_user_role[user_roles[uid]], और अंत में default। इस तरह आप किसी ख़ास विशेषज्ञ को 30 आइटमों पर, बाक़ी हर विशेषज्ञ को भूमिका के अनुसार 30 पर, और नौसिखियों को 200 पर सीमित कर सकते हैं, और ये दोनों प्रणालियाँ ऊपर की प्रति-आइटम सीमाओं में दख़ल नहीं देतीं।

ओवरलैप को निर्णय में बदलना

ओवरलैप इकट्ठा करना काम का बस आधा हिस्सा है; असल बात असहमतियों पर कार्रवाई करना है। निर्णयन ब्लॉक सक्षम होने पर, ओवरलैप-नमूने के जो आइटम अपनी सीमा तक पहुँचते हैं, उन्हें स्वतः स्कोर किया जाता है और जब सहमति आपकी देहली से नीचे गिरती है तो उन्हें एक निर्णयन क़तार में डाल दिया जाता है:

yaml
adjudication:
  enabled: true
  adjudicator_users: [admin]
  min_annotations: 2
  agreement_threshold: 0.75

इसका असर यह होता है कि कम-सहमति वाले आइटम उसी क्षण उभर आते हैं जब नमूना संतृप्त होता है, बजाय इसके कि कोई हाथ से क़तार दोबारा बनाने को याद रखे, इसका इंतज़ार किया जाए। एक निर्णायक क़तार खोलता है और उसे वही आइटम दिखते हैं जो सचमुच विवादित हैं, जिन्हें उस बड़े ढेर से पहले ही छाँट लिया गया है जिस पर सब सहमत थे।

सहमति को पढ़ना

जैसे ही ओवरलैप-नमूने के आइटम संतृप्त होते हैं, सहमति के आँकड़े /admin/iaa पर उपलब्ध हो जाते हैं। यह एंडपॉइंट हर चीज़ पर एक ही संख्या थोपने के बजाय हर स्कीम के प्रकार के अनुकूल मेट्रिक की गणना करता है: नाममात्र (nominal) स्कीमों के लिए Cohen's और Fleiss' kappa, क्रमिक (ordinal) के लिए weighted kappa, और स्पैन के लिए टोकन-स्तरीय kappa के साथ span F1। यह मायने रखता है क्योंकि अगर आपकी क्रमिक Likert रेटिंग्स को अनियत श्रेणियों जैसा मानकर κ निकाला जाए, तो वह वास्तविक सहमति को कम आँकेगा।

इसे आज़माना

रिलीज़ के साथ एक चलने-योग्य प्रदर्शन शामिल आता है। रिपॉज़िटरी की जड़ से:

bash
python potato/flask_server.py start examples/advanced/heterogeneous-coverage/config.yaml -p 8000

यह दो डोमेन में फैले 20 आइटमों का उपयोग करता है, डोमेन के अनुसार स्तरीकृत करके 20% को तीन-एनोटेटर ओवरलैप के लिए नमूना लेता है, 0.5 देहली पर एक अनुकूली बूस्ट सक्षम करता है, दो विशेषज्ञता-स्तर परिभाषित करता है, और कम-सहमति वाले आइटमों को निर्णयन की ओर रूट करता है: ऊपर दिया गया पूरा डिज़ाइन, आदि से अंत तक।

एक अच्छी कवरेज योजना का स्वरूप

सब मिलाकर, यह डिज़ाइन आपको यह तय करने देता है कि आपका एनोटेशन बजट कहाँ जाए, बजाय इसके कि उसे एकसमान फैला दिया जाए। अधिकांश आइटमों को एक पास मिलता है। एक स्तरीकृत टुकड़े को तीन पास मिलते हैं, ताकि आप पूरे कॉर्पस पर विश्वसनीयता की रिपोर्ट दे सकें, न कि उसके केवल एक कोने पर। जो आइटम सचमुच कठिन निकलते हैं, वे स्वतः बढ़ाए जाते हैं, और विवादित आइटम एक निर्णायक की ओर रूट होते हैं। आप सबसे अनिश्चित डेटा पर सबसे ज़्यादा खर्च करते हैं, और हर कवरेज निर्णय का बचाव किसी विधि (methods) खंड में कर सकते हैं।

किसी दिए गए कार्य के लिए आपको वास्तव में कितने एनोटेटर चाहिए, यह अपने आप में एक अलग सवाल है; आपको कितने एनोटेटर चाहिए पोस्ट अनुभव-आधारित नियमों को खँगालती है। यह रिलीज़ इस बारे में है कि आप जिस भी उत्तर पर पहुँचें, उसे व्यक्त करना आसान बना दिया जाए। विषम कवरेज Potato 2.6 में शामिल आती है; ऊपर के ब्लॉक जो कुछ कर सकते हैं उस सब के लिए विषम कवरेज दस्तावेज़ और कार्य असाइनमेंट संदर्भ देखें।