О
Эта статья представляет собой введение в библиотеку POTATO. POTATO — это независимая от языка среда XAI (объяснимый искусственный интеллект) для извлечения и оценки интерпретируемых функций графа для любой задачи классификации в обработке естественного языка (NLP).
Статья включает в себя:
- Краткое введение в основанные на правилах методы классификации текста
- Введение в определение шаблонов графов в POTATO
- Автоматическое изучение шаблонов
- Структура «человек в контуре» (HITL)
Введение
В настоящее время в задачах обработки текста (как и во многих других областях) преобладают модели машинного обучения. Но поскольку параметры этих моделей растут в геометрической прогрессии, объяснимость снижается.
Интерпретируемые модели среди прочего обладают следующими чертами [1]:
- Справедливость — беспристрастные прогнозы.
- Конфиденциальность — меньше утечки информации
- Надежность — небольшие изменения на входе не сильно влияют на результат
- Доверие, возможность аудита — мы знаем, чем вызваны прогнозы.
- Отладка: если в производственной среде возникает ошибка, мы можем изменить модель.
Недавние решения NLP, достигшие самых современных результатов в общедоступных тестах, основаны на моделях глубокого обучения (DL) с миллионами параметров (например, BERT [2]). Эти модели требуют больших объемов обучающих данных, и их решения трудно объяснить [3]. Кроме того, модели глубокого обучения создают риск непреднамеренной систематической ошибки в наборах данных [4]. Системы, основанные на правилах, могут предоставлять точные и прозрачные решения, но могут быть сложными и трудоемкими для создания и обслуживания. POTATO — это платформа быстрого прототипирования, поддерживающая создание классификаторов текста на основе правил. В POTATO вместо использования моделей машинного обучения для непосредственного изучения задачи мы вместо этого изучаем системы правил. При использовании этого метода конечная модель остается полностью прозрачной.
Системы на основе правил
Плюсы
- Системы, основанные на правилах, интерпретируемы и объяснимы по своей структуре.
- Популярны в «реальных» приложениях, и нет необходимости в крупных первоначальных вложениях (нет необходимости в графических процессорах).
- Полностью настраиваемый и может быть отлажен
Минусы
- Трудно поддерживать
- Хуже производительность на бенчмарках (в бенчмарках преобладают методы глубокого обучения)
- Нужна экспертиза домена
- Отнимает много времени на поддержание и развитие
В POTATO мы пытаемся устранить некоторые недостатки моделей, основанных на правилах, путем объединения машинного обучения и систем правил: изучайте правила!
Чтобы продемонстрировать системы правил, мы будем использовать пример из набора данных Semeval 2010 Relation Extraction. Извлечение отношений (RE) — это задача извлечения семантических отношений между сущностями из текста. Обычно определяется между двумя объектами. Отношения имеют семантические категории (например, Назначение, Компонент, Кем используется, Кем основан и т. д.), и задача состоит в том, чтобы отнести отношение к правильной категории.
Мы будем использовать только метку Entity-Destination. Пример для класса:
- Бриллиантовое кольцо(entity1)было брошено в сумку кондитера(entity2).
Чтобы определить правило, мы могли бы просто использовать простое регулярное выражение:
r”entity1 .* dropped into .* entity2"
Но использование только регулярных выражений — наивный метод, так как мы ничего не знаем о структуре текста (токены, грамматические категории и т. д.). Мы могли бы использовать более продвинутые пакеты Python, такие как SpaCy’s TokenMatcher или Holmes Extractor. С ними мы могли бы определить более сложное правило, учитывающее теги части речи (POS) (грамматическая категория слов):
pattern = [{‘POS’: ‘VERB’}, {‘LOWER’: ‘into’}, {‘TEXT’: {‘REGEX’: ‘.*’}}, {‘LOWER’: ‘entity2’}]
Но вместо того, чтобы писать правила для токенов текста, мы можем написать правила для графов, которые могли бы использовать базовую графовую структуру текстов. В POTATO мы используем пакет python networkx для представления графиков. С помощью networkx мы предоставляем унифицированный интерфейс для представления графов, и пользователи могут создавать шаблоны графов на произвольных графах. В настоящее время в POTATO поддерживаются три типа графов: AMR[5], UD(с использованием пакета stanza [6]) и 4lang [7]. ]. Пример шаблона можно увидеть на рисунке 1, а на рисунке 2 мы видим график 4lang примера, который мы определили выше (бриллиантовое кольцо было переброшено в сумка от кондитера) и нанесенный рисунок.
В отличие от простых шаблонов регулярных выражений, этот шаблон также будет соответствовать следующим примерам:
The man placed the entity1 into the entity2. Industries have pushed entity1 into fragile marine entity2. I am putting the entity1 into a MySQL entity2. The entity1 were released into the entity2.
Использование и настройка
POTATO — это XAI-фреймворк, написанный на python и обеспечивающий:
- единый сетевой интерфейс для нескольких графических библиотек (4lang, stanza, AMR)
- пакет python для изучения и оценки интерпретируемых функций графа как правил
- инфраструктура пользовательского интерфейса человек в цикле (HITL), встроенная в streamlit
- REST-API для использования извлеченных функций для логического вывода в производственном режиме
Все наши компоненты имеют открытый исходный код под лицензией MIT и могут быть установлены с помощью pip.
Инструмент сильно зависит от репозитория tuw-nlp для построения графиков и сопоставления функций. Вы можете установить tuw-nlp с помощью pip:
pip install tuw-nlp
Затем следуйте инструкциям по установке пакета.
Затем установите POTATO из pip:
pip install xpotato
Первые импортные упаковки из картофеля:
from xpotato.dataset.dataset import Dataset from xpotato.models.trainer import GraphTrainer
Мы продемонстрируем возможности POTATO на нескольких предложениях, выбранных вручную из набора данных Semeval [8].
Обратите внимание, что мы заменили два рассматриваемых объекта на XXX и YYY.
Затем следующим шагом является инициализация набора данных, а также предоставление кодировки метки. Затем разберите предложения на графики, для этого мы можем использовать метод parse_graphs() (также необходимо выбрать формат графика). В настоящее время мы предоставляем три типа графиков: ud, fourlang, amr. Также вы указываете язык, который хотите анализировать. В настоящее время мы поддерживаем английский (en) и немецкий (de).
Мы будем использовать пример из таблицы 1 (мы будем ссылаться на образцы с их идентификаторами, указанными в первом столбце). Примеры, инициализированные в python, можно выполнить с помощью следующего кода:
dataset = Dataset(sentences, label_vocab={"Other":0, "Entity-Destination(e1,e2)": 1}) dataset.set_graphs(dataset.parse_graphs(graph_format="fourlang"))
Проверьте набор данных:
df = dataset.to_dataframe()
Мы также можем проверить любой из проанализированных графов
from xpotato.models.utils import to_dot from graphviz import Source Source(to_dot(dataset.graphs[0]))
Написание правил с POTATO
Если набор данных подготовлен и графики проанализированы, мы можем написать правила для сопоставления меток. Мы можем писать правила либо вручную, либо извлекать их автоматически (POTATO также предоставляет интерфейс, который делает и то, и другое).
Простейшим правилом будет просто узел в графе (в данном случае into):
# The syntax of the rules # List[List[rules that we want to match] # List[rules that shouldn't be in the matched graphs] # Label of the rule rule_to_match = [[["(u_1 / into)"], [], "Entity-Destination(e1,e2)"]]
Запустите средство сопоставления правил:
from xpotato.graph_extractor.extract import FeatureEvaluator evaluator = FeatureEvaluator()
Сопоставьте правила в наборе данных:
# The function will return a dataframe with the matched instances: evaluator.match_features(df, rule_to_match)
Функция вернет кадр данных с совпавшими примерами. Это правило будет соответствовать любому предложению, в котором есть узел в. В нашем случае мы сопоставили бы примеры с номерами 0, 1, 2, 3, 4, 5, 6, 9, 14 из таблицы 1 (например, Ученые налили XXX в пинту YYY.)
Одной из основных особенностей нашего инструмента является то, что мы также можем сопоставлять подграфы. Для описания графа мы используем нотацию PENMAN.
Например. строка (u_1 / into :1 (u_3 / pour)) будет описывать граф с двумя узлами ("into" и "pour" ) и одно направленное ребро с меткой «1» между ними. Описание подграфа строкой (u_1 / into :1 (u_2 / pour) :2 (u_3 / YYY)) вернет только три примера вместо 9, когда у нас был только один узел в качестве особенность.
#match a simple graph feature evaluator.match_features(df, [[[“(u_1 / into :1 (u_2 / pour) :2 (u_3 / YYY))”], [], “Entity-Destination(e1,e2)”]])
Эта функция будет соответствовать примерам 0, 1, 9.
Мы также можем добавить отрицательные функции, которые мы не хотим сопоставлять (это не будет соответствовать первой строке, где присутствует «pour»):
# match a simple graph feature with a negated feature. #The negated features go into the second parameter. evaluator.match_features(df, [[[“(u_1 / into :2 (u_3 / YYY))”], [“(u_2 / pour)”], “Entity-Destination(e1,e2)”]])
Соответствие примерам 2, 3, 5, 6.
Если мы не хотим указывать узлы, можно использовать регулярное выражение вместо имен узлов и ребер:
# regex can be used to match any node (this will match instances # where ‘into’ is connected to any node with ‘1’ edge) evaluator.match_features(df, [[[“(u_1 / into :1 (u_2 / .*) :2 (u_3 / YYY))”], [], “Entity-Destination(e1,e2)”]])
Мы также можем уточнить правила регулярного выражения на основе обучающих данных, это автоматически заменит регулярное выражение ‘.*’ узлами с высокой точностью.
evaluator.train_feature("Entity-Destination(e1,e2)", "(u_1 / into :1 (u_2 / .*) :2 (u_3 / YYY))", df)
Это возвращает (u_1 / into :1 (u_2 / push|pour) :2 (u_3 / YYY)) (заменяет '.*' на push и налить)
Изучение правил «человек в цикле»
Идея POTATO:
- Используйте подграфы в качестве признаков для обучения простых классификаторов (LogReg, Random Forest и т. д.)
- Создавайте подграфы только до определенного числа ребер (чтобы избежать большого количества функций)
- Предлагайте правила пользователям в зависимости от важности функции
- С пользовательским интерфейсом пользователь может принимать, отклонять, редактировать, комбинировать шаблоны.
- Подграфы могут иметь регулярные выражения в качестве меток узлов или ребер.
- Недоопределенные подграфы могут быть уточнены
Чтобы автоматически извлекать правила из помеченного набора данных, обучите набор данных графическими функциями и ранжируйте их на основе релевантности:
from sklearn.model_selection import train_test_split train, val = train_test_split(df, test_size=0.2, random_state=1234) trainer = GraphTrainer(train) features = trainer.prepare_and_train(min_edge=1)
Переменная features будет содержать автоматически извлеченные правила:
(u_15 / into :1 (u_26 / push)) (u_15 / into :1 (u_19 / pour :2 (u_0 / xxx))) (u_15 / into :1 (u_19 / pour)) (u_19 / pour :2 (u_0 / xxx)) (u_15 / into :2 (u_3 / yyy))
Пользовательский интерфейс
Помимо серверной части, описанной в предыдущих разделах, POTATO также поставляется с пользовательским интерфейсом HITL, позволяющим пользователю извлекать правила из набора данных. Для запуска пользовательского интерфейса HITL нам нужно загрузить набор данных в виде набора помеченных или неразмеченных графиков. Любой ориентированный граф может быть загружен, кроме предустановленных форматов (ud, 4lang, amr). Для предложения и оценки правил требуются наземные метки истинности (с использованием метода изучения функций, описанного в предыдущем разделе). Если они недоступны, пользовательский интерфейс можно запустить в расширенном режиме для начальной загрузки и аннотирования меток с помощью правил. После загрузки набора данных можно запустить интерфейс HITL, и пользователю будет представлен интерфейс, показанный на рисунке 3, созданный с использованием библиотеки streamlit.
Внешний интерфейс, показанный на рис. 3, обеспечивает:
- 1 — браузер набора данных, который позволяет пользователю просматривать текст, график и метки для всех строк набора данных. Вьювер визуализирует графики с помощью библиотеки graphviz, а также предоставляет нотацию PENMAN, которую пользователь может скопировать для быстрого редактирования правил.
- 2 — пользователи могут выбирать класс для работы (небольшое количество, если речь идет о классификации с несколькими метками).
- 3 —список правил, созданных для каждого класса, сохраняется в виде списка, и их можно изменять, удалять или добавлять новые функции.
- 4 — правила можно просматривать и оценивать в наборах данных для обучения и проверки.
- 5 –прогноз каждого правила можно проанализировать, просмотрев истинно положительные, ложноположительные или ложноотрицательные примеры.
- 6 —Кнопка «Предложить новые правила» возвращает список предлагаемых графиков вместе с их эффективностью на обучающих данных, позволяя пользователю выбрать те, которые следует добавить в список правил, этот интерфейс показан на рисунке. 4. Для правил, содержащих регулярные выражения, кнопка Уточнить заменит регулярные выражения дизъюнкцией высокоточных меток. Эта функция реализуется методом, описанным в предыдущем разделе.
Как описано, внешний интерфейс — это приложение с потоковой подсветкой, мы можем начать его с наборов данных для обучения и проверки. Сначала сохраните их с помощью следующего кода:
train.to_pickle(“train_dataset.pickle”) train.to_pickle(“val_dataset.pickle”)
Затем приложение Streamlit можно запустить с помощью одной строки команды:
streamlit run frontend/app.py -- -t train_dataset.
pickle-v val_dataset.
pickle
Правила для каждого класса автоматически сохраняются на диск в формате JSON, этот файл можно загрузить для дальнейшего редактирования или для вывода.
streamlit run frontend/app.py -- -t notebooks/train_dataset -v notebooks/val_dataset -hr features.json
Расширенный режим
Если метки не указаны или предоставлены частично, интерфейс можно запустить и в расширенном режиме, где пользователь может аннотировать несколько примеров в начале, затем система постепенно предлагает правила на основе приведенных примеров.
Затем можно запустить интерфейс:
streamlit run frontend/app.py -- -t unsupervised_dataset -m advanced
Оценивать
Если у вас есть готовые функции и вы хотите оценить их на тестовом наборе, вы можете запустить:
python scripts/evaluate.py -d test_dataset.pickle -f features.json
Результатом будет файл csv с метками и соответствующими правилами.
Услуга
Если вы готовы использовать извлеченные функции и хотите использовать наш пакет в производстве для логического вывода (генерирования прогнозов для предложений), мы также предоставляем REST API, построенный на POTATO (на основе fastapi).
Сначала установите FastAPI и Uvicorn
pip install fastapi pip install "uvicorn[standard]"
Чтобы запустить службу, вы должны установить язык, graph_type и функции для службы. Это можно сделать через переменные окружения.
Пример:
export FEATURE_PATH=/home/adaamko/projects/POTATO/features/semeval/test_features.json export GRAPH_FORMAT=ud export LANG=en
Затем запустите REST API:
python services/main.py
Он запустит службу, работающую на localhost через порт 8000 (а также инициализирует правильные модели).
Затем вы можете использовать любой клиент для отправки почтовых запросов:
curl -X POST localhost:8000 -H 'Content-Type: application/json' -d '{"text":"The suspect pushed the XXX into a deep YYY.\nSparky Anderson is making progress in his XXX from YYY and could return to managing the Detroit Tigers within a week."}'
Ответом будет список с предсказанными метками (если ни одно из правил не совпадает, будет возвращено «НЕТ»):
["Entity-Destination(e1,e2)","NONE"]
Интерфейс Streamlit также имеет режим вывода, в котором реализованная система правил может использоваться для вывода. Его можно начать с:
streamlit run frontend/app.py -- -hr features/semeval/test_features.json -m inference
Заключение
POTATO позволяет быстро создавать системы на основе правил и предоставляет прозрачное, объяснимое и проверяемое альтернативное решение для моделей глубокого обучения в задачах НЛП. Если вы хотите узнать больше о фреймворке или попробовать его, вы можете проверить следующие источники:
- Вы можете ознакомиться с нашей статьей POTATO: объяснимая структура извлечения информации
- Код фреймворка доступен на GitHub под лицензией MIT: https://github.com/adaamko/POTATO, вы также можете проверить репозиторий на наличие дополнительных примеров и готовых систем правил для нескольких задач.
- Также доступны Слайды с семинара по фреймворку
- Посмотрите наше короткое демонстрационное (~2 мин) видео об инструменте: https://youtu.be/PkQ71wUSeNU
- Есть более длинная версия с подробным описанием метода и представленным фоновым исследованием (~1 час): https://youtu.be/6R_V1WfIjsU
Рекомендации
[1] Дошивелез и др., На пути к строгой науке интерпретируемого машинного обучения, (2019)
[2] Девлин и др., Предварительная подготовка глубоких двунаправленных преобразователей для понимания языка, (2019)
[3] Серрано и др., Интерпретируемо ли внимание?, (2019)
[4] Бендер и др., Об опасностях стохастических попугаев: могут ли языковые модели быть слишком большими?, (2021)
[5] Банареску и др., Абстрактное представление значения для Sembanking, (2013)
[6] Ци и др., Stanza: набор инструментов для обработки естественного языка Python для многих человеческих языков, (2020)
[7] Корнаи и др., Семантика (2019)
[8] Хендрикс и др., SemEval-2010 Задача 8: Многофакторная классификация семантических отношений между парами именных (2010)