Функции вычисления статистик¶
Алгоритм¶
Ударения и метр определяются по алгоритму Барахнина, Кожемякиной и Кузнецовой (CEUR 2019):
- Ударения по словарю. В каждом слове ищется ударный слог: по букве ё, у односложных слов - единственный, иначе по словарю
StressDictс поправкамиSTRESS_CORRECTIONS(ошибочные и подвижные ударения словаря, собранные по частым формам PoetryCorpus и разметке RIFMA: ещё, себе́, пе́ред, зо́лото, леса́х, спеши́т, земли́). Составные слова через дефис ищутся целиком, затем по частям, поэтические стяжения (желанье - желание) и деепричастия (забыв - забывший) - по полной форме. - Подбор метра. У каждого из пяти метров свои позиции сильных слогов - иктов: ямб
cC, хорейCc, дактильCcc, амфибрахийcCc, анапестccC(VERSE_METERS). Выбирается метр, при котором меньше всего словарных ударений многосложных слов попадает на слабые позиции, при равенстве - с наибольшим числом ударных иктов. Ударение в анакрузе - на слогах до первого икта строки - нарушением не считается: в трехсложных метрах оно обычно (Ста́ли дни холоднее). - Снятие неоднозначности. Односложные предлоги, союзы и частицы (
VERSE_PROCLITICS) безударны, остальные односложные слова ударны только на икте; многосложные служебные слова (VERSE_WEAK_WORDS: или, чтобы, перед, через, после) ударны, если словарное ударение попадает на икт. Словарное ударение многосложного слова на слабой позиции переносится на икт, если в слове ровно один икт, такое слово в строке одно или все они двусложные (формы с подвижным ударением: воды́ - во́ды, реки́ - ре́ки), и после переноса в строке не остается нарушений - иначе строка считается неметрической; ударение по букве ё и ударение в анакрузе не переносятся. Слово без словарного ударения получает единственный икт, при нескольких иктах ударение последнего слова строки выбирается по рифме с соседними, иначе - последний икт. - Проверка. Метр не определен, если после подгонки больше десятой части ударений многосложных слов (
VERSE_MAX_DEVIATIONS) остается на слабых позициях или если перенести на икт пришлось больше 15% словарных ударений многосложных слов (VERSE_MAX_MOVED) при четырех и более переносах (VERSE_MIN_MOVED) - это дольник, акцентный стих, силлабика, верлибр или проза: подгонка переносит у них ударения не подвижных форм, а любых двусложных слов, и без второго порога дольник или акцентный стих с частыми двусложными словами получал ложный хорей или ямб. На RIFMA переносов больше 15% лишь у 1% строф, у силлабики Тредиаковского, акцентного стиха и песен - у трети текстов и больше; на коротких строфах доля шумит (три подвижные формы в четверостишии - норма), поэтому порог действует от четырех переносов. Ударения тогда ставятся по словарю.
Рифма ищется в окне RHYME_WINDOW (4) строк внутри строфы по фонетическому ключу окончания - хвоста строки от последнего ударного слова: ударная гласная (я/а, ё/о, ю/у, ы/и сведены; е сохраняется и рифмуется с о, чтобы находить ё, записанное как е), группа согласных после нее (без ь и ъ, с оглушением, упрощением непроизносимых сочетаний стн - сн, тс - ц, стяжением двойных и заменой -ого/-его на -ово/-ево, кроме наречий с произносимым [г]: мно́го, стро́го, до́рого) и число заударных слогов. Опорный согласный открытых мужских окончаний и заударные гласные не сравниваются, поэтому находятся и точные, и приблизительные рифмы (пламя - память, лето - одетой); окончания с разной группой согласных (ветер - вечер) не рифмуются. Схема рифмовки записывается буквами по порядку появления (прописные, затем строчные; когда 52 буквы в одной строфе кончаются, повторно используется буква группы, к которой в окне уже не может присоединиться ни одна строка), нерифмованные строки - дефисом.
Точность проверена на наборе RIFMA (5121 строфа с ручной расстановкой ударений и схемами рифмовки, MIT): ударения совпадают с разметкой у 97% слов (у многосложных слов из словаря - 97%, у слов вне словаря - 75%), пары рифмующихся строк находятся с точностью 94% и полнотой 90%, схема строфы целиком совпадает в 78% случаев; метр не определен у 5% строф. Часть поправок STRESS_CORRECTIONS собрана по этой же разметке (63 формы, у которых словарь расходится с ней в 80% и более случаев из пяти и больше вхождений), поэтому оценка ударений отчасти внутривыборочная: на отложенной половине набора поправки, собранные по другой половине, добавляют 0.1-0.2 процентного пункта.
Ударный слог¶
ruts.verse_stats.word_stress()
Определение ударного слога слова по словарю (пункт 1 алгоритма). Слоги считаются по гласным с нуля; ударный слог можно получить, поделив слово функцией syllabify.
Параметры:
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
word |
str | - |
Слово |
stress_dict |
StressDict | None |
Словарь ударений; если не задан, используется StressDict() |
Возвращает None, если слово не найдено или в нем нет гласных.
Пример
from ruts.phon_stats import syllabify
from ruts.verse_stats import word_stress
word_stress("корова"), word_stress("ещё"), word_stress("желанье"), word_stress("кто-нибудь")
# (1, 1, 1, 0)
word_stress("хмурота")
# None
syllabify("корова")[word_stress("корова")]
# 'ро'
Расстановка ударений¶
ruts.verse_stats.accentuate()
Расстановка ударений в тексте по словарю: после ударной гласной каждого слова ставится знак акута (U+0301); односложные предлоги, союзы и частицы и слова без найденного ударения остаются без знака. Метр не учитывается: для стихов с подгонкой ударений под метр служит метод VerseStats.accentuate.
Параметры:
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
text |
str | - |
Текст |
stress_dict |
StressDict | None |
Словарь ударений; если не задан, используется StressDict() |
Пример
from ruts.verse_stats import accentuate
accentuate("Уже поздно, замерли на полночь.")
# 'Уже́ по́здно, за́мерли на по́лночь.'
Метр¶
ruts.verse_stats.detect_meter()
Определение метра стихотворения: ямб, хорей, дактиль, амфибрахий, анапест или None, если силлабо-тонический метр не подобран.
Параметры:
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
text |
str | - |
Текст стихотворения |
stress_dict |
StressDict | None |
Словарь ударений; если не задан, используется StressDict() |
Схема рифмовки¶
ruts.verse_stats.rhyme_scheme()
Определение схемы рифмовки стихотворения: схемы строф через пробел, нерифмованные строки обозначены дефисом.
Параметры:
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
text |
str | - |
Текст стихотворения |
stress_dict |
StressDict | None |
Словарь ударений; если не задан, используется StressDict() |
Пример
from ruts.verse_stats import detect_meter, rhyme_scheme
text = """Тучки небесные, вечные странники!
Степью лазурною, цепью жемчужною
Мчитесь вы, будто как я же, изгнанники,
С милого севера в сторону южную.
Кто же вас гонит: судьбы ли решение?
Зависть ли тайная? злоба ль открытая?
Или на вас тяготит преступление?
Или друзей клевета ядовитая?"""
detect_meter(text), rhyme_scheme(text)
# ('дактиль', 'ABAB ABAB')
blok = """Девушка пела в церковном хоре
О всех усталых в чужом краю,
О всех кораблях, ушедших в море,
О всех, забывших радость свою."""
detect_meter(blok), rhyme_scheme(blok)
# (None, 'ABAB')
Строфы¶
ruts.verse_stats.split_stanzas()
Деление текста на строфы и строки: строфы разделяются пустыми строками, строки без русских слов (номера, звездочки) пропускаются.
Параметры:
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
text |
str | - |
Текст стихотворения |
Пример
from ruts.verse_stats import split_stanzas
split_stanzas(
"Буря мглою небо кроет,\nВихри снежные крутя;\n\n* * *\n\nТо, как зверь, она завоет,"
)
# [['Буря мглою небо кроет,', 'Вихри снежные крутя;'], ['То, как зверь, она завоет,']]