Стиховедческие статистики¶
VerseStats(source, stress_dict=None)
Стиховедческие статистики текста: ударения, метр и стопы, рифмовка, окончания строк и строфы. Источник данных - текст с переносами строк или объект Doc библиотеки spaCy.
Строфы разделяются пустыми строками. Ударения ставятся по словарю StressDict и подгоняются под метр (алгоритм). Знак ударения в тексте важнее словаря и на икт не переносится, поэтому текст после функции accentuate, где ударения расставлены без метра, дает другие значения, чем тот же текст без знаков; ударная по знаку проклитика забирает ударение слова за ней через пробел (на́ сердце). Сами знаки и мягкие переносы в строки не попадают.
Словарь ударений загружается один раз: StressDict().download() (10 МБ). Текст с буквами, но без русских слов (латиница) дает пустые статистики - n_lines 0, метр None, доли nan.
Исключения:
SourceTypeError- источник, который не строка и неDoc, словарь ударений другого типа;SourceError- источник без слов (пустой, из цифр и знаков);DatasetNotFoundError- словарь ударений не загружен.
from ruts import VerseStats
from ruts.datasets import StressDict
StressDict().download()
text = """Мой дядя самых честных правил,
Когда не в шутку занемог,
Он уважать себя заставил
И лучше выдумать не мог."""
vs = VerseStats(text)
vs.print_stats()
Статистика | Значение
----------------------------------------------
Количество строк | 4
Количество строф | 1
Метр | ямб
Число стоп | 4
Доля отклонений от метра | 0.00
Доля пропущенных ударений на иктах | 0.19
Доля рифмованных строк | 1.00
Доля мужских окончаний | 0.50
Доля женских окончаний | 0.50
Доля дактилических окончаний | 0.00
Параметры¶
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
source |
str / Doc |
- | Источник данных |
stress_dict |
StressDict |
None |
Словарь ударений; по умолчанию StressDict() |
Атрибуты¶
| Атрибут | Тип | Описание |
|---|---|---|
stress_dict |
StressDict |
Словарь ударений |
lines |
tuple[str] |
Строки с русскими словами |
stanzas |
tuple[tuple[str, ...], ...] |
Строки по строфам |
mean_line_len |
float |
Средняя длина строки в слогах |
stresses |
tuple[tuple[int, ...], ...] |
Номера ударных слогов каждой строки, считая с нуля |
patterns |
tuple[str, ...] |
Схемы строк из символов c (безударный слог) и C (ударный) |
c_stressed_vowels |
dict[str, int] |
Распределение ударных гласных |
vs.patterns
vs.stresses[1]
vs.c_stressed_vowels
('cCcCcCcCc', 'cCcCcccC', 'cccCcCcCc', 'cCcCcccC')
(1, 3, 7)
{'а': 5, 'я': 2, 'у': 2, 'о': 2, 'е': 1, 'ы': 1}
Метрики¶
Каждая метрика - атрибут объекта, вычисленный при его создании, а get_stats дает их все.
| Метрика | Что измеряет | Диапазон | Чем больше, тем |
|---|---|---|---|
n_lines, n_stanzas |
Количество строк со словами и строф | от 0 | длиннее текст |
meter |
Силлабо-тонический метр | ямб, хорей, дактиль, амфибрахий, анапест, None без метра |
- |
n_feet |
Преобладающее число стоп в строке | от 1, None без метра |
длиннее строки |
p_deviations |
Доля ударений многосложных слов на слабых позициях | 0-0.1, nan без метра |
дальше ударения от метра |
p_pyrrhics |
Доля иктов без ударения | 0-1, nan без метра |
больше пропущенных ударений |
p_rhymed |
Доля рифмованных строк | 0-1, nan без строк |
больше рифм |
p_masculine, p_feminine, p_dactylic |
Доли мужских, женских и дактилических окончаний | 0-1, nan без окончаний |
больше таких окончаний |
Метр и стопы¶
detect_meter(text, stress_dict=None)
Метр стихотворения по алгоритму: ямб, хорей, дактиль, амфибрахий, анапест или None, если силлабо-тонический метр не подобран, - так отсеиваются дольник, акцентный стих, силлабика, верлибр и проза. Число стоп строки - число ее иктов, c_feet - распределение строк по числу стоп, p_deviations считается после подгонки ударений под метр.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
text |
str |
- | Текст стихотворения |
stress_dict |
StressDict |
None |
Словарь ударений; по умолчанию StressDict() |
Исключения - те же, что у VerseStats.
from ruts.verse_stats import detect_meter
lermontov = """Тучки небесные, вечные странники!
Степью лазурною, цепью жемчужною
Мчитесь вы, будто как я же, изгнанники,
С милого севера в сторону южную.
Кто же вас гонит: судьбы ли решение?
Зависть ли тайная? злоба ль открытая?
Или на вас тяготит преступление?
Или друзей клевета ядовитая?"""
blok = """Девушка пела в церковном хоре
О всех усталых в чужом краю,
О всех кораблях, ушедших в море,
О всех, забывших радость свою."""
detect_meter(lermontov), detect_meter(blok)
vs.c_feet
('дактиль', None)
{4: 4}
Пиррихии и профиль ударности¶
Доля иктов без ударения (пиррихиев в двусложных метрах) среди всех иктов строк; stress_profile - доля ударных иктов по позициям в строке, от первого икта к последнему. Без метра p_pyrrhics равна nan, а профиль пуст.
vs.p_pyrrhics, vs.stress_profile
(0.1875, (0.75, 1.0, 0.5, 1.0))
Рифма¶
rhyme_scheme(text, stress_dict=None)
Схема рифмовки стихотворения: схемы строф через пробел, нерифмованные строки обозначены дефисом (ABAB, -A-A, AABB CC). У объекта схемы по строфам - в rhyme_schemes.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
text |
str |
- | Текст стихотворения |
stress_dict |
StressDict |
None |
Словарь ударений; по умолчанию StressDict() |
Исключения - те же, что у VerseStats.
from ruts.verse_stats import rhyme_scheme
rhyme_scheme(lermontov), rhyme_scheme(blok)
vs.rhyme_schemes, vs.p_rhymed
('ABAB ABAB', 'ABAB')
(('ABAB',), 1.0)
Окончания строк¶
Тип окончания (клаузулы) строки - по числу слогов после последнего ударения: мужское - ударение на последнем слоге, женское - один заударный слог, дактилическое - два, гипердактилическое - три и больше (VERSE_CLAUSULAS, как у stress_type слова). c_clausulas - распределение строк по типам; доли считаются от строк с известным ударением последнего слова.
vs.c_clausulas
{'мужская': 2, 'женская': 2}
Методы¶
accentuate() возвращает текст со знаком акута (U+0301) после ударных гласных, с ударениями, подогнанными под метр; безударные слова (клитики, односложные вне икта) и слова без найденного ударения остаются без знака. В текст попадают только строки со словами, строфы разделяются пустой строкой.
print(vs.accentuate())
Мой дя́дя са́мых че́стных пра́вил,
Когда́ не в шу́тку занемо́г,
Он уважа́ть себя́ заста́вил
И лу́чше вы́думать не мо́г.
Остальные методы - get_stats, to_dataframe, print_stats и describe - из интерфейса статистик ядра anyTS; шкал у стиховедческих статистик нет, и describe возвращает для них None.
vs.get_stats()
{'n_lines': 4,
'n_stanzas': 1,
'meter': 'ямб',
'n_feet': 4,
'p_deviations': 0.0,
'p_pyrrhics': 0.1875,
'p_rhymed': 1.0,
'p_masculine': 0.5,
'p_feminine': 0.5,
'p_dactylic': 0.0}
Алгоритм¶
Ударения и метр определяются по алгоритму Барахнина, Кожемякиной и Кузнецовой (CEUR 2019):
- Ударения по словарю. Ударный слог слова - по букве ё, у односложного слова единственный, иначе по словарю
StressDictс поправкамиSTRESS_CORRECTIONS(ошибочные и подвижные ударения словаря: себе́, зо́лото). Составное слово через дефис ищется целиком, затем по частям, поэтические стяжения (желанье - желание) и деепричастия (забыв - забывший) - по полной форме. - Подбор метра. Сильные позиции (икты) пяти метров: ямб
cC, хорейCc, дактильCcc, амфибрахийcCc, анапестccC(VERSE_METERS). Выбирается метр, при котором меньше всего словарных ударений многосложных слов попадает на слабые позиции, при равенстве - с наибольшим числом ударных иктов. Ударение в анакрузе - на слогах до первого икта строки - нарушением не считается (Ста́ли дни холоднее). - Снятие неоднозначности. Односложные предлоги, союзы и частицы (
VERSE_PROCLITICS) безударны, остальные односложные слова ударны только на икте, многосложные служебные слова (VERSE_WEAK_WORDS: или, чтобы) - если словарное ударение попадает на икт. Словарное ударение многосложного слова на слабой позиции переносится на икт, если в слове ровно один икт, такое слово в строке одно или все они двусложные (подвижное ударение: воды́ - во́ды) и после переноса в строке не остается нарушений; ударение по букве ё и в анакрузе не переносится. Слово без словарного ударения получает единственный икт, при нескольких иктах ударение последнего слова строки выбирается по рифме с соседними, иначе - последний икт. - Проверка. Метр не определен, если после подгонки на слабых позициях остается больше десятой части ударений многосложных слов (
VERSE_MAX_DEVIATIONS) или на икт перенесено больше 15% их словарных ударений (VERSE_MAX_MOVED) при четырех и более переносах (VERSE_MIN_MOVED); ударения тогда ставятся по словарю. Метр не подбирается и при словарных ударениях многосложных слов меньше шести (VERSE_MIN_STRESSES).
Рифма ищется в окне RHYME_WINDOW (4) строк внутри строфы по фонетическому ключу окончания - хвоста строки от последнего ударного слова: ударная гласная (я/а, ё/о, ю/у, ы/и сведены, е рифмуется и с о), группа согласных после нее по произношению (с оглушением и упрощением сочетаний: стн - сн) и число заударных слогов. Опорный согласный открытых мужских окончаний и заударные гласные не сравниваются, поэтому находятся и точные, и приблизительные рифмы (пламя - память, лето - одетой); окончания с разной группой согласных (ветер - вечер) не рифмуются. Буквы схемы рифмовки идут по порядку появления: прописные, затем строчные.
Точность проверена на наборе RIFMA (5121 строфа с ручной разметкой ударений и рифм, MIT): ударения совпадают с разметкой у 97% слов (у слов вне словаря - 71%), пары рифмующихся строк находятся с точностью 94% и полнотой 90%, схема строфы целиком совпадает в 78% случаев; метр не определен у 8% строф, в том числе у 3% - из-за порога VERSE_MIN_STRESSES. Часть поправок STRESS_CORRECTIONS собрана по этой же разметке, так что оценка ударений отчасти внутривыборочная: поправки, собранные по одной половине набора, добавляют на другой 0.1-0.2 процентного пункта.
Расстановка ударений¶
accentuate(text, stress_dict=None)
Расстановка знаков акута (U+0301) после ударных гласных текста по словарю, без учета метра (под метр ударения подгоняет метод VerseStats.accentuate); уже стоящий в тексте знак ударения сохраняется, а односложные предлоги, союзы и частицы и слова без найденного ударения остаются без знака.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
text |
str |
- | Текст |
stress_dict |
StressDict |
None |
Словарь ударений; по умолчанию StressDict() |
Исключения:
SourceTypeError- текст, который не строка, словарь ударений другого типа;DatasetNotFoundError- словарь ударений не загружен.
from ruts.verse_stats import accentuate
accentuate("Уже поздно, замерли на полночь.")
'Уже́ по́здно, за́мерли на по́лночь.'
Строфы¶
split_stanzas(text)
Деление текста на строфы и строки: строфы разделяются пустыми строками, строки без русских слов (номера, звездочки) пропускаются.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
text |
str |
- | Текст стихотворения |
Исключения:
SourceTypeError- текст, который не строка.
from ruts.verse_stats import split_stanzas
split_stanzas(
"Буря мглою небо кроет,\nВихри снежные крутя;\n\n* * *\n\nТо, как зверь, она завоет,"
)
[['Буря мглою небо кроет,', 'Вихри снежные крутя;'],
['То, как зверь, она завоет,']]