Mnogoznal

Материал из NLPub
Перейти к: навигация, поиск

Mnogoznal — система разрешения лексической многозначности на основе обучения без учителя. Реализация системы выполнена на языке программирования Python.

Веб-интерфейс системы Mnogoznal.

Возможности

  • Разрешение лексической многозначности в предложениях на основе обучения без учителя.
  • Интеграция с анализатором Mystem для морфологической разметки.
  • Интерфейс прикладного программирования на языке Python.
  • Интерфейс командной строки для интеграции в командные сценарии.
  • Эффективная загрузка векторов слов при помощи сервера Word2Vec-Pyro4.

Алгоритм

Разреженная модель

Значение некоторого заданного слова w выбирается как

\hat{w} \gets \arg\max_{S \ni w} \cos(S, T),

где \hat{w} — синсет, соответствующий наиболее близкому значению слова w, S — синсет, T — предложение.

Плотая модель

Значение некоторого заданного слова w выбирается как

\hat{w} \gets \arg\max_{S \ni w} \cos(\vec{S}, \vec{T}),

где \vec{S} — векторное представление синсета, \vec{T} — векторное представление предложения.

В соответствии с методом SenseGram, векторные представления синсета и предложения получаются путём усреднения векторных представлений составляющих их слов:

\vec{S} \gets \frac{1}{|S|} \sum_{w \in S} \vec{w}.

Реализация

Системная архитектура

Предложение представлено в виде списка фрагментов. Фрагмент — это кортеж из четырех элементов: (w, p, l, i), где w — слово, p — часть речи, l — лемма, i — позиция слова в предложении. Эти данные предоставляются программой разрешения морфологической неоднозначности. Результаты разрешения лексической многозначности представляются в виде отображения фрагментов в соответствующие идентификаторы значений слова.

Инвентарь значений — это список синсетов. Синсет представлен тремя мешками слов: синонимами, гиперонимами и объединением двух предыдущих — мешком. Для повышения производительности, инвентарь значений также имеет инвертированный индекс, который отображает слово в набор синсетов, в которые он входит.

Каждый метод распознавания значения слова расширяет класс BaseWSD. Этот класс предоставляет конечному пользователю общий интерфейс для WSD, а также инкапсулирует общие процедуры для предварительной обработки данных. Унаследованные классы, такие как SparseWSD и DenseWSD, должны реализовать метод disambiguate_word(…), который устраняет неоднозначность запрашиваемого слова в запрашиваемом предложении. Оба класса используют мешок слов при инициализации. В результате для WSD используются не только синонимы, но и гиперонимы, соответствующие синсетам.

Подход к развертыванию

Модель развертывания состоит из трех узлов. Первый — внешний HTTP-сервер обратного прокси-сервера принимает пользовательские запросы и передает их во внутреннюю систему. Второй — Mnogoznal, работающий как приложение uWSGI, обрабатывает запросы пользователей и возвращает результаты на внешний сервер. Наконец, в случае использования плотного режима Mnogoznal использует сервер векторов слов для уменьшения использования памяти.

Пользовательский интерфейс

Пример разрешения лексической многозначности.

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

Использование

Командная строка

Для использования командной строки для начала нужно определить аргументы для парсера, которые определят такие параметры, как инвентарь синсетов, путь до mystem, модель обработки. Если выбрана плотная модель, то следует задать путь до файла с векторами слов или до pyro сервера.

parser = argparse.ArgumentParser(description='WSD.')
parser.add_argument('--inventory', required=True, type=argparse.FileType('r', encoding='UTF-8'))
parser.add_argument('--mystem', required=True, type=argparse.FileType('rb'))
parser.add_argument('--mode', choices=('sparse', 'dense'), default='sparse', type=str)
group = parser.add_mutually_exclusive_group()
group.add_argument('--w2v', default=None, type=argparse.FileType('rb'))
group.add_argument('--pyro', default=None, type=str)
args = parser.parse_args()

Заданные аргументы передаются в конструктор класса выбранного режима. Запрашиваемый текст передается в функцию mystem для морфологической разметки.

inventory = mnogoznal.Inventory(inventory_path=args.inventory.name)

if args.mode == 'sparse':
    wsd = mnogoznal.SparseWSD(inventory=inventory)
elif args.mode == 'dense':
    if args.w2v:
        from gensim.models import KeyedVectors
        w2v = KeyedVectors.load_word2vec_format(args.w2v, binary=True, unicode_errors='ignore')
        w2v.init_sims(replace=True)
    elif args.pyro:
        from mnogoznal.pyro_vectors import PyroVectors as PyroVectors
        w2v = PyroVectors(args.pyro)
    else:
        print('Please set the --w2v or --pyro option to engage the dense mode.', file=sys.stderr)
        exit(1)

    wsd = mnogoznal.DenseWSD(inventory=inventory, wv=w2v)

