?

Log in

No account? Create an account

Компьютерная лингвистика

Новостная лента www.solarix.ru

Previous Entry Share Next Entry
Аугментация и генерация NLP датасетов с помощью ruword2tags.RuFlexer
kelijah
В библиотеку ruword2tags добавлен новый класс RuFlexer, содержащий инструменты для генеративных текстовых моделей. Сейчас этот класс предоставляет единственный метод find_forms_by_tags для подбора форм слова с заданными тегами. Например, чтобы найти форму слова "кошка" для творительного падежа множественного числа, надо написать примерно такой код:

import ruword2tags

flexer = ruword2tags.RuFlexer()
flexer.load()

forms = flexer.find_forms_by_tags(u'кошка', [(u'ПАДЕЖ', u'ТВОР'), (u'ЧИСЛО', u'МН')])
print(list(forms))




Зачем это может пригодиться? Для аугментации и генерации текстовых датасетов в NLP.

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

Возьмем, к примеру, такую задачку. У нас некий алгоритм выдает тестовые фразы на заданную тему, по многу вариантов для каждого исходного мешка слов. Среди них есть как вполне нормальные, так и немного корявые фразы типа:

Ты любишь есть на яблочки.

Для отсева невалидных вариантов можно использовать 2- и 3-граммы, но они все равно пропускают часть таких случаев, особенно для редкой лексики (вдруг я люблю маракуйю, а яблоки не ем? то-то же). Одно из решений проблемы - анализировать дерево зависимостей и проверять статистику сочетаемости актантов с конкретным глаголом-сказуемым. Другой способ - нейросетевая модель детектора валидности предложения, которая заодно отсекала бы бессмыслицу типа "Я люблю в яблоки". В обоих случаях нам нужны сэмплы с правильными и неправильными предложениями. И в отличие от других ситуаций тут нельзя просто нагенерировать негативных примеров через подстановку/замену рандомных слов в правильных фразах, так как вышеупомянутый алгоритм выдает в общем-то синтаксически валидные фразы, в которых случайных слов не бывает.

Составлять такой датасет руками - адская вещь. В этом тоже есть грустная ирония NLP. Кто хочет, может попробовать написать хотя бы 100 разных предложений с ошибками ("Тебе наплевать близ наших картинок" и т.д.). Увы, креативность - не самая сильная черта человеческого языкового движка, и через некоторое время автор такого нонсенса скатывается в вариации на тему какого-то одного случая, а потом вообще бросает занятие. А сэмлов надо много, особенно для нейросетевого классификатора. Тысячи.

Тут может помочь аугментация, в частности шаблонная генерация негативных сэмплов из годных предложений (см. например https://medium.com/@jetbootsmaker/fountain-%D0%B0%D1%83%D0%B3%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%86%D0%B8%D1%8F-%D0%B4%D0%BB%D1%8F-%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%BE%D0%B2%D1%8B%D1%85-%D0%B4%D0%B0%D1%82%D0%B0%D1%81%D0%B5%D1%82%D0%BE%D0%B2-8d4c6940864f). Самый простой подход такой. Берем фразу с предлогом, заменяем предлог на рандомный, при необходимости пересогласуем зависящие от предлога элементы группы существительного.

Примеры работы этого алгоритма:

Исходное предложение: "Почему ты уверен в своей правоте"

Результаты генерации:

Почему ты уверен подобно своей правоте
Почему ты уверен вроде своей правоты
Почему ты уверен наравне со своею правотою
Почему ты уверен без оглядки на свою правоту
Почему ты уверен предо своею правотою
Почему ты уверен в честь своей правоты
Почему ты уверен среди своей правоты
Почему ты уверен параллельно своей правоте



Исходное предложение: "Ты решилась на местный вариант шавермы."

Результаты генерации:

Ты решилась внутрь местного варианта шавермы.
Ты решилась наперерез местному варианту шавермы.
Ты решилась по направлению к местному варианту шавермы.
Ты решилась обо местный вариант шавермы.
Ты решилась средь местного варианта шавермы.
Ты решилась согласно местному варианту шавермы.
Ты решилась за местный вариант шавермы.
Ты решилась следом за местным вариантом шавермы.
Ты решилась сроком на местный вариант шавермы.
Ты решилась кроме местного варианта шавермы.



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

Код генератора на Питоне с использованием библиотек ruword2tags, rulemma, rupostagger и rutokenizer: https://gist.github.com/Koziev/cd7ee3c0b9a264d147e787126eb7059a
PS: Юрий Бабуров подкинул еще хорошую статью по теме аугментации в NLP: https://towardsdatascience.com/these-are-the-easiest-data-augmentation-techniques-in-natural-language-processing-you-can-think-of-88e393fd610
Касательно упоминаемой в этой статье подстановки синонимов для русскоязычных датасетов я, возможно, выложу и свой примерчик.