Перейти к содержанию

SEO-метрики стиля

StyleStats(source, words_extractor=None, stopwords=None, top_n=10, cliches=None, nausea_stopwords=None)

Метрики стиля текста: SEO-метрики Advego и Text.ru и маркеры канцелярита. Формулы сервисов не опубликованы, поэтому взяты общепринятые определения. Источник данных - текст или объект Doc библиотеки spaCy.

SEO-метрики считаются по словам экстрактора слов, по умолчанию в нижнем регистре, или по токенам Doc; явно переданный экстрактор применяется к тексту Doc. Маркеры считаются по словоформам в нижнем регистре (forms) независимо от экстрактора.

Исключения:

  • SourceTypeError - источник, который не строка и не Doc, экстрактор другого типа, список, который не список строк;
  • SourceError - источник без слов;
  • ParameterError - top_n, который не целое число не меньше единицы.

Класс расширяет StyleStats ядра anyTS крючками русского языка, о которых говорят карточки метрик. Слова строки извлекает русский WordsExtractor и не лемматизирует, поэтому формы одного слова считаются разными словами, как в Advego; для расчета по леммам передайте WordsExtractor с параметрами use_lexemes=True и lowercase=True. Переданные списки слов и словосочетания сравниваются без буквы ё (normalize_yo). Слова Doc берутся без знаков ударения, а части дефисного слова, разрезанного spaCy, склеиваются (во-первых - одно слово). Таблица print_stats и сообщения об ошибках - по-русски (STYLE_STATS_DESC и CORE_MESSAGES из ruts.constants).

from ruts import StyleStats

text = "Ног нет, а хожу, рта нет, а скажу: когда спать, когда вставать, когда работу начинать"
StyleStats(text).print_stats()
                     Метрика                     | Значение
------------------------------------------------------------
Классическая тошнота                             |   1.73
Академическая тошнота (%)                        |  53.33
Водность (%)                                     |  33.33
Заспамленность (%)                               |  26.67
Естественность по Ципфу (%)                      |  33.33
Отглагольные существительные (% существительных) |   0.00
Производные предлоги (на 100 слов)               |   0.00
Вводные слова (на 100 слов)                      |   0.00
Штампы (на 100 слов)                             |   0.00

Параметры

Параметр Тип По умолчанию Описание
source str / Doc - Источник данных
words_extractor WordsExtractor None Инструмент для извлечения слов; применяется и к Doc, к его тексту
stopwords list[str] None Слова «воды»; без них решает is_water_word
top_n int 10 Количество самых частых слов академической тошноты и естественности по закону Ципфа (NAUSEA_TOP_N)
cliches list[str] None Штампы; по умолчанию cliches_list класса
nausea_stopwords list[str] None Стоп-слова академической тошноты; без них решает is_stopword

Множество слов берется в отсортированном порядке.

NAUSEA_TOP_N - константа anyts.constants.

Атрибуты

Атрибут Тип Описание
words tuple[str] Слова SEO-метрик
forms tuple[str] Словоформы маркеров в нижнем регистре

Метрики - свойства, которые вычисляются при каждом обращении.

Метрики

get_stats дает все метрики. Метрику считает функция из ее карточки по words или forms с крючками класса.

Метрика Что измеряет Диапазон Чем больше, тем
classic_nausea Повторы самого частого слова от 0, растет с текстом навязчивее одно слово
academic_nausea Доля самых частых значимых слов 0-100 % беднее словарь
water Доля слов без содержания 0-100 % меньше смысла на слово
spam Доля повторов слов 0-100 % больше повторов
zipf_naturalness Согласие частот с законом Ципфа 0-100 %, nan без рангов для сравнения ближе к естественному тексту
verbal_nouns Доля отглагольных среди существительных 0-100 %, nan без существительных номинативнее стиль
compound_prepositions Производные предлоги на 100 слов 0-100 больше канцелярита
parentheticals Вводные слова на 100 слов 0-100 больше вставок
cliches Штампы на 100 слов 0-100 больше штампов

Карточки дают полосы, по которым читает метод describe, - нормы Advego, Text.ru, pr-cy и megaindex (STYLE_NORMS). Нормы - ориентиры сервисов для текстов сайтов в несколько сотен слов: на коротких текстах значения тошноты и заспамленности неинформативны, к художественной прозе нормы неприменимы. У маркеров канцелярита норм нет.

Классическая тошнота

classic_nausea · Advego

calc_classic_nausea(text)

Насколько навязчиво повторяется одно слово: квадратный корень из числа вхождений \(f_1\) самого частого слова. Значение не поправлено на длину текста, поэтому растет вместе с текстом; без слов - 0.