sentences = mnogoznal.mystem(input())

В конце вызывается функция wsd.disambiguate для каждого предложения, и выводится конечный результат.

def disambiguate(index):
    return wsd.disambiguate(sentences[index])

with concurrent.futures.ProcessPoolExecutor() as executor:
    for i, result in enumerate(executor.map(disambiguate, range(len(sentences)))):
        for (word, lemma, pos, _), id in result.items():
            print('\t'.join((word, lemma, pos, id if id is not None else '')))

        if i + 1 < len(sentences):
            print()

Программный интерфейс

Для того чтобы начать, необходимо задать файл с набором синсетов Inventory, на котором будет основана работа алгоритма. Этот набор передается в конструктор класса режима работы. Для использования разреженной модели необходимо использовать класс SparseWSD. Затем текст передается в функцию mnogoznal.mystem, которая на выходе дает список предложений, состоящий из кортежей четырех элементов для каждого слова: исходная форма слова, лемма, часть речи, номер подходящего синсета.

from mnogoznal import Inventory, SparseWSD, mystem

inventory = Inventory('….tsv')
wsd = SparseWSD(inventory)

sentences = mystem('Статья содержит описание экспериментов.')

for sentence in sentences:
    for (word, lemma, pos, _), id in wsd.disambiguate(sentence).items():
        print((word, lemma, pos, id))
('Статья', 'статья', 'S', '12641')
('содержит', 'содержать', 'V', '3240')
('описание', 'описание', 'S', '24626')
('экспериментов', 'эксперимент', 'S', '36055')
('.', '.', 'UNKNOWN', None)

Для плотной модели необходимо загрузить вектора слов с помощью Gensim и использовать класс DenseWSD. Остальная часть кода идентична.

from gensim.models import KeyedVectors
wv = KeyedVectors.load_word2vec_format('….w2v', binary=True, unicode_errors='ignore')
wv.init_sims(replace=True)

wsd = DenseWSD(inventory, wv)

Также возможно и очень удобно использовать удаленные словарные векторы, обслуживаемые word2vec-pyro4 , а не Gensim.

from mnogoznal.pyro_vectors import PyroVectors as PyroVectors
wv = PyroVectors('PYRO:w2v@…:9090')

wsd = DenseWSD(inventory, wv)

Запустить веб-сервис можно следующим образом:

INVENTORY=….tsv W2V_PATH=….w2v FLASK_APP=mnogoznal_web.py flask run или INVENTORY=….tsv W2V_PYRO=PYRO:w2v@…:9090 FLASK_APP=mnogoznal_web.py flask run

Кроме того, можно запустить веб-службу непосредственно из Docker Hub:

docker run --rm -p 5000:5000 -e INVENTORY=….tsv -v ….tsv:/usr/src/app/….tsv:ro

Оценка качества

Метод оценки качества разрешения лексической многозначности представлен в программе eval/measure.py. Программа работает в режиме командной строки и принимает следующие аргументы:

  • --gold — путь к файлу с золотым стандартом;
  • --measure — мера качества: vmeasure (по умолчанию) или ari;
  • --average — усреднение для вычисления общей оценки: instances (по умолчанию) или words;
  • path — путь к файлам с результатами разрешения лексической многозначности.

Формат файла с входными данными совпадает с текстовым форматом дорожки SemEval 2010 Task 14. Формат файла с результатами оценки — TSV с заголовком. При использовании скорректированного коэффициента Рэнда поля: path — путь к файлу с результами, для которого получены оценки, lemma — идентификатор леммы, ari — значение меры качества. При использовании V-меры вместо последнего поля используется три: homogeneity, completeness, vmeasure. Пустое поле с мерой качества означает общую для всего набора данных оценку.

$ eval/measure.py --measure=ari --gold=nouns.key nouns-dense.key

При работе с результатами удобно использовать сортировку и разбиение по колонкам в терминале: column -ts $'\t' | less.

Цитирование

@inproceedings{Ustalov:17:sibircon,
  author    = {Ustalov, D. and Teslenko, D. and Panchenko, A. and Chernoskutov, M.},
  title     = {{Mnogoznal: an Unsupervised System for Word Sense Disambiguation}},
  booktitle = {2017 International Multi-Conference on Engineering, Computer and Information Sciences (SIBIRCON)},
  year      = {2017},
  pages     = {147--150},
  isbn      = {978-1-5386-1595-9},
  address   = {Novosibirsk, Russia},
  publisher = {IEEE},
  doi       = {10.1109/SIBIRCON.2017.8109857},
  language  = {english},
}

Ссылки

См. также

Примечания