Подсветка текста¶
HighlightedText(source, layers=None, long_sent_word_factor=20, complex_syl_factor=4, stopwords=None, cliches=None, alliteration_threshold=0.001)
Подсветка текста по слоям в духе сервисов проверки стиля: каждый слой отмечает фрагменты текста, которые считает статистика, - длинные предложения, сложные слова, пассив. Источник данных - текст или объект класса Doc библиотеки spaCy. Результат отображается в Jupyter как HTML со стилями и легендой; to_html возвращает разметку, а highlights хранит фрагменты для собственной отрисовки. Фрагменты разных слоев могут пересекаться.
Исключения:
SourceTypeError- источник, который не строка и неDoc;SourceError- источник без слов;ParameterError- слои, которые не имя и не список имен, неизвестный слой или слой, которому нужна разметка, отсутствующая у источника.
highlight(source, layers=None, long_sent_word_factor=20, complex_syl_factor=4, stopwords=None, cliches=None, alliteration_threshold=0.001)
Функция highlight возвращает объект HighlightedText ruTS со слоями в стиле сервисов Главред и Тургенев: длинные предложения, сложные и редкие слова, пассив, обороты, цепочки родительных падежей, расщепленные сказуемые, отглагольные существительные, производные предлоги, штампы, стоп-слова, вводные слова, коннекторы, аллитерации. Одна картинка объясняет, из чего складываются значения метрик, лучше таблицы чисел.
| Группа | Слой | Что отмечает | Статистика |
|---|---|---|---|
| Читаемость | long_sents |
Предложения с числом слов не меньше long_sent_word_factor |
BasicStats, ReadabilityStats |
complex_words |
Слова с числом слогов не меньше complex_syl_factor |
BasicStats, ReadabilityStats | |
rare_words |
Слова с леммой вне вшитого списка топ-10000; числа, латиница, сокращения и стоп-слова не подсвечиваются | LexicalStats | |
| Синтаксис | passive |
Пассивные глагольные формы вместе со вспомогательным глаголом | SyntaxStats |
participle_clauses |
Причастные обороты | SyntaxStats | |
converb_clauses |
Деепричастные обороты | SyntaxStats | |
genitive_chains |
Цепочки родительных падежей вместе с управляющим словом | SyntaxStats | |
split_predicates |
Расщепленные сказуемые от глагола до именной части | SyntaxStats | |
| Канцелярит | verbal_nouns |
Отглагольные существительные | StyleStats |
compound_prepositions |
Производные предлоги по списку COMPOUND_PREPOSITIONS |
StyleStats | |
cliches |
Штампы по списку OFFICIALESE_CLICHES или параметру cliches |
StyleStats | |
| Стиль | stopwords |
Слова «воды» по части речи (is_water_word) или переданному списку |
StyleStats |
parentheticals |
Вводные слова и обороты | StyleStats | |
connectors |
Коннекторы по части речи из разметки Doc или ruMorph, в подсказке класс и тип |
CohesionStats | |
| Фоника | alliteration |
Повторы согласной в соседних словах, маловероятные при частотах букв русского языка | PhonStats |
Группы заданы в ruts.constants.HIGHLIGHT_LAYER_GROUPS. Слои группы «Синтаксис» считаются по дереву зависимостей и доступны только для объекта Doc с разбором зависимостей (рекомендуемый конвейер или модели ru_core_news_sm, ru_core_news_md, ru_core_news_lg). По умолчанию включаются слои HIGHLIGHT_DEFAULT_LAYERS - длинные предложения, сложные слова, пассив, цепочки родительных, расщепленные сказуемые, штампы - из доступных источнику; layers="all" включает все доступные. Пятнадцать слоев сразу перекрывают друг друга (производный предлог состоит из стоп-слов, коннектор может быть вводным словом), поэтому выбирайте нужные.
Аллитерация
Аллитерация ищется внутри предложения как цепочка из двух и более соседних слов, в основе каждого из которых есть одна и та же согласная буква. Основа - общая начальная часть словоформы и ее леммы по ruMorph (крупных → крупны, руках → рука): окончания согласуются с соседними словами и повторяют согласные по грамматике, а не по звучанию (этих крупных, своим целям и нуждам). Вероятность цепочки при независимом распределении букв - произведение по словам вероятностей встретить согласную среди букв основы, \(1 - (1 - f)^n\), где \(f\) - частота согласной в русских текстах, \(n\) - число букв основы; цепочка подсвечивается, если вероятность ниже порога alliteration_threshold. На каждой позиции проверяется около двадцати согласных, поэтому порог строгий: на прозе при 0.001 подсвечено около 5% слов, при 0.01 - около 20%, в основном случайные совпадения частых букв. Повтор редкой согласной (слышно, бесшумно шуршат камыши) заметен в двух-трех словах, повтор частой в длинных словах ожидаем и не подсвечивается. Слова короче трех букв, стоп-слова и слова без гласных цепочку не прерывают и не продолжают, буква й не учитывается, так как в именительном падеже входит в лемму прилагательного. Индекс аллитерации PhonStats измеряет сгруппированность повторов во всем тексте, подсветка показывает их места.
Класс расширяет HighlightedText ядра anyTS крючками русского языка из ruts.constants: слои с их названиями в легенде - HIGHLIGHT_LAYERS_DESC, слои по умолчанию - HIGHLIGHT_DEFAULT_LAYERS, разметка Doc, которая нужна слою, - HIGHLIGHT_LAYER_ANNOTATIONS (синтаксическим слоям нужен только разбор зависимостей, так как леммы берутся из ruMorph), стили слоев - HIGHLIGHT_LAYER_STYLES; префикс классов CSS - ruts. Слова строки выделяются так же, как в WordsExtractor, предложения - anySeg; Doc без границ предложений (spacy.blank, пайплайн без parser и senter) тоже делится на предложения anySeg, поэтому для него доступен слой long_sents, а части дефисного слова Doc составляют одно слово. Фрагменты слоев, кроме пассива, оборотов и цепочек родительных, находят искатели ядра с русскими крючками: слоги count_syllables, сравнение без буквы ё (normalize_yo), сопоставитель коннекторов RussianConnectorMatcher с частями речи connector_pos, основы get_stem и частоты согласных RU_LETTER_FREQUENCIES без й для аллитерации.
from ruts import load_pipeline
from ruts.visualizers import highlight
nlp = load_pipeline()
text = (
"Проект, подготовленный за неделю, был одобрен советом без обсуждения. "
"Повышение эффективности использования бюджетных средств обсуждалось, не выходя за рамки регламента. "
"Участники, представлявшие региональные министерства, не смогли согласовать позиции по вопросам "
"финансирования и распределения ответственности между ведомствами, поскольку каждое из них "
"настаивало на собственной трактовке положений соглашения. "
"Споры стихли, в кулуарах шумно шептались и шушукались, а решение было отложено "
"до следующего заседания."
)
ht = highlight(nlp(text))
ht.counts
ht.highlights[:2]
highlight(nlp(text), layers="all").counts
{'long_sents': 1,
'complex_words': 26,
'passive': 4,
'genitive_chains': 2,
'split_predicates': 0,
'cliches': 1}
(Highlight(start=8, end=22, layer='complex_words', note='сложное слово, 5 слогов'),
Highlight(start=8, end=22, layer='passive', note='пассив без агенса'))
{'long_sents': 1,
'complex_words': 26,
'rare_words': 3,
'passive': 4,
'participle_clauses': 2,
'converb_clauses': 1,
'genitive_chains': 2,
'split_predicates': 0,
'verbal_nouns': 10,
'compound_prepositions': 0,
'cliches': 1,
'stopwords': 7,
'parentheticals': 0,
'connectors': 4,
'alliteration': 1}
В Jupyter объект ht отображается так (наведите курсор на фрагмент, чтобы увидеть пояснение):
Подсветка по строке без модели spaCy включает все слои, кроме синтаксических: по умолчанию длинные предложения, сложные слова и штампы.
text = "Чуть слышно, бесшумно шуршат камыши. Повышение эффективности использования ресурсов обсуждалось."
highlight(text, layers=["complex_words", "alliteration"]).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 слога'))
Параметры¶
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
source |
str / Doc |
- | Источник данных (строка или объект Doc) |
layers |
list[str] / str |
None |
Слои подсветки; если не заданы, включаются слои по умолчанию, доступные источнику; "all" - все доступные |
Параметры слоев ruTS:
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
long_sent_word_factor |
int |
20 |
Минимальное количество слов в длинном предложении |
complex_syl_factor |
int |
4 |
Минимальное количество слогов в сложном слове |
stopwords |
list[str] / set[str] |
None |
Список или множество слов «воды»; если не задан, они определяются по части речи с помощью ruMorph |
cliches |
list[str] / set[str] |
None |
Список или множество штампов; если не задан, используется OFFICIALESE_CLICHES |
alliteration_threshold |
float |
0.001 |
Порог вероятности повтора согласной при независимом распределении букв, ниже которого повтор считается аллитерацией |
Порог, который не целое число не меньше единицы, или вероятность вне интервала (0, 1] дают ParameterError, стоп-слова или штампы, которые не строки, - SourceTypeError.
Атрибуты¶
| Атрибут | Тип | Описание |
|---|---|---|
text |
str |
Текст источника данных |
layers |
tuple[str] |
Включенные слои в порядке отрисовки |
highlights |
tuple[Highlight] |
Подсвеченные фрагменты, упорядоченные по началу, затем по убыванию конца |
counts |
dict[str, int] |
Количество фрагментов каждого слоя |
Highlight(start, end, layer, note='')
Фрагмент подсветки: неизменяемый объект с параметрами в роли полей.
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
start |
int |
- | Позиция первого символа фрагмента в тексте |
end |
int |
- | Позиция после последнего символа фрагмента |
layer |
str |
- | Слой подсветки |
note |
str |
'' |
Пояснение фрагмента для всплывающей подсказки |
Пояснение фрагмента ruTS - число слов в предложении, слогов в слове, длина цепочки или согласная аллитерации.
Методы¶
to_html(legend=True, css=True) возвращает HTML-разметку подсвеченного текста: блок div с классом <префикс>-highlight, в котором легенда со счетчиками и текст, где подсвеченный отрезок - span с классами <префикс>-hl и <префикс>-hl-<слой> с пояснениями в его title; <префикс> - css_prefix. Пересекающиеся фрагменты разных слоев дают отрезки с несколькими классами в порядке отрисовки. Переносы строк (\n, \r\n, \r) становятся символьными ссылками, по одной на перенос, поэтому разметку можно вставлять в Markdown.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
legend |
bool |
True |
Добавлять легенду со счетчиками фрагментов |
css |
bool |
True |
Добавлять стили слоев |
Метод класса css() возвращает стили, которые добавляет to_html: стили контейнера, легенды и текста под классами css_prefix, объявления layer_styles для каждого слоя и темный цвет текста на слоях с фоном.
alliteration = highlight("Чуть слышно, бесшумно шуршат камыши.", layers="alliteration")
alliteration.to_html(legend=False, css=False)
'<div class="ruts-highlight"><div class="ruts-highlight-text">Чуть <span class="ruts-hl ruts-hl-alliteration" title="аллитерация на «ш»">слышно, бесшумно шуршат камыши</span>.</div></div>'