Содержание курса 30 / 37

30 / 37 · Задачи NLP

Распознавание именованных сущностей

Пометить каждый токен сущностью, к которой он относится: схема BIO, превращающая фрагменты в классы токенов, выравнивание между размеченными словами и токенами-подсловами, линейный выходной слой на предобученном энкодере, точность, полнота и F1 на уровне сущностей, а также базовые уровни и ловушки разметки последовательностей.

На этой странице 11

Классификация даёт одну метку на документ. Многим вопросам нужна метка на каждый фрагмент документа: какие слова называют человека, организацию, место, дату. Распознавание именованных сущностей (NER) — стандартный пример разметки последовательностей (sequence labelling), и именно здесь разрыв между словами, которые размечает набор данных, и токенами-подсловами, которые читает трансформер, приходится преодолевать явно.

Обозначения. Предложение — последовательность слов w1,…,wnw_1, \dots, w_n с эталонными тегами y1,…,yny_1, \dots, y_n; токенизатор превращает её в токены-подслова t1,…,tmt_1, \dots, t_m с m≥nm \ge n; энкодер даёт вектор hjh_j на токен; выходной слой даёт логиты по набору тегов в каждой позиции.

Постановка задачи#

Вход: предложение. Выход: множество фрагментов-сущностей в нём, у каждого — тип. Стандартные типы бенчмарка CoNLL-2003 (Tjong Kim Sang and De Meulder, 2003) — PER, ORG, LOC и MISC; в обучающей части 14 041 предложение, в валидационной — 3250, в тестовой — 3453. Фрагменты переводятся в теги слов схемой BIO: B-X начинает сущность типа X, I-X продолжает её, O — вне сущностей. С четырьмя типами это 4×2+1=94 \times 2 + 1 = 9 классов.

ТокенBarackObamawasborninHonolulu
ТегB-PERI-PEROOOB-LOC

Различие B/I позволяет отличить две соседние сущности одного типа: B-PER I-PER B-PER — два человека, B-PER I-PER I-PER — один.

Отправная точка: признаки и модель последовательности#

До нейросетевых моделей NER решали условным случайным полем (CRF) над придуманными вручную признаками: регистр, форма слова, суффиксы, вхождение в справочники, предыдущее и следующее слово (Lafferty, McCallum and Pereira, 2001). CRF моделирует последовательность тегов совместно, поэтому выучивает оценки переходов: низкая оценка перехода от O к I-PER делает его маловероятным. Чтобы сделать его невозможным, нужно жёсткое ограничение — маска на переходах, которая в соглашении IOB2 разрешает I-X только после B-X или I-X. Первые нейросетевые системы сохранили CRF поверх двунаправленной LSTM над эмбеддингами слов и символов (Lample et al., 2016; Huang, Xu and Yu, 2015) и достигли примерно 90–91 F1F_1 на CoNLL-2003; регистр и форма символов оставались самыми полезными сигналами, только теперь выученными.

Классификация токенов на предобученном энкодере#

logitsj=Whj+b∈R9,L=−1∣J∣∑j∈Jlog⁡softmax⁡(logitsj)yj,\text{logits}_j = W h_j + b \in \mathbb R^{9}, \qquad \mathcal L = -\frac{1}{|J|}\sum_{j \in J} \log \operatorname{softmax}(\text{logits}_j)_{y_j},

где JJ — множество позиций токенов, у которых есть метка. Размерности: идентификаторы [B, m] → векторы [B, m, 768] → логиты [B, m, 9], развёрнутые в [B·m, 9] относительно целей [B·m] для функции потерь. Без CRF: контекст энкодера достаточно силён, чтобы независимые решения по токенам работали, а немногие недопустимые переходы можно исправить постобработкой.

Модель с учётом регистра (cased): заглавные буквы — самый сильный признак имени, а токенизатор без учёта регистра из прежних заметок их бы выбросил.

Выравнивание слов и токенов#

