Как легко настроить любой преобразователь обработки естественного языка для распознавания именованных сущностей на любом языке.

В этой статье мы рассмотрим, как легко настроить любой предварительно обученный преобразователь обработки естественного языка (= NLP) для распознавания именованных сущностей (= NER) на любом языке.

Почему тебе должно быть до этого дело? Что ж, NER - это мощная задача НЛП со множеством приложений, как было подробно описано в «На пути к науке о данных». Однако эффективное использование NER часто требует точной настройки вашей модели NER для конкретного языка или предметной области на основе предварительно обученных преобразователей, которые доступны и реалистичны для использования с учетом вашего вычислительного бюджета.

Чтобы показать вам, как это сделать, мы используем пакет python NERDA для точной настройки преобразователя BERT для NER.

NERDA - это NER-система общего назначения, которую можно использовать для тонкой настройки любого преобразователя для NER на любом языке с минимумом кода.

Признание именных организаций для начинающих

Если вы не знакомы с NER, посмотрите определение Википедии:

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

Мы можем проиллюстрировать это далее на примере задачи NER.

ЗАДАЧА. Определите имена людей и организации в тексте:

Джим купил 300 акций Acme Corp.

РЕШЕНИЕ: Люди: «Джим», Организации: «Acme Corp.»

Чтобы получить представление о других концепциях и технологиях, упомянутых в этой статье, мы перечислили ряд предыдущих историй о Data Science в разделе Ресурсы.

Набор инструментов

Теперь давайте перейдем к настройке трансформатора для NER.

Шаги, которые мы вам покажем, одинаковы, независимо от вашего выбора трансформера и целевого языка.

Для этой работы мы будем использовать новый пакет python NERDA.

NERDA имеет простой в использовании интерфейс для тонкой настройки преобразователей NLP для задач распознавания именованных сущностей. Он основан на популярной платформе машинного обучения PyTorch и Hugging Face transformers.

NERDA имеет открытый исходный код и доступен в индексе пакетов Python (PyPI). Его можно установить с помощью:

pip install NERDA

Набор данных

Мы будем использовать набор данных на английском языке CoNLL-2003 с аннотациями NER для обучения и проверки нашей модели.
Сначала мы загружаем набор данных и загружаем предопределенные разбиения данных для обучения и проверки.

from NERDA.datasets import get_conll_data, download_conll_data download_conll_data()
training = get_conll_data('train')
validation = get_conll_data('valid')

CoNLL-2003 оперирует следующими типами именованных сущностей (довольно стандартные категории):

  1. PER сыновей
  2. ORG анизации
  3. МЕСТО
  4. MISC прочее
  5. O сторона (не названный объект)

Наблюдение из набора данных CoNLL-2003 состоит из предложения с лексемами слов с тегом именованного объекта для каждого токена слова.

Ниже вы видите пример случайного предложения из набора данных CoNLL с его словосочетаниями в сочетании с соответствующими тегами именованных сущностей ([tag]).

Germany [B-LOC]
's [O]
representative [O]
to [O] 
the [O]
European [B-ORG] 
Union [I-ORG] 
's [O]
veterinary [O] 
committee [O]
Werner [B-PER] 
Zwingmann [I-PER]
said [O]
on [O] 
Wednesday [O]
...

Набор данных реализует схему тегов Inside-Outside-Beginning (IOB).

Схема маркировки IOB подразумевает, что слова, которые являются началом именованных сущностей, помечаются 'B-', а слова «внутри» (= продолжения) именованных сущностей помечаются «I-» .

В приведенном выше примере «Германия» обозначена как МЕСТОПОЛОЖЕНИЕ, «Европейский Союз» - как ОРГАНИЗАЦИЯ, а «Вернер Цвингманн» - как PERson.

Настройка модели

В качестве первого шага мы указываем доступные теги NER для задачи (за исключением специального тега «external»).

tag_scheme = [
'B-PER',
'I-PER',
'B-ORG',
'I-ORG',
'B-LOC',
'I-LOC',
'B-MISC',
'I-MISC'
]

Затем мы должны решить, какой преобразователь из Hugging Face transformers мы хотим настроить. Мы остановимся на многоязычном трансформаторе BERT без корпуса (популярный выбор).

transformer = 'bert-base-multilingual-uncased'

Кроме того, у нас есть возможность предоставить набор основных гиперпараметров для сети, а также для самого обучения модели.

# hyperparameters for network
dropout = 0.1
# hyperparameters for training
training_hyperparameters = {
'epochs' : 4,
'warmup_steps' : 500,                                                   'train_batch_size': 13,                                         'learning_rate': 0.0001
}

Собираем кусочки вместе

Теперь соедините части в полную конфигурацию модели, используя интерфейс модели NERDA.