\[ \sqrt{f_1} \]
Параметр Тип По умолчанию Описание
text list[str] - Список слов
Значение Прочтение
[0; 5] норма Advego
(5; 7] у верхней границы нормы Advego
(7; ∞) выше нормы Advego

Академическая тошнота

academic_nausea · nausea_words() · Advego

calc_academic_nausea(text, top_n=10, stopwords=None)

Доля вхождений top_n самых частых значимых слов среди всех слов в процентах.

\[ 100 \cdot \frac{\sum_{w \in \textrm{top}_n} f_w}{\textrm{Количество слов}} \]
Параметр Тип По умолчанию Описание
text list[str] - Список слов
top_n int 10 Количество самых частых слов
stopwords list[str] None Стоп-слова; без них решает is_stopword

top_n, который не целое число не меньше единицы, дает ParameterError.

Значение Прочтение
[0; 5) ниже нормы Advego
[5; 15] норма Advego
(15; 100] выше нормы Advego
find_nausea_words(text, top_n=10, stopwords=None)

top_n самых частых слов без стоп-слов, которые считает академическая тошнота, с числом вхождений: сначала самые частые, слова равной частоты - в порядке текста. Стоп-слово - слово из stopwords без учета регистра и буквы ё или, без списка, слово is_stopword.

Параметр Тип По умолчанию Описание
text list[str] - Список слов
top_n int 10 Количество самых частых слов
stopwords list[str] None Стоп-слова; без них решает is_stopword

top_n, который не целое число не меньше единицы, дает ParameterError.

is_stopword(word)

Незначимо ли слово для академической тошноты по разбору ruMorph: союзы, частицы, предлоги, местоимения, определительные местоимения и междометия (CCONJ, SCONJ, PART, ADP, PRON, DET, INTJ; набор ruts.constants.STOPWORD_POS), предикативы (надо, можно, нет) и «бы», указательные, вопросительные и относительные наречия (PronType Dem, Int, Rel: там, тогда, где, почему; ruts.utils.is_pronominal) и вводные слова (помета Prnt).

from ruts.style_stats import find_nausea_words

find_nausea_words(["кот", "и", "кот", "и", "пес"], top_n=1)
{'кот': 2}

Водность

water · Text.ru

calc_water(text, stopwords=None)

Доля слов без содержания в процентах: слов из stopwords без учета регистра и буквы ё или, без списка, слов is_water_word. «Вода» Advego - другой показатель, здесь он не реализован.

Параметр Тип По умолчанию Описание
text list[str] - Список слов
stopwords list[str] None Слова «воды»
Значение Прочтение
[0; 15) естественная водность по Text.ru
[15; 30] избыточная водность по Text.ru
(30; 100] высокая водность по Text.ru
is_water_word(word)

Является ли слово «водой» по разбору ruMorph - для водности и слоя stopwords подсветки: союзы, частицы (и «бы»), местоимения-существительные и междометия (CCONJ, SCONJ, PART, PRON, INTJ; набор ruts.constants.WATER_POS), «его», «её», «их» и вводные слова (конечно, например). Предлоги, определительные местоимения и предикативы, в отличие от is_stopword, водой не считаются.

Заспамленность

spam · Text.ru

calc_spam(text)

Доля повторов слов в процентах: каждого вхождения слова после первого.

\[ 100 \cdot \left(1 - \frac{\textrm{Количество лексем}}{\textrm{Количество слов}}\right) \]
Параметр Тип По умолчанию Описание
text list[str] - Список слов
Значение Прочтение
[0; 30) естественный текст по Text.ru
[30; 60] SEO-оптимизированный текст по Text.ru
(60; 100] заспамленный текст по Text.ru

Естественность по Ципфу

zipf_naturalness · pr-cy, megaindex

calc_zipf_naturalness(text, top_n=10)

Согласие частот самых частых слов с идеальным распределением закона Ципфа \(f_r = f_1 / r\), где \(f_1\) - частота самого частого слова, \(r\) - ранг. Ранги берутся от 2 до \(R = \min(\textrm{top}_n, V, f_1)\), где \(V\) - количество лексем. Отрицательные значения обрезаются до 0. Без рангов для сравнения - все слова гапаксы, одна лексема или top_n меньше 2 - значение равно nan.

\[ 100 \cdot \left(1 - \frac{1}{R - 1} \sum_{r=2}^{R} \frac{|r \cdot f_r - f_1|}{f_1}\right) \]
Параметр Тип По умолчанию Описание
text list[str] - Список слов
top_n int 10 Количество самых частых слов

top_n, который не целое число не меньше единицы, дает ParameterError.