Набор данных размечает слова; модель читает токены WordPiece. Hendrix penned on a piece of London hotel stationery in late 1966 превращается в Hendrix penned on a piece of London hotel station ##ery in late 1966, а 10,925 — в четыре токена. Метод токенизатора word_ids() даёт для каждого токена номер слова, из которого он получен (None для [CLS] и [SEP]), и метки назначаются по правилу:

  • специальные токены получают метку −100-100, которую кросс-энтропия игнорирует;
  • первый токен слова получает тег слова;
  • токены-продолжения (##ery) получают либо −100-100, так что обучается только первая часть, либо копию тега слова. Скопированный B-X превращает одну сущность в несколько (B-PER B-PER — два человека), поэтому при копировании на частях-продолжениях B-X нужно заменять на I-X.

Обучение и подсчёт метрики — разные правила. Каким бы ни было соглашение при обучении, метрика использует один тег на слово: построить по word_ids() маску, которая оставляет первый токен каждого слова и отбрасывает специальные токены и части-продолжения, применить её одинаково к предсказаниям и к эталону и только потом передать последовательности тегов оценщику. Для London hotel station ##ery word_ids() даёт 6, 7, 8, 8, и маска оставляет первые три. Отбрасывание одних позиций с −100-100 даёт один тег на слово, только если частям-продолжениям ставилось −100-100.

Рисунок

Метки слов и токены-подслова

Выравнивание меток слов по токенам[CLS]: −100 / −100; Jim: B-PER / B-PER; ##i: I-PER / −100; Hendrix: I-PER / I-PER; moved: O / O; to: O / O; London: B-LOC / B-LOC; [SEP]: −100 / −100словатокенывсе частитолько перваяJimiB-PERHendrixI-PERmovedOtoOLondonB-LOC[CLS]None−100−100Jim0B-PERB-PER##i0I-PER−100Hendrix1I-PERI-PERmoved2OOto3OOLondon4B-LOCB-LOC[SEP]None−100−100word_idsВыравнивание меток слов по токенам[CLS]: −100 / −100; Jim: B-PER / B-PER; ##i: I-PER / −100; Hendrix: I-PER / I-PER; moved: O / O; to: O / O; London: B-LOC / B-LOC; [SEP]: −100 / −100токеныword_idsвсе частитолько первая[CLS]None−100−100Jim0 JimiB-PERB-PER##i0 JimiI-PER−100Hendrix1 HendrixI-PERI-PERmoved2 movedOOto3 toOOLondon4 LondonB-LOCB-LOC[SEP]None−100−100
Набор данных размечает слова, а модель читает токены WordPiece. bert-base-cased разбивает Jimi на Jim и ##i, а [CLS] и [SEP] не принадлежат никакому слову. word_ids() токенизатора даёт для каждого токена номер его слова, и по нему метки переносятся на токены: специальные токены получают −100 (функция потерь их игнорирует), первая часть слова — его метку, а продолжение — либо копию метки (label_all_tokens=True; скопированная B- заменяется на I-, иначе ##i начал бы второго человека), либо −100, чтобы обучалась только первая часть. При оценке маска первых токенов оставляет один тег на слово и в предсказаниях, и в эталоне.

Замороженного энкодера недостаточно#

Заморозим все 108.3 млн параметров BERT-base-cased и обучим только выходной слой на 6921 параметр (0.01% модели) на обучающей части CoNLL-2003 две эпохи с шагом обучения 5×10−35 \times 10^{-3}; токены-продолжения получают тег своего слова. Функция потерь на обучении заканчивается на 0.26, а первое тестовое предложение показывает результат:

SOCCER-JAPANGETLUCKYWIN,CHINAINSURPRISEDEFEAT.
эталонOOB-LOCOOOOB-PEROOOO
заморожен + слойOOB-PEROOOOOOOOO

Выходной слой находит JAPAN, но присваивает неверный тип, и пропускает CHINA, эталонный тег которого сам по себе — известная ошибка разметки этого корпуса (CHINA — страна, здесь футбольная команда, а не человек). В заголовке заглавными буквами, где признак регистра исчезает, линейное считывание замороженных признаков находит некоторые имена и не может надёжно определить их тип; это результат линейного зондирования из заметки о дообучении в другой задаче. Дообучение всего энкодера на CoNLL-2003 даёт 92.4 F1F_1 для BERT-base (Devlin et al., 2019, таблица 7); рецепт тот же, что в прежних заметках (шаг обучения от 22 до 5×10−55 \times 10^{-5}, от двух до четырёх эпох), применённый к той же модели без заморозки энкодера.

Оценка: сущности, а не токены#

Доля верных токенов обманывает дважды: большинство токенов — O, а наполовину размеченная сущность бесполезна. Стандарт — точность, полнота и F1F_1 на уровне сущностей из заметки об оценке, как их реализует seqeval: предсказанный фрагмент засчитывается, только если его начало, конец и тип совпадают с эталонным фрагментом. Предсказание B-PER I-PER над Barack Obama — одно верное срабатывание; B-PER над одним Barack — одно ложное срабатывание и один пропуск. Маска первых токенов из предыдущего раздела применяется к предсказаниям и к эталону до подсчёта, а идентификаторы тегов переводятся обратно в строки, потому что оценщик читает префиксы B-/I-.

Разбивка по типам (PER, ORG, LOC, MISC) — стандарт, и она зависит от того, взято ли отображение идентификаторов в метки из набора данных. Написанное вручную отображение, которое упорядочивает теги не так, как набор данных, например меняет местами B-LOC и B-ORG, не влияет на общую F1F_1, потому что перестановка согласованная, но меняет местами числа по типам и предсказанные теги этих двух типов. Отсюда правило: брать отображение из собственного списка меток набора данных и никогда не писать отображения меток вручную.

Зачем извлекать сущности#

Повторяются три применения. Мониторинг и аналитика: считать упоминания организаций, людей и мест в потоке новостей и связывать их с базой знаний. Заполнение слотов в ассистентах: в book a flight to Tokyo next Friday нужно найти Tokyo как пункт назначения и next Friday как дату, прежде чем заработает логика бронирования; NER — первый этап, за ним идут связывание и нормализация. Обезличивание (de-identification): заменить имена, адреса, телефоны и даты в тексте заглушками ([CLIENT_1]) до того, как текст покинет контролируемую среду, например чтобы отправить его во внешнюю модель. Последнее применение острее всего показывает слабые места задачи: пропущенная сущность — это утечка, неверная граница пропускает половину имени, один и тот же человек должен получать одну и ту же заглушку во всём документе (кореференция), а заглушки должны быть обратимыми для уполномоченного читателя и при этом не восстанавливаться из контекста кем-то ещё — чего один NER не гарантирует.

Что изменилось#

CRF на признаках / BiLSTM-CRFЭнкодер + линейный слой, дообученный
Признакипридуманные или выученные по словам и символамконтекстные векторы подслов
Модель последовательностиCRF над тегаминет; контекст внутри энкодера
Регистр, формаявные признакивыучены, нужна модель с учётом регистра
F1F_1 на тесте CoNLL-2003≈ 90–91≈ 92–93
Токенысловаподслова, выровненные через word_ids

Ограничения#

  • Фрагменты плоские. BIO не может выразить вложенные сущности ([Bank of [America]]) или разрывные; вложенному NER нужны модели на фрагментах.
  • Типы задаются данными. Модель, обученная на четырёх грубых типах, не найдёт названия лекарств или коды продуктов без новых меток; zero-shot NER на языковых моделях с промптом обменивает точность на гибкость.
  • Сдвиг предметной области силён: модели, обученные на новостях, деградируют на твитах, юридических текстах и медицинских записях, где регистр и форматирование другие.
  • Границы хрупки на пунктуации, дефисах и разбиениях на подслова, а метрика не прощает ошибок в один токен.
  • В бенчмарке есть ошибки (CHINA как человек), поэтому лучшие результаты отчасти измеряют согласие с разметчиками.

Что нужно запомнить#

  • NER — классификация токенов с тегами BIO; четыре типа дают девять классов.
  • Выравнивать метки слов по токенам-подсловам через word_ids: специальные токены — −100-100, первая часть получает тег, части-продолжения — −100-100 или тег с заменой B- на I-. Считать метрику по одному тегу на слово, с маской первых токенов для предсказаний и эталона.
  • Линейный слой на замороженном энкодере находит некоторые имена и ошибается в типах или пропускает другие; энкодер нужно дообучать (92.4 F1F_1 для BERT-base на CoNLL-2003).
  • Оценивать на уровне сущностей (seqeval), по типам, с отображением меток, взятым из набора данных.
  • Использовать модель с учётом регистра; регистр — самый сильный признак.

Ноутбук#

week07_nlp_tasks.ipynb. Номера ячеек считают все ячейки, включая текстовые, начиная с 1. Приведённые числа взяты из прогона, сохранённого в курсе; у ячеек, изменённых с тех пор под текущие версии библиотек, сохранённого выхода нет.

  • Ячейки 3–9 загружают CoNLL-2003 и печатают его признаки, включая список меток ner_tags в собственном порядке набора данных.
  • Ячейки 11–15 токенизируют обучающее предложение bert-base-cased и показывают разбиения на подслова и word_ids().
  • Ячейка 17 определяет tokenize_and_align_labels с соглашением −100-100 и label_all_tokens=True (токены-продолжения получают копию тега слова, в том числе тега B-); ячейка 18 применяет её к набору данных.
  • Ячейки 23–27 строят BERTforNER (замороженный AutoModel, дропаут, nn.Linear(768, 9), кросс-энтропия на развёрнутых логитах) и печатают 6921 обучаемый параметр из 108 317 193; если убрать строки, выставляющие requires_grad = False, постановка превращается в полное дообучение.
  • Ячейка 29 берёт id2label из названий меток набора данных (его features). Ноутбук в том виде, в каком курс читали впервые, вместо этого задавал своё отображение с B-LOC под индексом 3 и B-ORG под 5, тогда как в списке признаков набора данных B-ORG стоит под 3, а B-LOC — под 5, поэтому числа по типам и печатаемые теги этих двух типов менялись местами. Ячейка 30 определяет функцию метрики seqeval, которая отбрасывает только позиции с −100-100 и поэтому при скопированных тегах оценивает каждую часть-подслово, а не один тег на слово; ячейка 31 обучает две эпохи через Trainer (шаг обучения 5×10−35\times10^{-3}, батч 32, DataCollatorForTokenClassification) и приводит итоговую функцию потерь на обучении 0.262; метрики оценки, посчитанные на каждой эпохе, в сохранённом выходе отсутствуют.
  • Ячейки 33–34 печатают эталонные теги и предсказания модели для первого тестового предложения, приведённые выше. Сохранённые эталонные теги получены с отображением меток, написанным вручную в первой версии, поэтому JAPAN значится там как B-ORG; его идентификатор в наборе данных — B-LOC. Предсказания напечатаны по токенам-подсловам, 33 позиции с [CLS] и [SEP]; таблица переносит их обратно на слова по первому токену каждого слова (JAPAN — это J ##AP ##AN, и все три предсказаны как B-PER).
  • Ячейки 35–36 перечисляют применения NER и ставят вопрос об обезличивании.

Дальше#

Разметка находит сущности, которые уже есть в тексте. Следующая заметка просит фрагмент, отвечающий на вопрос, — это тот же энкодер, читающий вопрос и отрывок вместе и предсказывающий две позиции, начало и конец, вместо тега на каждый токен.

Литература#