Skip to content

تعليق النطاقات

تحديد نطاقات النص وتصنيفها في Potato للتعرّف على الكيانات المسماة، مع ألوان لكل تصنيف واختصارات لوحة المفاتيح والتلميحات والنطاقات غير المتصلة.

يتيح تعليق النطاقات للمُعلّقين تحديد أجزاء من النص وتصنيفها، وبه تُبنى في Potato مهام التعرّف على الكيانات المسماة (NER) ووسم أقسام الكلام وتظليل النص. يُكتب التصنيف إما سلسلةً نصية بسيطة وإما كائنًا يحمل color وkey_value وtooltip الخاصة به. يقرأ Potato هذه الثلاثة بوصفها خصائص لكل تصنيف، لذا فإن خريطة colors أو key_values أو tooltips على مستوى المخطط لا أثر لها في مخطط النطاقات.

واجهة تعليق النطاقات مع تظليل الكياناتتعليق النطاقات مع تصنيفات كيانات ملوّنة في Potato

الإعداد الأساسي

yaml
annotation_schemes:
  - annotation_type: span
    name: entities
    description: "Highlight named entities in the text"
    labels:
      - PERSON
      - ORGANIZATION
      - LOCATION

الحقل description مطلوب في كل مخطط، ويظهر فوق أزرار التصنيفات بوصفه التعليمات التي يقرؤها المُعلّق، لذا ينبغي أن يصف قرار التصنيف المطلوب بدلًا من تكرار اسم المخطط. أما التصنيفات المكتوبة سلاسلَ نصية بسيطة فتأخذ ألوانها من لوحة ألوان Potato بترتيب ورودها في القائمة.

خيارات الإعداد

تصنيفات الكيانات

مجموعة التصنيفات هي قرار التصميم الأهم في مهمة النطاقات، لأن الاستدعاء والاتفاق وكل قياس لاحق تُعرَّف كلها بالنسبة إليها. اجعلها صغيرة بما يكفي ليحفظها المُعلّقون دون الرجوع إلى الإرشادات عند كل نطاق، وهذا يعني عمليًا من أربعة إلى ثمانية أنواع في معظم أعمال NER. أضف التصنيفات إلى المخطط السابق:

yaml
labels:
  - PERSON
  - ORGANIZATION
  - LOCATION
  - DATE
  - EVENT

الألوان

يعيّن Potato لكل تصنيف لونًا من لوحة الألوان بترتيب القائمة، لذا لا تستحق كتابة الألوان صراحةً إلا حين يهمّ اقتران بعينه، كنوعين يظهران كثيرًا في الجملة نفسها وينبغي ألا يسهل الخلط بينهما للوهلة الأولى. اللون خاصية للتصنيف:

yaml
annotation_schemes:
  - annotation_type: span
    name: entities
    description: "Highlight named entities in the text"
    labels:
      - name: PERSON
        color: "#3b82f6"
      - name: ORGANIZATION
        color: "#10b981"
      - name: LOCATION
        color: "#f59e0b"
      - DATE