from NERDA.models import NERDA
model = NERDA(
dataset_training = training,
dataset_validation = validation,
tag_scheme = tag_scheme, 
tag_outside = 'O',
transformer = transformer,
dropout = dropout,
hyperparameters = training_hyperparameters
)

Под капотом NERDA реализована torch нейронная сеть, основанная на выбранном преобразователе (в данном случае BERT). По умолчанию архитектура сети будет аналогична одной из моделей в Hvingelby et al. 2020 (при желании вы также можете предоставить свою архитектуру сети).

Чтобы обучить модель и тем самым точно настроить преобразователь BERT, все, что осталось сделать, - это вызвать метод train.

model.train()

Примечание: это займет некоторое время в зависимости от размеров вашей машины (если вы хотите пропустить обучение, вы можете продолжить и использовать одну из предварительно приготовленных моделей, которая NERDA поставляется с).

Вот и все. Теперь мы настроили нашу собственную современную модель на основе BERT для NER.

Давайте посмотрим, как модель работает (с помощью F1-score) на независимом тестовом наборе.

>>> test = get_conll_data('test')
>>> model.evaluate_performance(test)
Level  F1-Score 
B-PER  0.963
I-PER  0.987
B-ORG  0.887
I-ORG  0.866
B-LOC  0.922
I-LOC  0.817
B-MISC  0.823
I-MISC  0.680
AVG_MICRO 0.907

‘AVG_MICRO’: микро-усредненная оценка F1 по тегам сущностей.

Как видите, производительность выглядит великолепно.

Теперь мы можем использовать модель для идентификации именованных сущностей в новых текстах, т.е.

>>> model.predict_text('Cristiano Ronaldo plays for Juventus FC')
([['Cristian', 'Ronaldo', 'plays', 'for', 'Juventus', 'FC']], 
[['B-PER', 'I-PER', 'O', 'O', 'B-ORG', 'I-ORG']])

Модель (правильно) идентифицирует Криштиану Роналду (футболиста) как личность, а «Ювентус» (футбольный клуб) как организацию.

Точная настройка любого трансформатора

На данный момент на Hugging Face доступно более 5000 моделей трансформаторов. Итак, какой из них вам следует настроить? Мы очень не хотим вас разочаровывать, но ответ таков: это зависит от обстоятельств. Бесплатных обедов нет. У всех моделей трансформаторов есть свои сильные и слабые стороны. Кроме того, вам необходимо выбрать преобразователь, который соответствует вашему вычислительному бюджету и уровню уважения к изменению климата.

Как упоминалось ранее, BERT обычно хороший выбор. Новый ребенок в блоке, ELECTRA, однако, намного легче и эффективнее с точки зрения вычислений по сравнению с BERT, и по-прежнему очень хорошо справляется с задачами NER.

Какой бы трансформатор вы ни выбрали, вполне вероятно, что NERDA его поддержит. В приведенном выше примере кода все, что вам нужно было бы изменить для точной настройки трансформатора ELECTRA, вместо BERT - это изменить параметр transformer, то есть:

model = NERDA(
...,
transformer = 'google/electra-small-discriminator',
...
)

Точная настройка для любого языка

С помощью NERDA вы также можете точно настроить преобразователь для любого языка, например с легкостью используя свой собственный набор данных. Чтобы настроить преобразователь для NER на датском языке, мы можем использовать набор данных DaNE, состоящий из датских предложений с аннотациями NER.

Все, что вам нужно было бы изменить в предыдущем примере кода, чтобы добиться этого, это просто:

from NERDA.datasets import get_dane_data
model = NERDA(
...,
dataset_training = get_dane_data('train'),
dataset_validation = get_dane_data('dev'),
...
)

Если у вас нет (или просто недостаточно) обучающих данных с аннотациями NER для желаемого языка, вы можете использовать такие инструменты, как doccano, для аннотирования новых текстов.

Удивительно, но тонкая настройка NERDA для конкретного языка не требует такого количества аннотированных данных, как вы могли подумать, поскольку NERDA использует знания, которые уже существуют в преобразователе. Датский набор данных NER DaNE, например, включает не более 5500 предложений, чего достаточно для обучения NERDA моделей с разумной производительностью.

О `NERDA`

NERDA разработан в рамках деятельности Ekstra Bladet по платформе Intelligence in News (PIN). PIN - это промышленный исследовательский проект, который осуществляется в сотрудничестве между Техническим университетом Дании, Копенгагенским университетом и Копенгагенской школой бизнеса при финансовой поддержке Инновационного фонда Дании. Проект работает с 2020-2023 гг. И разрабатывает рекомендательные системы и системы обработки естественного языка, предназначенные для публикации новостей, некоторые из которых имеют открытый исходный код, например NERDA.

Ресурсы









DaNE: ресурс именованных организаций для датского языка, Hvingelby et. al (2020) »