Базовые статистики¶
BasicStats(source, sents_extractor=None, words_extractor=None, normalize=False, complex_syl_factor=4, long_word_letter_factor=6)
Базовые статистики текста: количество его предложений, слов, символов, слогов и знаков препинания и распределения его слов. Источник данных - текст или объект Doc библиотеки spaCy. Буквы считаются по str.isalpha, поэтому цифры, дефисы и знаки внутри слова буквами не являются.
Слова и предложения строки дают экстракторы. Doc дает словами свои токены без знаков препинания и символов вроде € или %, предложениями - свои границы или, если их нет или они частичные (has_sents), границы экстрактора предложений; переданный экстрактор вместо этого применяется к его тексту. Пустая строка завершает предложение строки и Doc без границ; Doc с границами - если в его пайплайне до парсера, senter или sentencizer стоит start_sents_after_blank_lines (библиотека регистрирует компонент под своим именем). Предложение без слов, например из одних знаков препинания, не считается.
Исключения:
SourceTypeError- источник, который не строка и неDoc, экстрактор другого типа;SourceError- источник без слов;ParameterError- порог, который не целое число не меньше единицы,normalize, который неbool.
Класс расширяет BasicStats ядра anyTS крючками русского языка: слоги слова считает count_syllables, экстракторы по умолчанию - русские SentsExtractor и WordsExtractor, знаки препинания - count_punctuations ruTS, а части дефисного слова, разрезанного spaCy, склеиваются (во-первых - одно слово). Компонент пустых строк в ruTS называется ruts_blank_lines: nlp.add_pipe("ruts_blank_lines", before="parser"). Знаки ударения и мягкие переносы не считаются ни символами, ни частями слов, а й и ё из двух символов - одна буква (ruts.utils.strip_marks): текст с ударениями дает те же статистики, что без них. Статистики вычисляются при создании объекта, таблица print_stats - по-русски.
from ruts import BasicStats
text = "Существуют три вида лжи: ложь, наглая ложь и статистика"
bs = BasicStats(text, normalize=True)
bs.print_stats()
Статистика | Значение
---------------------------------------------
Предложения | 1
Слова | 9
Уникальные слова | 8
Длинные слова | 3
Сложные слова | 2
Простые слова | 7
Односложные слова | 5
Многосложные слова | 4
Символы | 55
Буквы | 45
Пробелы | 8
Слоги | 18
Знаки препинания | 2
Энтропия длин слов в буквах (бит) | 2.20
Энтропия длин слов в слогах (бит) | 1.66
Параметры¶
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
source |
str / Doc |
- | Источник данных (строка или объект Doc) |
sents_extractor |
SentsExtractor |
None |
Инструмент для извлечения предложений; для Doc применяется к его тексту |
words_extractor |
WordsExtractor |
None |
Инструмент для извлечения слов; для Doc применяется к его тексту |
normalize |
bool |
False |
Вычислять нормализованные статистики |
complex_syl_factor |
int |
COMPLEX_SYL_FACTOR |
Минимальное количество слогов в сложном слове |
long_word_letter_factor |
int |
LONG_WORD_LETTER_FACTOR |
Минимальное количество букв в длинном слове |
Объект хранит normalize, complex_syl_factor и long_word_letter_factor под их именами.
В ruTS сложное слово - от четырех слогов, длинное - от шести букв: COMPLEX_SYL_FACTOR = 4 и LONG_WORD_LETTER_FACTOR = 6 из ruts.constants.
Статистики¶
| Статистика | Тип | Описание | Нормализованная |
|---|---|---|---|
c_letters |
dict[int, int] |
Распределение слов по количеству букв | - |
c_syllables |
dict[int, int] |
Распределение слов по количеству слогов | - |
n_sents |
int |
Количество предложений со словами | - |
n_words |
int |
Количество слов | - |
n_unique_words |
int |
Количество уникальных слов без учета регистра | p_unique_words |
n_long_words |
int |
Количество длинных слов, не меньше чем из long_word_letter_factor букв |
p_long_words |
n_complex_words |
int |
Количество сложных слов, не меньше чем из complex_syl_factor слогов |
p_complex_words |
n_simple_words |
int |
Количество простых слов: со слогом, но не сложных | p_simple_words |
n_monosyllable_words |
int |
Количество односложных слов | p_monosyllable_words |
n_polysyllable_words |
int |
Количество многосложных слов, от двух слогов | p_polysyllable_words |
n_chars |
int |
Количество символов без переносов строк | - |
n_letters |
int |
Количество букв | p_letters |
n_spaces |
int |
Количество пробелов Unicode (категория Zs), например неразрывных, и табуляций | p_spaces |
n_syllables |
int |
Количество слогов | - |
n_punctuations |
int |
Количество знаков препинания | p_punctuations |
letters_entropy |
float |
Энтропия Шеннона длин слов в буквах (c_letters) в битах; 0, когда все слова одной длины; оценка по долям на коротком тексте занижена, на десятках слов - на десятые доли бита |
- |
syllables_entropy |
float |
Энтропия Шеннона длин слов в слогах (c_syllables) в битах, с тем же смещением |
- |
c_punctuations |
dict[str, int] |
Распределение знаков препинания по типам (count_punctuations) |
- |
С normalize=True у объекта есть и нормализованные статистики типа float: количества слов, деленные на число слов, количества символов - на число символов.
Методы¶
count_words_by_syllables(min_syllables) и count_words_by_letters(min_letters) возвращают количество слов не меньше чем с заданным числом слогов или букв; минимум, который не целое число, дает ParameterError.
Методы пересчитывают сложные и длинные слова с порогом, отличным от заданного при создании объекта: так класс ReadabilityStats считает индекс SMOG (сложное слово - от 5 слогов) и LIX (длинное слово - от 7 букв).
get_stats(flat) возвращает справочник с распределениями c_letters и c_syllables, статистиками из stats_desc, распределением c_punctuations и, с normalize=True, нормализованными количествами - копию: ее правка не меняет объект. С flat=True распределения дают по ключу на каждое значение, которое есть в тексте, например c_letters_3 и c_punctuations_comma.
print_stats() выводит таблицу со статистиками из stats_desc, их описаниями и заголовками из stats_headers.
Нормализованных статистик p_* в таблице нет.
to_dataframe() возвращает плоские статистики, get_stats(flat=True), таблицей DataFrame библиотеки pandas из одной строки со столбцом на каждый ключ. Статистика-справочник дает столбцы только для ключей, которые есть у текста, поэтому в таблицах нескольких текстов, объединенных pandas.concat, количество, которого у текста нет, - NaN. Нулями можно заполнять только такие столбцы: в остальных NaN - неопределенное значение.
bs.count_words_by_syllables(5), bs.count_words_by_letters(7)
bs.get_stats()
(0, 2)
{'c_letters': {1: 1, 3: 2, 4: 3, 6: 1, 10: 2},
'c_syllables': {1: 5, 2: 1, 3: 1, 4: 2},
'n_sents': 1,
'n_words': 9,
'n_unique_words': 8,
'n_long_words': 3,
'n_complex_words': 2,
'n_simple_words': 7,
'n_monosyllable_words': 5,
'n_polysyllable_words': 4,
'n_chars': 55,
'n_letters': 45,
'n_spaces': 8,
'n_syllables': 18,
'n_punctuations': 2,
'letters_entropy': 2.197159723424149,
'syllables_entropy': 1.6577427265048887,
'c_punctuations': {'comma': 1,
'period': 0,
'question': 0,
'exclamation': 0,
'ellipsis': 0,
'colon': 1,
'semicolon': 0,
'dash': 0,
'hyphen': 0,
'angle_quotes': 0,
'straight_quotes': 0,
'parentheses': 0,
'other': 0},
'p_unique_words': 0.8888888888888888,
'p_long_words': 0.3333333333333333,
'p_complex_words': 0.2222222222222222,
'p_simple_words': 0.7777777777777778,
'p_monosyllable_words': 0.5555555555555556,
'p_polysyllable_words': 0.4444444444444444,
'p_letters': 0.8181818181818182,
'p_spaces': 0.14545454545454545,
'p_punctuations': 0.03636363636363636}
Метод describe - из интерфейса статистик ядра anyTS; шкал у базовых статистик нет, поэтому он для статистик get_stats возвращает None.
Знаки препинания¶
count_punctuations(text, marks=PUNCTUATION_MARKS, dash_pattern=DASH_PATTERN)
Считает знаки препинания по типам - распределение c_punctuations: запятые, точки, вопросительные и восклицательные знаки, многоточия, двоеточия, точки с запятой, тире, дефисы, кавычки-елочки, кавычки, скобки и прочие знаки. Сначала считаются тире, набранные дефисами (dash_pattern), затем многоточия - …, три и более точек или две после ? и !, один знак, точки которого в точки не входят (Кто там?.. - вопрос и многоточие), - затем каждый знак по его типу в marks; любой другой символ категорий Unicode P и S - прочий знак (§, €, °).
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
text |
str |
- | Строка текста |
marks |
dict[str, str] |
PUNCTUATION_MARKS |
Тип каждого знака из PUNCTUATION_TYPES |
dash_pattern |
Pattern |
DASH_PATTERN |
Тире, набранные дефисами |
Знак marks, который не один символ или имеет неизвестный тип, дает ParameterError; текст, который не строка, marks, которые не словарь, и dash_pattern, который не скомпилированное регулярное выражение, дают SourceTypeError.
В ruTS PUNCTUATION_MARKS и DASH_PATTERN модуля ruts.basic_stats - знаки ядра с нижней кавычкой „ в роли кавычки и шаблон тире, при котором висячий дефис перед и, или, либо или запятой остается дефисом (двух- и трёхкомнатные, сорока-, пятидесятилетние), а тире реплики, набранное дефисом, - тире (- Ушли, - сказал он).
from ruts.basic_stats import count_punctuations
text = "Кот — «зверь»... Пёс, конечно, - друг; а кто-то (тот, что ещё жив) — нет!"
{kind: count for kind, count in count_punctuations(text).items() if count}
{'comma': 3,
'exclamation': 1,
'ellipsis': 1,
'semicolon': 1,
'dash': 3,
'hyphen': 1,
'angle_quotes': 2,
'parentheses': 2}
Тире, набранные дефисами¶
dash_pattern(conjunctions=(), hanging_before_comma=False)
Строит dash_pattern для count_punctuations. Висячий дефис, приклеенный к букве или цифре и отнесенный к следующему слову (до- и послевоенный, 5- и 10-летний), остается дефисом перед пробелами строки и одним из союзов conjunctions без учета регистра, а с hanging_before_comma - и перед запятой (двух-, трех- и четырехлетний). Язык, в диалоге которого строку закрывает дефис перед запятой (-Come -he said-, and left), оставляет hanging_before_comma выключенным. Без параметров шаблон - DASH_PATTERN.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
conjunctions |
Collection[str] |
() |
Союзы после висячего дефиса |
hanging_before_comma |
bool |
False |
Считать дефис между буквой и запятой висячим |
Союзы, которые не набор строк, дают SourceTypeError, а пустой союз - ParameterError.
Без параметров получается DASH_PATTERN ядра (anyts.basic_stats), а DASH_PATTERN модуля ruts.basic_stats - dash_pattern(("и", "или", "либо"), hanging_before_comma=True).
from ruts.basic_stats import count_punctuations, dash_pattern
text = "Двух- и трёхкомнатные, сорока-, пятидесятилетние - сказал он"
counts = count_punctuations(text)
counts["dash"], counts["hyphen"]
counts = count_punctuations(text, dash_pattern=dash_pattern())
counts["dash"], counts["hyphen"]
(1, 2)
(3, 0)
Профиль пунктуации¶
punctuation_profile(text, n_words=None)
Частоты знаков препинания по типам (count_punctuations) на 1000 слов и yo_share - доля буквы ё среди букв е и ё, то есть пишет ли автор ё. Без слов или без букв е и ё значения - nan. Текст, который не строка, дает SourceTypeError, количество слов, которое не целое неотрицательное число, - ParameterError.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
text |
str |
- | Строка текста |
n_words |
int |
None |
Количество слов; без него слова извлекает WordsExtractor |
Профиль - редакторский и стилометрический признак: у Чехова многоточий и восклицаний в разы больше, чем у Толстого (см. сравнение корпусов). Он зависит от оформления текста - типографских кавычек и тире, буквы ё - и легко подделывается, поэтому его стоит смотреть отдельно от лингвистических признаков.
from ruts.basic_stats import punctuation_profile
text = "Кот — «зверь»... Пёс, конечно, - друг; а кто-то (тот, что ещё жив) — нет!"
profile = punctuation_profile(text)
round(profile["dash"], 1), round(profile["yo_share"], 2)
(250.0, 0.33)