Значение Прочтение
[0; 50) ниже нормы pr-cy и megaindex
[50; 100] норма pr-cy и megaindex

Отглагольные существительные

verbal_nouns

calc_verbal_nouns(text)

Доля отглагольных существительных среди существительных (по первому разбору ruMorph) в процентах; nan для текста без существительных. Существительное отглагольное, если его лемма оканчивается на суффикс из VERBAL_NOUN_SUFFIXES (-ние, -нье, -тие, -тье, -ствие, -ция) или входит в VERBAL_NOUN_LEMMAS (производство, руководство, строительство) - функция ruts.utils.is_verbal_noun. Эвристика захватывает и неотглагольные слова с теми же суффиксами (здание). find_verbal_nouns(text) возвращает границы найденных слов как срезы списка.

Параметр Тип По умолчанию Описание
text list[str] - Список слов

Производные предлоги и штампы

compound_prepositions · cliches

calc_phrase_density(text, phrases)

Число вхождений словосочетаний из списка на 100 слов. Словосочетания сравниваются без учета регистра и буквы ё, а словосочетание, начинающееся с инфинитива, в том числе после «не», находится в любой форме своего глагола, включая причастия и деепричастия («имело место», «доведено до сведения»). Эти варианты из текста, каждый со своим словосочетанием, дает expand_phrases(text, phrases). Так StyleStats считает по словоформам (forms) производные предлоги из COMPOUND_PREPOSITIONS (в целях, в связи с, в рамках, за счет) и штампы из OFFICIALESE_CLICHES (на сегодняшний день, в настоящее время, иметь место) или из параметра cliches.

Параметр Тип По умолчанию Описание
text list[str] - Список слов
phrases list[str] - Словосочетания через пробел

Вводные слова

parentheticals

calc_parentheticals(text)

Число вводных слов на 100 слов: словосочетания из PARENTHETICALS (таким образом, как правило, в частности, кроме того) и вне их одиночные слова с пометой Prnt ruMorph (конечно, например, впрочем; функция is_parenthetical(word)). find_parentheticals(text) возвращает границы найденных слов и словосочетаний как срезы списка.

Параметр Тип По умолчанию Описание
text list[str] - Список слов

Плотность ключевых слов

keyword_density(*keywords) · Text.ru

calc_keyword_density(text, keywords)

Число вхождений каждого ключевого слова на 100 слов. Ключевое слово из нескольких слов через пробел - последовательность слов, вхождения которой могут пересекаться. Слова и ключевые слова сравниваются в нижнем регистре без буквы ё, как стоп-слова и словосочетания, а ключевые слова из множества идут в отсортированном порядке.

Параметр Тип По умолчанию Описание
text list[str] - Список слов
keywords list[str] - Ключевые слова или фразы

Функции проверяют свои слова: слова, стоп-слова, ключевые слова и словосочетания, которые не список строк, дают SourceTypeError.

Методы

keyword_density(*keywords) дает плотность ключевых слов и фраз в процентах (calc_keyword_density с normalize класса), nausea_words() - самые частые значимые слова академической тошноты с числом вхождений (find_nausea_words).

markers() возвращает найденные маркеры канцелярита по метрикам - verbal_nouns, compound_prepositions, parentheticals, cliches - так, как они записаны в словоформах, в порядке текста.

from ruts import StyleStats

text = "В целях повышения качества в кратчайшие сроки, как правило, проводится проверка"
StyleStats(text).markers()
StyleStats(text, top_n=2).nausea_words()
{'verbal_nouns': ('повышения',),
 'compound_prepositions': ('в целях',),
 'parentheticals': ('как правило',),
 'cliches': ('в кратчайшие сроки',)}
{'целях': 1, 'повышения': 1}

Остальные методы - get_stats, to_dataframe, print_stats и describe - из интерфейса статистик ядра anyTS; describe читает SEO-метрики по полосам норм из их карточек, а для маркеров канцелярита возвращает None.

from ruts import StyleStats

text = "Ног нет, а хожу, рта нет, а скажу: когда спать, когда вставать, когда работу начинать"
ss = StyleStats(text)
ss.keyword_density("когда", "нет а")
ss.describe("water"), ss.describe("cliches")
ss.get_stats()
{'когда': 20.0, 'нет а': 13.333333333333334}
('высокая водность по Text.ru', None)
{'classic_nausea': 1.7320508075688772,
 'academic_nausea': 53.333333333333336,
 'water': 33.333333333333336,
 'spam': 26.666666666666668,
 'zipf_naturalness': 33.333333333333336,
 'verbal_nouns': 0.0,
 'compound_prepositions': 0.0,
 'parentheticals': 0.0,
 'cliches': 0.0}