Привет, Хабр!
В этой статье рассмотрим пять лучших библиотек 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, освоить различные языковые модели и создать собственный телеграм-бот можно на онлайн-курсе от экспертов-практиков.