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

Функции вычисления статистик

Алгоритм

Ударения и метр определяются по алгоритму Барахнина, Кожемякиной и Кузнецовой (CEUR 2019):

  1. Ударения по словарю. В каждом слове ищется ударный слог: по букве ё, у односложных слов - единственный, иначе по словарю StressDict с поправками STRESS_CORRECTIONS (ошибочные и подвижные ударения словаря, собранные по частым формам PoetryCorpus и разметке RIFMA: ещё, себе́, пе́ред, зо́лото, леса́х, спеши́т, земли́). Составные слова через дефис ищутся целиком, затем по частям, поэтические стяжения (желанье - желание) и деепричастия (забыв - забывший) - по полной форме.
  2. Подбор метра. У каждого из пяти метров свои позиции сильных слогов - иктов: ямб cC, хорей Cc, дактиль Ccc, амфибрахий cCc, анапест ccC (VERSE_METERS). Выбирается метр, при котором меньше всего словарных ударений многосложных слов попадает на слабые позиции, при равенстве - с наибольшим числом ударных иктов. Ударение в анакрузе - на слогах до первого икта строки - нарушением не считается: в трехсложных метрах оно обычно (Ста́ли дни холоднее).
  3. Снятие неоднозначности. Односложные предлоги, союзы и частицы (VERSE_PROCLITICS) безударны, остальные односложные слова ударны только на икте; многосложные служебные слова (VERSE_WEAK_WORDS: или, чтобы, перед, через, после) ударны, если словарное ударение попадает на икт. Словарное ударение многосложного слова на слабой позиции переносится на икт, если в слове ровно один икт, такое слово в строке одно или все они двусложные (формы с подвижным ударением: воды́ - во́ды, реки́ - ре́ки), и после переноса в строке не остается нарушений - иначе строка считается неметрической; ударение по букве ё и ударение в анакрузе не переносятся. Слово без словарного ударения получает единственный икт, при нескольких иктах ударение последнего слова строки выбирается по рифме с соседними, иначе - последний икт.
  4. Проверка. Метр не определен, если после подгонки больше десятой части ударений многосложных слов (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То, как зверь, она завоет,"
)
# [['Буря мглою небо кроет,', 'Вихри снежные крутя;'], ['То, как зверь, она завоет,']]