Подсветка текста¶
ruts.visualizers.highlight()
Описание¶
Подсветка фрагментов текста, по которым считаются статистики библиотеки, в стиле сервисов Главред и Тургенев: длинные предложения, сложные слова, стоп-слова, пассив, причастные и деепричастные обороты, цепочки родительных падежей, аллитерации. Одна картинка объясняет, из чего складываются значения метрик, лучше таблицы чисел. В качестве источника данных может использоваться как непосредственно текст, так и объект класса Doc библиотеки spaCy.
Функция возвращает объект HighlightedText, который в Jupyter отображается как HTML со стилями и легендой; метод to_html возвращает ту же разметку для документации и веб-приложений. Фрагменты хранятся в атрибуте highlights и доступны для собственной отрисовки.
Слои подсветки:
| Слой | Что отмечает | Статистика |
|---|---|---|
long_sents |
Предложения с числом слов не меньше long_sent_word_factor |
BasicStats, ReadabilityStats |
complex_words |
Слова с числом слогов не меньше complex_syl_factor |
BasicStats, ReadabilityStats |
stopwords |
Стоп-слова по части речи или переданному списку - «вода» текста | StyleStats |
passive |
Пассивные глагольные формы вместе со вспомогательным глаголом | SyntaxStats |
participle_clauses |
Причастные обороты | SyntaxStats |
converb_clauses |
Деепричастные обороты | SyntaxStats |
genitive_chains |
Цепочки родительных падежей вместе с управляющим словом | SyntaxStats |
alliteration |
Повторы согласной в соседних словах, маловероятные при частотах букв русского языка | PhonStats |
Слои passive, participle_clauses, converb_clauses и genitive_chains считаются по дереву зависимостей и доступны только для объекта Doc с разбором зависимостей (модели ru_core_news_sm, ru_core_news_md, ru_core_news_lg); слой long_sents для Doc требует границ предложений. По умолчанию включаются все слои, доступные источнику.
Примечание
Аллитерация ищется внутри предложения как цепочка из двух и более соседних слов, в основе каждого из которых есть одна и та же согласная буква. Основа - общая начальная часть словоформы и ее леммы по pymorphy3 (крупных → крупны, руках → рука): окончания согласуются с соседними словами и повторяют согласные по грамматике, а не по звучанию (этих крупных, своим целям и нуждам). Вероятность цепочки при независимом распределении букв - произведение по словам вероятностей встретить согласную среди букв основы, \(1 - (1 - f)^n\), где \(f\) - частота согласной в русских текстах, \(n\) - число букв основы; цепочка подсвечивается, если вероятность ниже порога alliteration_threshold. На каждой позиции проверяется около двадцати согласных, поэтому порог строгий: на прозе при 0.001 подсвечено около 5% слов, при 0.01 - около 20%, в основном случайные совпадения частых букв. Повтор редкой согласной (слышно, бесшумно шуршат камыши) заметен в двух-трех словах, повтор частой в длинных словах ожидаем и не подсвечивается. Слова короче трех букв и слова без гласных цепочку не прерывают и не продолжают, буква й не учитывается, так как в именительном падеже входит в лемму прилагательного. Индекс аллитерации PhonStats измеряет сгруппированность повторов во всем тексте, подсветка показывает их места.
Параметры¶
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
source |
str/Doc | - |
Источник данных (строка или объект Doc) |
layers |
list[str] | None |
Слои подсветки; если не заданы, включаются все доступные источнику |
long_sent_word_factor |
int | 20 |
Минимальное количество слов в длинном предложении |
complex_syl_factor |
int | 4 |
Минимальное количество слогов в сложном слове |
stopwords |
list[str] | None |
Список стоп-слов; если не задан, стоп-слова определяются по части речи с помощью pymorphy3 |
alliteration_threshold |
float | 0.001 |
Порог вероятности повтора согласной, ниже которого повтор считается аллитерацией |
Атрибуты¶
| Атрибут | Тип | Описание |
|---|---|---|
text |
str | Текст источника данных |
layers |
tuple[str] | Включенные слои подсветки в порядке отрисовки |
highlights |
tuple[Highlight] | Подсвеченные фрагменты в порядке появления в тексте |
counts |
dict[str, int] | Количество фрагментов каждого слоя |
Фрагмент Highlight - неизменяемый объект с полями start и end (позиции в тексте), layer (слой) и note (пояснение для всплывающей подсказки: число слов в предложении, слогов в слове, длина цепочки, согласная аллитерации).
Методы¶
to_html¶
Возвращает HTML-разметку подсвеченного текста: блок div с классом ruts-highlight, внутри легенда со счетчиками и текст, в котором подсвеченные отрезки обернуты в span с классами ruts-hl и ruts-hl-<слой>, пояснения выводятся в атрибут title. Пересекающиеся фрагменты разных слоев дают отрезки с несколькими классами. Переносы строк сохраняются как символьные ссылки, поэтому разметку можно вставлять в Markdown.
Параметры:
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
legend |
bool | True |
Добавлять легенду со счетчиками фрагментов |
css |
bool | True |
Добавлять стили слоев |
Пример использования¶
Пример
Код:
# Загрузка библиотек
import spacy
from ruts.visualizers import highlight
# Подготовка данных
nlp = spacy.load("ru_core_news_sm")
text = (
"Проект, подготовленный за неделю, был одобрен советом без обсуждения. "
"Повышение эффективности использования бюджетных средств обсуждалось, не выходя за рамки регламента. "
"Участники, представлявшие региональные министерства, не смогли согласовать позиции по вопросам "
"финансирования и распределения ответственности между ведомствами, поскольку каждое из них "
"настаивало на собственной трактовке положений соглашения. "
"Споры стихли, в кулуарах шумно шептались и шушукались, а решение было отложено "
"до следующего заседания."
)
# Подсветка текста
ht = highlight(nlp(text))
ht.counts
# {'long_sents': 1, 'complex_words': 26, 'stopwords': 17, 'passive': 4, 'participle_clauses': 2,
# 'converb_clauses': 1, 'genitive_chains': 2, 'alliteration': 1}
ht.highlights[:2]
# (Highlight(start=8, end=32, layer='participle_clauses', note='причастный оборот, 3 слова'),
# Highlight(start=8, end=22, layer='complex_words', note='сложное слово, 5 слогов'))
# Отображение в Jupyter или сохранение разметки
ht
html = ht.to_html()
Результат (наведите курсор на фрагмент, чтобы увидеть пояснение):
Подсветка по строке без модели spaCy включает четыре слоя: длинные предложения, сложные слова, стоп-слова и аллитерации.
Пример
from ruts.visualizers import highlight
text = "Чуть слышно, бесшумно шуршат камыши. Повышение эффективности использования ресурсов обсуждалось."
ht = highlight(text, layers=["complex_words", "alliteration"])
ht.highlights
# (Highlight(start=5, end=35, layer='alliteration', note='аллитерация на «ш»'),
# Highlight(start=37, end=46, layer='complex_words', note='сложное слово, 5 слогов'),
# Highlight(start=47, end=60, layer='complex_words', note='сложное слово, 5 слогов'),
# Highlight(start=61, end=74, layer='complex_words', note='сложное слово, 6 слогов'),
# Highlight(start=84, end=95, layer='complex_words', note='сложное слово, 4 слога'))