Привет, Хабр!

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

Natasha

Библиотека Natasha имеет множество функций включая токенизацию, морфологический анализ, лемматизацию, синтаксический анализ и извлечение именованных сущностей.

Токенизация и сегментация текста на предложения и токены в Natasha осуществляются с помощью встроенной библиотеки Razdel:

from razdel import tokenize, sentenize
text = "Текст для анализа."
tokens = list(tokenize(text))
sents = list(sentenize(text))

Морфологический анализатор Natasha, основанный на модели Slovnet, позволяет извлекать богатую морфологическую информацию о каждом токене, такую как часть речи, род, число и падеж:

from natasha import MorphVocab, Doc

morph_vocab = MorphVocab()
doc = Doc(text)
doc.segment(segmenter)
doc.tag_morph(morph_tagger)

for token in doc.tokens:
    print(token.text, token.pos, token.feats)

Лемматизация в Natasha производится на основе того же морфологического анализа и использует Pymorphy для приведения слов к их начальной форме:

for token in doc.tokens:
    token.lemmatize(morph_vocab)
    print(token.text, token.lemma)

Синтаксический анализатор Natasha основан на модели Slovnet и позволяет строить деревья зависимостей для предложений. Например, визуализации синтаксического анализа будет выглядеть так:

doc.parse_syntax(syntax_parser)
for sent in doc.sents:
    sent.syntax.print()

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

doc.tag_ner(ner_tagger)
for span in doc.spans:
    print(span.text, span.type)

DeepPavlov

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

Модели DeepPavlov могут быть легко интегрированы и использованы через различные интерфейсы, к примеру через командную строку, Python API, REST API и даже через Docker.

DeepPavlov также оптимизирован для работы с GPU.

Примеры использования

Классификация намерений помогает понять, что хочет пользователь, вводя запрос в чат-бота. Можно использовать предобученную модель для классификации намерений:

from deeppavlov import build_model, configs

# загрузка модели классификации намерений
intent_model = build_model(configs.classifiers.intents_snips, download=True)

# классификация намерения в запросе
intent_predictions = intent_model(['Book a flight from New York to San Francisco'])
print(intent_predictions)

Извлечение именованных сущностей используют для определения и классификации значимых информационных элементов в тексте:

ner_model = build_model(configs.ner.ner_ontonotes_bert_mult, download=True)

# извлечение сущностей из текста
ner_results = ner_model(['John works at Disney in California'])
print(ner_results)

Модель для ответов на вопросы позволяет системе находить ответы на вопросы, указанные в контексте:

qa_model = build_model(configs.squad.squad_bert, download=True)

# получение ответа на вопрос из предоставленного контекста
qa_result = qa_model(["What is the capital of France?", "The capital of France is Paris."])
print(qa_result)

mystem и pymorphy2

MyStem — это продукт от Яндекса, предоставляющий возможности для морфологического и синтаксического анализа текстов. Он работает как консольное приложение и доступен для различных операционных систем (Windows, Linux, MacOS). MyStem использует собственные алгоритмы для определения начальной формы слова и его грамматических характеристик

Например, базовая лемматизация и морфологический анализ:

from pymystem3 import Mystem

m = Mystem()
text = "Мама мыла раму каждый вечер перед сном."
lemmas = m.lemmatize(text)
print(''.join(lemmas))

analyzed = m.analyze(text)
for word_info in analyzed:
    if 'analysis' in word_info and word_info['analysis']:
        gr = word_info['analysis'][0]['gr']
        print(f"{word_info['text']} - {gr}")

PyMorphy2 также предоставляет функции для морфологического анализа текстов, но в отличие от MyStem, PyMorphy2 полностью открыта и развивается сообществом. Библиотека использует словари OpenCorpora для анализа и может работать с русским и украинским языком. PyMorphy2 также предлагает API.

Примеры использования:

Определение части речи и форм слова:

import pymorphy2

morph = pymorphy2.MorphAnalyzer()
word = 'стали'
parsed_word = morph.parse(word)[0]
print(f"Нормальная форма: {parsed_word.normal_form}")
print(f"Часть речи: {parsed_word.tag.POS}")
print(f"Полное морфологическое описание: {parsed_word.tag}")

