Высокопроизводительный морфологический анализатор для Python
Project description
steosmorphy: Руководство пользователя
steosmorphy — это высокопроизводительный морфологический анализатор для русского языка, предоставляющий Python-интерфейс к ядру, написанному на Go.
Ключевые особенности
- Знакомый API: Интерфейс и возможности во многом вдохновлены
pymorphy2. - Полный функционал: Включает разбор, лемматизацию, генерацию всех словоформ и предсказание несловарных слов.
- Корректная обработка супплетивизма: Правильно генерирует все формы для слов вроде
хороший -> лучший. - Высокая производительность: Скорость анализа составляет ~100 микросекунд на слово (~10 000 слов/сек на одном ядре CPU).
- При использовании пакетной обработки слов скорость достигает до ~20 микросекунд за одно слово
Оглавление
- steosmorphy: Руководство пользователя
1. Установка
Библиотека устанавливается из PyPI стандартной командой:
pip install steosmorphy
Пакет содержит уже скомпилированные бинарные файлы для операционных систем (Windows, Linux, macOS), поэтому установка Go не требуется.
2. Быстрый старт
Использовать библиотеку очень просто.
from steosmorphy import MorphAnalyzer
# 1. Инициализируем анализатор.
# Словарь загружается автоматически при первом создании объекта.
analyzer = MorphAnalyzer()
# 2. Анализируем слово
word = "стали"
result = analyzer.analyze(word)
# 3. Работаем с результатом
print(f"Варианты разбора для слова '{word}':")
# `result.parses` - это список всех возможных разборов
for p in result.parses:
print(f" - Лемма: {p.lemma:<10} Часть речи: {p.part_of_speech:<15} Падеж: {p.case}")
# `result.forms` - это список всех словоформ (лексема)
print(f"\nПримеры словоформ для '{word}':")
for p in result.forms[:5]: # Ограничим вывод
print(f" - {p.word}")
3. API и объекты результата
3.1. Метод analyze
Он принимает на вход слово и возвращает объект AnalysisResult, содержащий полный анализ. Если слово не найдено в словаре и не может быть предсказано, метод вернет None.
analyzer.analyze(word: str) -> AnalysisResult | None
3.2. Метод (parse_list)
Для достижения максимальной производительности при обработке большого количества слов используйте метод parse_list.
analyzer.parse_list(words: list[str]) -> list[Parsed]
Этот метод принимает на вход список слов, передает его целиком в ядро на Go, где он обрабатывается в многопоточном режиме, и возвращает единый список всех возможных разборов.
Почему это важно?
Каждый вызов analyze из Python несет в себе накладные расходы на "пересечение границы" между Python и Go. Метод
parse_list пересекает эту границу всего один раз для всего списка, что приводит к многократному (в 5-10 раз)
ускорению по сравнению с вызовом analyze в цикле.
Пример использования:
words = ["мама", "мыла", "раму", "стали", "программистка", "хороший"]
# Вызываем пакетную обработку
all_parses = analyzer.parse_list(words)
# `all_parses` - это плоский список всех разборов
# (для "стали" будет два объекта, итого 7)
for p in all_parses:
print(f"Слово: {p.word:<15} Лемма: {p.lemma:<15} ЧР: {p.part_of_speech}")
Рекомендация:
Всегда используйте parse_list, если вам нужно обработать более одного слова. Вызов analyze в цикле следует
применять только для анализа единичных, интерактивно вводимых слов.
ОСТОРОЖНО
Передача на вход метода слишком большого числа слов может потребовать большого объема оперативной памяти во время работы
метода.
Например, использование списка из 1 000 000 может использовать свыше 5ГБ ОЗУ!
3.3. Метод (inflect_list)
Работает аналогичным образом с методом parse_list, но возвращает список всех словоформ для каждого слова из входного списка.
analyzer.inflect_list(words: list[str]) -> list[Parsed]
3.4. Объект AnalysisResult
Это контейнер для всего результата анализа.
-
.parses(list[Parsed]) Список объектовParsed, представляющих все возможные варианты разбора для исходного слова. -
.forms(list[Parsed]) Список объектовParsed, представляющих все словоформы (полную лексему) для исходного слова. -
.first(Parsed | None) Удобный доступ к первому (самому вероятному) варианту разбора из списка.parses. Эквивалентноresult.parses[0].
3.5. Объект Parsed
Каждый *Parsed — это объект, содержащий полный разбор одной словоформы с доступом к полям через точку.
.word(str): Сама словоформа..lemma(str): Нормальная (словарная) форма..tags(str): "Сырая" строка тегов для отладки..part_of_speech(str): Часть речи..animacy(str): Одушевленность..aspect(str): Вид глагола..case(str): Падеж..gender(str): Род..mood(str): Наклонение..number(str): Число..person(str): Лицо..tense(str): Время..transitivity(str): Переходность..voice(str): Залог..other_tags(set[str]): Множество прочих тегов.
4. Примеры использования
4.1. Разбор неоднозначности
Многие слова в русском языке неоднозначны. analyze вернет все варианты в списке .parses.
result = analyzer.analyze("стекла")
for p in result.parses:
if p.part_of_speech == "Глагол":
print(f"Это глагол '{p.lemma}' в форме {p.gender} рода, {p.tense} времени.")
# -> Это глагол 'стечь' в форме Средний рода, Прошедшее времени.
elif p.part_of_speech == "Существительное":
print(f"Это существительное '{p.lemma}' в {p.case} падеже.")
# -> Это существительное 'стекло' в Родительный падеже.
4.2. Генерация словоформ и супплетивизм
Список .forms содержит полную лексему слова, включая формы, образованные от разных корней.
result = analyzer.analyze("хорошая")
# `result.forms` будет содержать *полную* лексему
all_forms = {p.word for p in result.forms}
print("лучший" in all_forms) # -> True
print("хорошую" in all_forms) # -> True
4.3. Работа с несловарными словами
Если слово не найдено в словаре, анализатор автоматически пытается его предсказать.
result = analyzer.analyze("нейросеть")
p = result.first
print(p.lemma) # -> нейросеть
print(p.part_of_speech) # -> Существительное
print(p.gender) # -> Женский
# Будут также сгенерированы все предсказанные словоформы
forms = {f.word for f in result.forms}
print("нейросетей" in forms) # -> True
5. Производительность
steosmorphy спроектирован для высокой производительности.
- Скорость (одно слово): Среднее время анализа одного слова через
analyze()составляет около ~100 микросекунд. - Память: Потребление оперативной памяти остается стабильно низким (~100-150 МБ).
- Пакетная обработка: При использовании методов
parse_list()/inflect_list()среднее время на слово приближается к нативным ~20 микросекундам, что позволяет обрабатывать до 50 000 слов в секунду на одном ядре CPU.
---
## 6. Тестирование
#### Требования для тестов Python
Перед запуском убедитесь, что вы установили все необходимые зависимости для разработки:
```bash
pip install pytest pytest-benchmark
Также убедитесь, что ваш пакет steosmorphy установлен, желательно в режиме редактирования:
pip install -e .
Юнит- и интеграционные тесты
Файл tests/test_analyzer.py содержит тесты, которые проверяют корректность разбора и генерации словоформ.
Как запустить: Находясь в корне проекта, выполните команду:
pytest
pytest автоматически найдет и запустит все тесты. Для подробного вывода используйте флаги -v (verbose) и -s (чтобы видеть вывод print).
Нагрузочные тесты и бенчмарки
-
Микро-бенчмарки (
tests/test_benchmark.py): Измеряют точное время выполнения одного вызоваanalyzeдля разных типов слов. Запускаются с помощью плагинаpytest-benchmark.Как запустить:
pytest --benchmark-onlyВы увидите подробную статистическую таблицу со средним, медианным, минимальным и максимальным временем выполнения.
-
Нагрузочные тесты (
tests/test_load.py): Эмулируют реальную нагрузку, прогоняя через анализатор сотни тысяч и миллионы случайных слов. Эти тесты измеряют общую "пропускную способность" (слов в секунду) и помогают выявить утечки памяти или деградацию производительности под нагрузкой.Как запустить:
pytest -v -s tests/test_load.py
Наличие такой всеобъемлющей тестовой системы позволяет гарантировать высокое качество и надежность библиотеки steosmorphy.
7. Зависимости и окружение
Для работы библиотеки (Runtime)
Конечный пользователь, устанавливающий ваш пакет через pip, не нуждается ни в каких внешних зависимостях, так как все
необходимое встроено в Python.
- Python: Требуется версия Python 3.7 или новее.
- Используемые стандартные библиотеки:
ctypes: Для взаимодействия со скомпилированной Go-библиотекой (.dll/.so).json: Для десериализации результатов, полученных от Go.platform: Для определения операционной системы и выбора правильного файла библиотеки.importlib.resources: Для надежного поиска файлов (.dll,.dawg) внутри установленного пакета.
Для разработки и тестирования (Development)
Если вы хотите вносить изменения или запускать тесты, вам понадобятся следующие инструменты:
pytest: Мощный фреймворк для написания и запуска юнит-тестов и интеграционных тестов.pytest-benchmark: Плагин дляpytestдля проведения тестов производительности (микро-бенчмарков).
Установить их можно командой:
pip install pytest pytest-benchmark
8. Справочник по граммемам
Каждый успешный разбор слова возвращается в виде объекта Parsed. Этот раздел подробно описывает каждое поле этого
объекта и возможные значения, которые оно может принимать.
Основные поля
-
word(str) Исходная словоформа, которая была передана на анализ или сгенерирована. Пример: "коту", "стали", "хорошая". -
lemma(str) Нормальная форма слова. Для существительных — именительный падеж, единственное число. Для глаголов — инфинитив. Для прилагательных — именительный падеж, единственное число, мужской род. Пример: "кот", "стать", "хороший". -
tags(string) Все грамматические теги в виде строки, разделенных запятой. Полезна для отладки или для случаев, когда требуется полный набор граммем в одной строке. Пример:"Существительное,Одушевленное,Мужской,Единственное число,Дательный".
Грамматические категории
-
part_of_speech(str) Часть речи. Это основная категория слова.СуществительноеПрилагательноеГлаголНаречиеПричастиеДеепричастиеМестоимениеЧислительноеПредлогЧастицаСоюзМеждометиеВводное слово
-
animacy(str) Одушевленность. Категория, присущая существительным и согласующимся с ними частям речи.ОдушевленноеНеодушевленное
-
aspect(str) Вид. Характеристика глаголов, причастий и деепричастий.СовершенныйНесовершенныйДвувидовой
-
case(str) Падеж. Одна из ключевых характеристик для склоняемых частей речи.ИменительныйРодительныйДательныйВинительныйТворительныйПредложныйЗвательный(для обращений, напр., "боже")Местный(напр., "в лесу")Счетный(напр., "два часа")Партитивный(напр., "чашка чаю")Ждательный(специфический падеж, напр., "ждать письма")Несклоняемый(для несклоняемых слов, напр., "пальто")
-
gender(str) Род.МужскойЖенскийСреднийОбщий(напр., "сирота", "умница")Парный(используется для обозначения парных предметов, но редко встречается)
-
mood(str) Наклонение. Характеристика глагола.Повелительное(indc - изъявительное - обычно опускается)
-
number(str) Число.Единственное числоМножественное число
-
person(str) Лицо. Характеристика глаголов в настоящем/будущем времени и личных местоимений.1-е лицо(я, мы)2-е лицо(ты, вы)3-е лицо(он, она, оно, они)нет лица(для безличных глаголов)
-
tense(str) Время. Характеристика глагола.ПрошедшееНастоящееБудущее
-
transitivity(str) Переходность. Способность глагола сочетаться с дополнением в винительном падеже без предлога.ПереходныйНепереходныйЛабильный(может быть и переходным, и непереходным)
-
voice(str) Залог. Характеристика причастий.ДействительныйСтрадательный
-
other_tags(set[str]) Множество для всех остальных граммем, которые не попали в основные поля. Это позволяет сохранить всю информацию из исходного словаря. Примеры: "Краткая форма", "Сравнительная степень", "Имя собственное", "Фамилия", "Сокращение", "Разговорное" и т.д.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file steosmorphy-1.0.0.tar.gz.
File metadata
- Download URL: steosmorphy-1.0.0.tar.gz
- Upload date:
- Size: 102.9 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b618f238de3ecc891420982769a038c5f8f1457cea8eb625c990fd27a7be15f9
|
|
| MD5 |
2b68f912170c64419c7068d860627cbb
|
|
| BLAKE2b-256 |
f1d28f0522b406afc844dc2c0af692332d9fd5cdc8551b506094d220d1b98b0f
|
File details
Details for the file steosmorphy-1.0.0-py3-none-any.whl.
File metadata
- Download URL: steosmorphy-1.0.0-py3-none-any.whl
- Upload date:
- Size: 102.9 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0492aa2974bb1185232cd07159730c7684af2464089cf9294b8acf047964097f
|
|
| MD5 |
d88fdc262d1b20f385bc6cd3c26dbefb
|
|
| BLAKE2b-256 |
2cc0fa218ebafe8c85e3729bc52bf6bd500c8139c24a9322aa7a3759e7737ee3
|