القيم إما بصيغة hex (#3b82f6) وإما rgb(255, 0, 0). والتصنيف المتروك سلسلةً نصية بسيطة، مثل DATE أعلاه، يأخذ اللون التالي من اللوحة، فيمكن للمخطط أن يحدد ألوان التصنيفات التي تحتاج إليها ويترك البقية كما هي.

ويمكن أيضًا ضبط ألوان عدة مخططات في موضع واحد، تحت ui.label_colors، مفهرسةً باسم المخطط ثم بالتصنيف:

yaml
ui:
  label_colors:
    entities:
      PERSON: "#3b82f6"
      ORGANIZATION: "#10b981"

خريطة colors: المكتوبة داخل المخطط نفسه ليست مفتاحًا يقرؤه Potato. والمخطط الذي يحملها يُعرض بألوان اللوحة كأن الكتلة غير موجودة.

اختصارات لوحة المفاتيح

يستحق تفعيل الاختصارات في أي مهمة نطاقات فيها أكثر من تصنيفين، لأن المُعلّق الذي يحرّك الفأرة إلى زر عند كل نطاق يعمل بجزء يسير من سرعة من يُبقي يديه كلتيهما على النص. ضبط sequential_key_binding: true يمنح التصنيفات مفاتيح بترتيب ورودها في القائمة:

yaml
- annotation_type: span
  name: entities
  description: "Highlight named entities in the text"
  labels:
    - PERSON
    - ORGANIZATION
    - LOCATION
    - DATE
  sequential_key_binding: true

حين تضم المهمة عدة مخططات في الصفحة، يخصّص Potato لكل منها مفاتيح من مجموعة منفصلة، فيأخذ صف الأرقام أولًا، ثم صف الحروف العلوي، ثم الصف الأوسط، فلا تتعارض اختصارات المخططات المختلفة أبدًا.

ولتثبيت تصنيف على مفتاح بعينه بدلًا من موضعه في القائمة، أعطِ التصنيف key_value. يلتزم المُخصِّص بقيمة key_value الصريحة قبل أن يعيّن أي شيء تلقائيًا، وتبقى المفاتيح التذكيرية صالحة بعد إعادة ترتيب قائمة التصنيفات لاحقًا، وهو ما لا يحدث مع المفاتيح المعتمدة على الموضع:

yaml
- annotation_type: span
  name: entities
  description: "Highlight named entities in the text"
  labels:
    - name: PERSON
      key_value: "p"
    - name: ORGANIZATION
      key_value: "o"
    - LOCATION
  sequential_key_binding: true

لا تُقرأ خريطة key_values: على مستوى المخطط، ولا تُقرأ كذلك خريطة مكتوبة قيمةً لـ sequential_key_binding، إذ يعامله Potato بوصفه علامة تشغيل فقط.

التلميحات

التلميح هو موضع الحالات الحدّية للتصنيف، كي يتحقق المُعلّق مما يُعدّ ORGANIZATION دون مغادرة المهمة. التلميحات خصائص لكل تصنيف:

yaml
- annotation_type: span
  name: entities
  description: "Highlight named entities in the text"
  labels:
    - name: PERSON
      tooltip: "Names of people, characters, or personas"
    - name: ORGANIZATION
      tooltip: "Companies, agencies, institutions"
    - name: LOCATION
      tooltip_file: "config/tooltips/location.html"

يأخذ tooltip نصًا عاديًا، ويأخذ tooltip_file مسار ملف HTML، وهو الخيار الأفضل حين تحتاج الإرشادات إلى أمثلة أو نص عريض أو قائمة. أما خريطة tooltips: على مستوى المخطط فلا يقرؤها إلا hierarchical_multiselect، ولا تفعل شيئًا في مخطط النطاقات.

النطاقات المتداخلة

السماح بالتداخل

يُسمح للنطاقات بأن تتداخل، ولا يوجد إعداد يشغّل هذا السلوك. والتداخل هو المطلوب حين يحمل مقطع واحد من النص تصنيفين معًا، كما في "Dr. Smith" الذي هو PERSON وROLE في آن واحد. ومنذ الإصدار 2.9.0 يُقبل أيضًا التحديد الذي يبدأ عند نهاية نطاق موجود أو ينتهي عند بداية نطاق، فيمكن إنشاء نطاقات متداخلة جزئيًا. أما الإصدارات السابقة فكانت ترفض ذلك التحديد.

تعطيل التداخل (الافتراضي)

لا يحتوي مخطط النطاقات على مفتاح يمنع التداخل، لذا فالمهمة التي يجب ألا تتداخل فيها النطاقات أبدًا عليها أن تنص على ذلك في إرشادات التعليق. وحين يهمّ هذا التمييز للتصدير لا للمُعلّق، يُبقي مخططا نطاقات اثنان مجموعتي التصنيفات منفصلتين، لأن كل مخطط يخزّن نطاقاته تحت اسمه الخاص:

yaml
annotation_schemes:
  - annotation_type: span
    name: entities
    description: "Label named entities"
    labels:
      - PERSON
      - ORGANIZATION
 
  - annotation_type: span
    name: roles
    description: "Label professional roles"
    labels:
      - ROLE

أوضاع تحديد النطاق

يخزّن Potato كل نطاق على هيئة إزاحات أحرف داخل نص العنصر، ولا يوجد مفتاح إعداد يبدّل التحديد بين مستوى الكلمة ومستوى الحرف. الوضعان التاليان يصفان ما يستطيع المُعلّق فعله، لا إعدادات تشغّلها.

التحديد على مستوى الكلمة

السحب فوق كلمات كاملة هو الشكل المعتاد لمعظم أعمال NER في الممارسة، وتُخزَّن النتيجة بوصفها إزاحتي أول حرف وآخر حرف محدَّدين. لا شيء في الإعداد يفرض حدود الكلمات، فإن كانت النطاقات المؤلفة من كلمات كاملة مهمة لبياناتك، فضع هذا الشرط في الإرشادات وتحقق منه في التصدير بدلًا من أن تتوقع من الواجهة رفض جزء من كلمة.

التحديد على مستوى الحرف

تحديد جزء من كلمة متاح دائمًا ولا يحتاج إلى إعداد، وعليه تعتمد المهام الصرفية والمهام التي تعمل دون مستوى الرمز المميّز. يدمج Potato سلاسل المسافات وعلامات الجدولة قبل العرض حتى تطابق الإزاحات التي يخزّنها ما يقيسه المتصفح، وهذا مهم حين يحمل نصك مسافات بادئة ذات معنى. صرّح بـ instance_display حين يجب الحفاظ على المسافات الأفقية كما هي تمامًا.

النطاقات المُعلّقة مسبقًا

تزويد المهمة بمخرجات نموذج مسبقًا يحوّل التصنيف إلى تصحيح، وهو سير العمل الأسرع كلما كان النموذج مصيبًا في معظم المدوّنة. يقرأ Potato التعليقات الأولية من حقل في كل عنصر يحدد اسمه pre_annotation.field:

yaml
pre_annotation:
  enabled: true
  field: "predictions"
  allow_modification: true
  show_confidence: true
  highlight_low_confidence: 0.7

الإعداد allow_modification: true هو ما يجعل المهمة تصحيحًا لا مراجعة، إذ لا يستطيع المُعلّقون من دونه تغيير ما اقترحه النموذج. ويُعلّم highlight_low_confidence: 0.7 العناصر التي كان النموذج أقل ثقة فيها، فيتجه الانتباه إلى النطاقات الأرجح خطأً.

يحمل الحقل مدخلًا لكل اسم مخطط، ويأخذ مخطط النطاقات قائمة من الإزاحات:

json
{
  "id": "item_002",
  "text": "Apple announced new iPhone in California.",
  "predictions": {
    "entities": [
      {"start": 0, "end": 5, "label": "ORG", "confidence": 0.85},
      {"start": 27, "end": 37, "label": "LOC", "confidence": 0.91}
    ]
  }
}

التعليقات المسبقة نقطة بداية وليست تعليقًا، لذا فالعنصر الذي لا يفتحه أحد يُصدَّر فارغًا حتى لو وصل ومعه تنبؤات مرفقة.

إعدادات NER الشائعة

NER القياسي (4 أنواع)

تتبع مجموعة الأنواع الأربعة اصطلاح CoNLL-2003، وهي الخيار الصحيح حين يجب أن تكون نتائجك قابلة للمقارنة بأرقام NER المنشورة:

yaml
- annotation_type: span
  name: ner
  description: "Label named entities"
  labels:
    - PER    # Person
    - ORG    # Organization
    - LOC    # Location
    - MISC   # Miscellaneous
  sequential_key_binding: true

NER الموسّع (بأسلوب OntoNotes)

تمنح ثمانية عشر نوعًا تمييزات أدق بكلفة حقيقية في الاتفاق، لأن الحدود بين NORP وORG وGPE هي حيث يختلف المُعلّقون أكثر من أي موضع آخر. استخدم المجموعة الموسّعة حين تحتاج الأعمال اللاحقة إلى هذه التمييزات، واحسب حساب تدريب أطول:

yaml
- annotation_type: span
  name: ner_extended
  description: "Label named entities using the OntoNotes type set"
  labels:
    - PERSON
    - NORP        # Nationalities, religious/political groups
    - FAC         # Facilities
    - ORG
    - GPE         # Geopolitical entities
    - LOC
    - PRODUCT
    - EVENT
    - WORK_OF_ART
    - LAW
    - LANGUAGE
    - DATE
    - TIME
    - PERCENT
    - MONEY
    - QUANTITY
    - ORDINAL
    - CARDINAL

NER الطبي الحيوي

النطاقات الطبية الحيوية طويلة وكثيرًا ما تكون متداخلة، لذا فالتلميحات التي تحمل مثالًا محلولًا لكل نوع تؤتي ثمارها هنا أكثر مما تفعل في مهمة من مجال عام:

yaml
- annotation_type: span
  name: bio_ner
  description: "Label biomedical entities"
  labels:
    - GENE
    - PROTEIN
    - DISEASE
    - DRUG
    - SPECIES

NER لوسائل التواصل الاجتماعي

يأتي نص وسائل التواصل الاجتماعي بأنواع كيانات لا مكان لها في مجموعات الأخبار الصحفية، وCREATIVE_WORK وGROUP هما النوعان اللذان ينتهي بهما الأمر غالبًا مصنّفين خطأً على أنهما ORG إن لم يكن لهما تصنيف خاص:

yaml
- annotation_type: span
  name: social_ner
  description: "Label named entities in social media text"
  labels:
    - PERSON
    - ORGANIZATION
    - LOCATION
    - PRODUCT
    - CREATIVE_WORK
    - GROUP

النطاق مع سمات إضافية

يجمع مخطط ثانٍ إلى جانب مخطط النطاقات حكمًا على العنصر ككل. يخزّن Potato الاثنين منفصلين، لذا فإجابة الاختيار الفردي تنطبق على المستند لا على نطاق بعينه:

yaml
annotation_schemes:
  - annotation_type: span
    name: entities
    description: "Highlight named entities"
    labels:
      - PERSON
      - ORGANIZATION
 
  - annotation_type: radio
    name: entity_type
    description: "What type of entity is this?"
    labels:
      - Named
      - Nominal
      - Pronominal

مخططات نطاق متعددة

مخططا نطاقات اثنان هما طريقة تعليق جوانب مختلفة من النص نفسه دون إجبار المُعلّقين على استحضار مجموعة تصنيفات مدمجة واحدة. يحصل كل مخطط على صف أزرار خاص به ومجموعة مفاتيح خاصة به وحقل خاص به في التصدير:

yaml
annotation_schemes:
  # Named entities
  - annotation_type: span
    name: entities
    description: "Label named entities"
    labels:
      - PERSON
      - ORGANIZATION
      - LOCATION
 
  # Sentiment expressions
  - annotation_type: span
    name: sentiment_spans
    description: "Highlight sentiment expressions"
    labels:
      - POSITIVE
      - NEGATIVE

تعليق النطاقات متعدد الحقول

جديد في الإصدار 2.1.0

يمكن لتعليق النطاقات أن يستهدف حقلًا نصيًا محددًا في البيانات متعددة الحقول عبر الخيار target_field، وهذا ما تحتاج إليه حين يحتوي العنصر على مستند مصدر وملخص وينتمي النطاق إلى أحدهما.

الإعداد

يسمّي كل مخطط الحقل الذي يعلّقه، فتبقى مجموعتا التصنيفات مرتبطتين بالنص الصحيح:

yaml
annotation_schemes:
  - annotation_type: span
    name: source_entities
    description: "Label entities in the source text"
    target_field: source_text
    labels:
      - PERSON
      - ORGANIZATION
 
  - annotation_type: span
    name: summary_entities
    description: "Label entities in the summary"
    target_field: summary
    labels:
      - PERSON
      - ORGANIZATION

صيغة البيانات متعددة الحقول

يجب أن تتضمن بياناتك الحقول النصية المنفصلة:

json
{
  "id": "doc1",
  "source_text": "John Smith works at Microsoft in Seattle.",
  "summary": "Smith is employed by Microsoft."
}

صيغة المخرجات

عند استخدام target_field، تُفهرَس التعليقات حسب الحقل:

json
{
  "id": "doc1",
  "source_entities": {
    "source_text": [
      {"start": 0, "end": 10, "text": "John Smith", "label": "PERSON"},
      {"start": 20, "end": 29, "text": "Microsoft", "label": "ORGANIZATION"}
    ]
  },
  "summary_entities": {
    "summary": [
      {"start": 0, "end": 5, "text": "Smith", "label": "PERSON"},
      {"start": 22, "end": 31, "text": "Microsoft", "label": "ORGANIZATION"}
    ]
  }
}

للاطلاع على مثال كامل يعمل، انظر project-hub/simple_examples/simple-multi-span/ في مستودع Potato.

خيارات العرض

إظهار التصنيف داخل النطاق

يطبع Potato التصنيف داخل كل نطاق مظلَّل افتراضيًا. وفي مستند كثيف فيه نطاقات قصيرة كثيرة يزاحم نص التصنيفات الجملة، والإعداد show_span_labels: false يُبقي النص مقروءًا بينما يواصل لون التظليل الدلالة على التصنيف:

yaml
- annotation_type: span
  name: entities
  description: "Highlight named entities in the text"
  labels:
    - PERSON
    - ORGANIZATION
  show_span_labels: false

نمط التسطير

لا يحتوي مخطط النطاقات على مفتاح لنمط التظليل، وتُعرض النطاقات دائمًا بخلفية ملوّنة. أما التسطير والعرض بين أقواس فهما خياران في نوع الإشارة المرجعية المشتركة، عبر visual_display.highlight_mode، لذا فالمهمة التي تحتاج إلى أحدهما ينبغي أن تستخدم سلاسل الإشارة المرجعية المشتركة.

صيغة المخرجات

تُحفَظ تعليقات النطاقات مع إزاحات الأحرف:

json
{
  "id": "doc1",
  "entities": [
    {
      "start": 0,
      "end": 10,
      "text": "John Smith",
      "label": "PERSON"
    },
    {
      "start": 20,
      "end": 29,
      "text": "Microsoft",
      "label": "ORGANIZATION"
    }
  ]
}

مثال كامل: مهمة NER

يسمّي item_properties الحقلين اللذين يقرأ منهما Potato معرّف العنصر ونصه، والإعداد الخالي منه لا يبدأ التشغيل. تحصل أنواع الكيانات الخمسة على مفاتيح من صف الأرقام عبر sequential_key_binding، ويسجّل مخطط الاختيار الفردي في النهاية حكمًا على الصعوبة يفيد لاحقًا في تفسير المواضع التي انخفض فيها الاتفاق:

yaml
annotation_task_name: "Named Entity Recognition"
 
data_files:
  - data/documents.json
 
item_properties:
  id_key: id
  text_key: text
 
annotation_schemes:
  - annotation_type: span
    name: entities
    description: "Highlight and label all named entities"
    labels:
      - PERSON
      - ORGANIZATION
      - LOCATION
      - DATE
      - MONEY
    sequential_key_binding: true
    allow_discontinuous: false
 
  - annotation_type: radio
    name: difficulty
    description: "How difficult was this document to annotate?"
    labels:
      - Easy
      - Medium
      - Hard
 
output_annotation_dir: annotation_output
export_annotation_format: jsonl

النطاقات غير المتصلة

جديد في الإصدار 2.2.0

يتيح allow_discontinuous: true للمُعلّق تحديد عدة مقاطع نصية غير متجاورة وتسجيلها نطاقًا واحدًا، وهذا ما تحتاج إليه السوابق المنقسمة والمكوّنات غير المتصلة. عدم الاتصال أمر مختلف عن التداخل، ولا أثر لهذا المفتاح في ما إذا كان يجوز لنطاقين أن يغطيا الأحرف نفسها:

yaml
- annotation_type: span
  name: entities
  description: "Highlight named entities in the text"
  labels:
    - PERSON
    - ORGANIZATION
  allow_discontinuous: true

عند تفعيل الخيار، يضغط المُعلّق على Ctrl في Windows وLinux، أو على Cmd في Mac، أثناء تحديد نص إضافي لإضافته إلى النطاق الحالي. وتحمل المخرجات زوجًا من البداية والنهاية لكل مقطع.

التكامل مع ربط الكيانات

جديد في الإصدار 2.2.0

يمكن ربط تعليقات النطاقات بقواعد معرفة خارجية (Wikidata أو UMLS أو واجهات REST مخصصة) بإضافة كتلة entity_linking إلى مخطط النطاقات. ويستحق الربط الخطوة الإضافية لكل نطاق حين يشترك كيانان في الصيغة السطحية نفسها ولا يكفي التصنيف وحده للتمييز بينهما:

yaml
- annotation_type: span
  name: entities
  description: "Highlight and link named entities"
  labels:
    - PERSON
    - ORGANIZATION
    - LOCATION
  entity_linking:
    enabled: true
    knowledge_bases:
      - name: wikidata
        type: wikidata
        language: en
    auto_search: true
    required: false

يُجري auto_search: true البحث فور إنشاء النطاق، مما يوفّر نقرة في المهام التي يُربط فيها معظم النطاقات. ويرفض required: true حفظ نطاق بلا رابط، لذا اتركه معطّلًا ما لم يكن متوقعًا أن يوجد كل كيان في بياناتك داخل قاعدة المعرفة. عند تفعيل ربط الكيانات، تظهر أيقونة رابط في شريط تحكم كل نطاق، والنقر عليها يفتح نافذة بحث. انظر توثيق ربط الكيانات للتفاصيل الكاملة.

أفضل الممارسات

  1. اكتب الألوان على التصنيفات التي تحتاج إليها واترك البقية للوحة الألوان
  2. ضع الحالات الحدّية في tooltip أو tooltip_file، واحدًا لكل تصنيف، لا في وصف المخطط
  3. فعّل sequential_key_binding في أي مخطط فيه أكثر من تصنيفين، وأضف key_value حيث يفيد مفتاح تذكيري
  4. حدّد سياسة التداخل في الإرشادات، لأن المخطط لا يفرض أي سياسة
  5. زوّد المهمة مسبقًا عبر pre_annotation في سير عمل التصحيح، وأبقِ allow_modification: true
  6. اجعل مجموعة التصنيفات صغيرة ووزّع الجوانب غير المترابطة على مخططات نطاقات منفصلة

قراءات إضافية

للاطلاع على تفاصيل التنفيذ، انظر التوثيق المصدري.