Согласование слова с числом:

word = 'книга'
parsed_word = morph.parse(word)[0]
plural = parsed_word.make_agree_with_number(5).word
print(f"Множественное число слова '{word}': {plural}")

Работа с различными падежами:

word = 'город'
parsed_word = morph.parse(word)[0]
for case in ['nomn', 'gent', 'datv', 'accs', 'ablt', 'loct']:
    form = parsed_word.inflect({case}).word
    print(f"{case}: {form}")

Сравним эти библиотеки в таблице

Характеристика

MyStem

PyMorphy2

Исходный код

Закрытый

Открытый

Поддержка ОС

Windows, Linux, MacOS

Кроссплатформенный

Язык разработки

С++ (обертка Python)

Python

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

Да

Нет

Лицензия

Бесплатно для некоммерческого использования

MIT

Поддерживаемые языки

Только русский

Русский и украинский

Скорость работы

Быстрее на больших текстах

По некоторый данным медленнее, чем MyStem

RuBERT

RuBERT от DeepPavlov — это адаптация архитектуры BERT, специализированная для русского языка. Модель была предварительно обучена на корпусе, включающем русскоязычную Википедию и новостные данные. RuBERT использует мультиязычную версию BERT-base в качестве инициализации.

Используя RuBERT, можно реализовать систему классификации текста. Например, определить, относится ли текст к положительному или отрицательному отзыву:

from transformers import BertTokenizer, BertForSequenceClassification
from torch.nn.functional import softmax

# загрузка токенизатора и модели
tokenizer = BertTokenizer.from_pretrained('DeepPavlov/rubert-base-cased')
model = BertForSequenceClassification.from_pretrained('DeepPavlov/rubert-base-cased', num_labels=2)

# пример текста
text = "Этот продукт был отличным!"

# токенизация и создание входных данных для модели
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True, max_length=512)

# получение предсказаний
outputs = model(**inputs)
predictions = softmax(outputs.logits, dim=-1)

Для извлечения именованных сущностей можно адаптировать Conversational RuBERT, обучив его на соответствующей задаче NER:

from transformers import BertTokenizer, BertForTokenClassification
import torch

tokenizer = BertTokenizer.from_pretrained('DeepPavlov/rubert-base-cased-conversational')
model = BertForTokenClassification.from_pretrained('DeepPavlov/rubert-base-cased-conversational', num_labels=9)  # предполагаем 9 классов сущностей

text = "Анна поехала в Москву на выставку."

inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True, max_length=512)

# предсказание
with torch.no_grad():
    outputs = model(**inputs)
predictions = torch.argmax(outputs.logits, dim=-1)

# сопоставление предсказаний с токенами
tokens = tokenizer.convert_ids_to_tokens(inputs['input_ids'][0])
for token, prediction in zip(tokens, predictions[0]):
    print(f"{token} - {model.config.id2label[prediction.item()]}")

Подробнее про библиотеки можно прочесть здесь:

MyStem:
- MyStem на GitHub

PyMorphy2:
- PyMorphy2 на GitHub

RuBERT и другие модели DeepPavlov:
- RuBERT на Hugging Face
- Conversational RuBERT на Hugging Face
- DeepPavlov на GitHub


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

Комментарии (3)


  1. Jury_78
    19.04.2024 18:36
    +1

    для работы с русским языком

    Например так ? :)

    'Book a flight from New York to San Francisco'


  1. inkelyad
    19.04.2024 18:36

    И снова почти все написано с точки зрения анализа анализа текста.

    А про синтез есть?

    Чтобы инструмент по заданной (кстати, какой? По каким ключевым словам искать?) смысловой разметке позволял выбрать нужную форму и предлог для 'бежать' в 'видим бегущий вверх индикатор', 'видим бегущего вверх человека', "видим бегущего к двери человека', 'видим бегущего от опасности человека'

    Тот же pymorphy2 просто вываливает на тебя список из 99 форм - и разбирайся дальше как знаешь. Ибо работает, вроде бы, строго по одному слову.


  1. madrugado
    19.04.2024 18:36

    сейчас нужно использовать pymorphy3, т.к. pymorphy2 не развивается