Автоматизированный анализ структуры тонических стихотворений

Автоматизированный анализ структуры тонических стихотворений

Морозов Алексей Юрьевич,
советник Российской академии естествознания,
e-mail: redactor@vpoezii.online

Аннотация

Статья посвящена разработке автоматизированного метода анализа тонических стихотворений с использованием JavaScript. Предложенный подход включает статистический анализ ударений, построение ритмической матрицы и визуализацию структуры стиха. Алгоритм позволяет точно определять ритмический рисунок, корректировать отклонения и проверять соответствие критериям тонической системы. Реализация метода в системе Fet.Online (свидетельство Роспатента №2021614295) демонстрирует эффективность для образовательных и исследовательских задач.

Ключевые слова: тоническое стихосложение, автоматизированный анализ, ритмическая структура, JavaScript, Fet.Online

Введение

Тоническое стихосложение представляет собой одну из фундаментальных систем организации стиха, основанную на упорядоченном чередовании ударных и безударных слогов. В отличие от силлабо-тонической системы с её строго фиксированными схемами расположения ударений, тоническая система предлагает большую свободу в количестве слогов и интервалах между ударениями. Эта гибкость делает её особенно ценной для передачи естественной ритмики речи и эмоциональной выразительности.

Тоническая система широко применяется как в народной поэзии, так и в современных поэтических произведениях, где важна естественность звучания. Однако ручной анализ таких стихотворений, особенно при работе с большими текстами, требует значительных временных затрат и субъективен в интерпретации.

Исследования в области классификации, математического моделирования и автоматизации анализа силлабо-тонических и тонических стихотворений проводились как российскими, так и зарубежными исследователями. Крупнейший отечественный филолог и стиховед Гаспаров М.Л. дал общее определение структуры силлабо-тонических и тонических стихотворений, показал эффективность использования статистических методов исследования поэтических текстов [1]. Вопросы автоматического распознавания метрико-ритмических параметров стихотворений исследовали Пильщиков И.А., Старостин А.С. [2]. Классификацию стихотворений на основе интервальной модели предложил Брейдо Е.М. [3]. Существуют и другие алгоритмы, но создать систему, которая автоматически анализирует структуру стихотворения и классифицирует его по ритмико-метрическим характеристикам оказалось довольно сложно. В настоящее время в интернете доступно две программы, написанные самодеятельными авторами: десктопная программа «Ритм во мне» Зигули С.Н. и сайт «Рифмовед.ру» Онуфриева В.В. более-менее точно определяют размер, ритм и тип рифмовки стихотворения. В обзоре доктора технических наук Кожемякиной О.Ю. [4] отмечено, что указанные программы заметно уступают в точности разработке Института вычислительных технологий СО РАН «Программная система автоматизированного комплексного анализа русских поэтических текстов». Также подчёркивается, что это единственная на 2023 год научно обоснованная и апробированная система. Данная система [5] доступна по адресам http://poem.ict.nsc.ru/ и http://poem.ict.nsc.ru/meterrhyme/analyze/.

По неизвестной причине в обзор Кожемякиной О.Ю. не попала Программа метрико-ритмического анализа стихотворений, написанных в силлабо-тонической системе (интеллектуальная система «Fet.Online»), зарегистрированная Роспатентом в 2021 году [6]. В 2025 году система «Fet.Online» дополнена модулем анализа чисто тонических стихотворений. В отличии от всех упомянутых программ система «Fet.Online» отличает тоническое стихотворение от силлабо-тонического, выдаёт метрико-ритмические характеристики в зависимости от типа организации стихотворения, а также визуализирует схему стихотворения. Система доступна по адресу https://fet.vpoezii.online/.

Материалы и методы исследования

В данной статье представлен подход к автоматизированному анализу тонических стихотворений с использованием JavaScript, включающий возможности визуализации и определения ритмического рисунка. Раскрывается математический аппарат и соответствующий программный код.

Основные принципы тонического стихосложения

Формальные параметры стиха

Для формального описания тонического стиха введём следующие обозначения:

  • S — строка стихотворения
  • n — общее количество слогов в строке S
  • k — количество ударных слогов в строке S
  • dᵢ — количество безударных слогов между i-м и (i+1)-м ударными слогами (где i = 1, 2, …, k-1)

Ключевые правила тонической системы

  1. Постоянство ударений: Для любых двух строк S₁ и S₂ выполняется k₁ = k₂. Количество ударных слогов в строках стихотворения должно быть одинаковым.
  2. Вариативность слогов: Для двух строк S₁ и S₂ возможно n₁ ≠ n₂. Общее количество слогов может варьироваться.
  3. Гибкость интервалов: Для двух строк S₁ и S₂ возможно d₁ᵢ ≠ d₂ᵢ для некоторых i. Количество безударных слогов между ударными может изменяться.
  4. Ограничение на безударные последовательности: Не допускается более трёх безударных слогов подряд.

Алгоритм анализа тонических стихотворений

Представленная программа реализует комплексный подход к анализу тонических стихотворений, включающий следующие этапы:

1. Предварительная обработка текста

function splitLines(poem, commentsDiv, repeat) {

    // Разбиваем текст на строки по символам новой строки

    var lines = poem.split(‘\n’);

    // Выводим информацию только при первом проходе анализа

    if (repeat == 1) {

        commentsDiv.innerHTML += ‘<b>Анализ подготовлен интеллектуальной системой Fet.Online (свидетельство Роспатента от 22.03.2021 №2021614295) <br><br></b>’;

        commentsDiv.innerHTML += ‘<b>Исходные строки:</b><br><br>’ + lines.join(‘<br>’) + ‘<br><br>’;

    }

    return lines;

}

Программа начинает с разделения входного текста на отдельные строки, сохраняя их исходный порядок. Этот этап важен для последующего построчного анализа.

2. Статистический анализ ударений

function countStresses(lines) {

    var stressCounts = [];

    for (var i = 0; i < lines.length; i++) {

        // Находим все заглавные гласные (ударные слоги) в строке

        var uppercaseVowels = lines[i].match(/[АЕЁИОУЫЭЮЯ]/g) || [];

        stressCounts.push(uppercaseVowels.length);

    }

    return stressCounts;

}

function findMostFrequentCount(stressCounts, commentsDiv, repeat) {

    // Создаём частотный словарь количества ударений

    var countMap = {};

    for (var i = 0; i < stressCounts.length; i++) {

        var count = stressCounts[i];

        countMap[count] = (countMap[count] || 0) + 1;

    }

    // Находим наиболее часто встречающееся количество ударений

    var mostFrequentCount = 0;

    var maxFrequency = 0;

    for (var key in countMap) {

        if (countMap[key] > maxFrequency) {

            mostFrequentCount = parseInt(key);

            maxFrequency = countMap[key];

        }

    }

    if (repeat == 1) {

        commentsDiv.innerHTML += ‘<b>Наиболее часто встречающееся количество ударных гласных: ‘ + mostFrequentCount + ‘<br><br></b>’;

    }

    return mostFrequentCount;

}

Алгоритм подсчитывает ударные слоги в каждой строке (помеченные заглавными гласными буквами) и определяет наиболее типичное количество ударений для данного стихотворения. Это значение становится эталоном для последующего анализа.

3. Фильтрация строк и построение ритмической матрицы

function filterLines(lines, stressCounts, mostFrequentCount, commentsDiv) {

    var filteredLines = [];

    var excludedLines = [];

    var excludedIndices = [];

    // Разделяем строки на соответствующие и не соответствующие эталону

    for (var i = 0; i < lines.length; i++) {

        if (stressCounts[i] === mostFrequentCount) {

            filteredLines.push(lines[i]);

        } else {

            excludedLines.push(lines[i]);

            excludedIndices.push(i);

        }

    }

    // Выводим информацию об исключённых строках

    if (excludedLines.length > 0) {

        commentsDiv.innerHTML += ‘<b>Исключённые строки:</b><br><br>’ + excludedLines.join(‘<br>’) + ‘<br><br>’;

    }

    return { filteredLines, excludedLines, excludedIndices };

}

function createAndFillMatrix(filteredLines, matrixWidth) {

    var matrix = [];

    // Инициализируем матрицу заданной ширины

    for (var i = 0; i < filteredLines.length; i++) {

        matrix.push(new Array(matrixWidth).fill(‘_’));

    }

    for (var lineIndex = 0; lineIndex < filteredLines.length; lineIndex++) {

        var line = filteredLines[lineIndex];

        var vowels = line.match(/[АЕЁИОУЫЭЮЯаеёиоуыэюя]/g) || [];

        var stresses = (line.match(/[АЕЁИОУЫЭЮЯ]/g) || []).length;

        // Равномерно распределяем ударные позиции по строке

        var step = matrixWidth / (stresses + 1);

        var stressPositions = [];

        for (var i = 0; i < stresses; i++) {

            stressPositions.push(Math.round((i + 1) * step) – 1);

        }

        // Заполняем матрицу гласными с учётом ударений

        var vowelIndex = 0;

        var stressIndex = 0;

        for (var pos = 0; pos < matrixWidth; pos++) {

            if (stressIndex < stressPositions.length && pos === stressPositions[stressIndex]) {

                // Пропускаем безударные гласные перед ударной

                while (vowelIndex < vowels.length && vowels[vowelIndex] === vowels[vowelIndex].toLowerCase()) {

                    vowelIndex++;

                }

                if (vowelIndex < vowels.length) {

                    matrix[lineIndex][pos] = vowels[vowelIndex];

                    vowelIndex++;

                    stressIndex++;

                }

            } else if (vowelIndex < vowels.length && vowels[vowelIndex] === vowels[vowelIndex].toLowerCase()) {

                // Записываем безударные гласные

                matrix[lineIndex][pos] = vowels[vowelIndex];

                vowelIndex++;

            }

        }

    }

    return matrix;

}

Программа создаёт матрицу, где каждая строка представляет собой последовательность гласных исходного стиха с сохранением их ударности. Ударные гласные распределяются равномерно по строке матрицы, что позволяет выявить общий ритмический рисунок.

4. Визуализация ритмической структуры

function styleMatrix(matrix) {

    var styledMatrix = matrix.map(row => {

        return row.map(cell => {

            // Ударные гласные выделяем чёрным фоном

            if (cell === cell.toUpperCase() && cell !== ‘_’) {

                return `<span class=”black-symbol”>${cell}</span>`;

            }

            // Безударные гласные — белым фоном

            else {

                return `<span class=”white-symbol”>${cell}</span>`;

            }

        }).join(‘ ‘);

    }).join(‘<br>’);

    return styledMatrix;

}

Для наглядности программа использует цветовое кодирование: ударные гласные отображаются на чёрном фоне, безударные — на белом. Такой подход позволяет быстро оценить ритмическую структуру стихотворения.

5. Определение ритмического рисунка

function calculateRhythm(matrix) {

    var rhythmMatrix = [];

    for (var i = 0; i < matrix.length; i++) {

        var rhythm = [];

        for (var j = 0; j < matrix[i].length; j++) {

            // Ударные гласные кодируем как 2, безударные как 0

            if (matrix[i][j] === matrix[i][j].toUpperCase() && matrix[i][j] !== ‘_’) {

                rhythm.push(2);

            } else {

                rhythm.push(0);

            }

        }

        rhythmMatrix.push(rhythm);

    }

    return rhythmMatrix;

}

function analyzeRhythmColumns(rhythmMatrix) {

    var columnAverages = [];

    // Анализируем каждый столбец матрицы ритма

    for (var col = 0; col < rhythmMatrix[0].length; col++) {

        var sum = 0;

        for (var row = 0; row < rhythmMatrix.length; row++) {

            sum += rhythmMatrix[row][col];

        }

        // Вычисляем среднее значение и округляем вверх

        var average = sum / rhythmMatrix.length;

        columnAverages.push(Math.ceil(average));

    }

    return columnAverages;

}

Программа преобразует матрицу гласных в числовую матрицу ритма (2 — ударение, 0 — отсутствие ударения), а затем вычисляет средние значения по столбцам. Это позволяет выявить устойчивые ритмические закономерности.

6. Коррекция исключённых строк

function fixExcludedLine(line, averageStresses, rhythm) {

    var vowels = line.match(/[АЕЁИОУЫЭЮЯаеёиоуыэюя]/g) || [];

    var stresses = (line.match(/[АЕЁИОУЫЭЮЯ]/g) || []).length;

    // Корректируем строки, где количество ударений отличается на 1 от эталона

    if (Math.abs(stresses – averageStresses) === 1) {

        var words = line.split(/[\s,.!?;:]+/).filter(word => word.length > 0);

        // Ищем односложные слова для коррекции ударений

        for (var i = 0; i < words.length; i++) {

            var word = words[i];

            var wordVowels = word.match(/[АЕЁИОУЫЭЮЯаеёиоуыэюя]/g) || [];

            if (wordVowels.length === 1) { // Односложные слова

                var vowelIndex = word.search(/[АЕЁИОУЫЭЮЯаеёиоуыэюя]/);

                var isStressed = word[vowelIndex] === word[vowelIndex].toUpperCase();

                // Сравниваем с общим ритмом

                var rhythmIndex = rhythm.indexOf(2);

                if (rhythmIndex !== -1 && Math.abs(vowelIndex – rhythmIndex) <= 1) {

                    if (stresses > averageStresses && isStressed) {

                        // Убираем ударение

                        words[i] = word.substring(0, vowelIndex) +

                            word[vowelIndex].toLowerCase() +

                            word.substring(vowelIndex + 1);

                        return words.join(‘ ‘);

                    } else if (stresses < averageStresses && !isStressed) {

                        // Добавляем ударение

                        words[i] = word.substring(0, vowelIndex) +

                            word[vowelIndex].toUpperCase() +

                            word.substring(vowelIndex + 1);

                        return words.join(‘ ‘);

                    }

                }

            }

        }

    }

    return null;

}

Алгоритм пытается автоматически корректировать строки, которые незначительно отклоняются от основного ритма, изменяя ударения в односложных словах. Это позволяет включить в анализ больше строк без искажения общего ритмического рисунка.

7. Проверка соответствия тонической системе

function checkTonicSystem(columnAverages, resultDiv) {

    var isValidTonic = true;

    var errors = [];

    var stressCount = columnAverages.filter(x => x === 2).length;

    // Проверка минимального количества ударных позиций

    if (stressCount < 2) {

        isValidTonic = false;

        errors.push(‘Менее двух ударных позиций.’);

    }

    // Проверка окружения ударных позиций

    for (var i = 0; i < columnAverages.length; i++) {

        if (columnAverages[i] === 2) {

            if (i > 0 && columnAverages[i – 1] !== 0) {

                isValidTonic = false;

                errors.push(`Ударная позиция ${i} не имеет безударной позиции слева.`);

            }

            if (i < columnAverages.length – 1 && columnAverages[i + 1] !== 0) {

                isValidTonic = false;

                errors.push(`Ударная позиция ${i} не имеет безударной позиции справа.`);

            }

        }

    }

    // Проверка на длинные безударные последовательности

    var zeroStreak = 0;

    for (var i = 0; i < columnAverages.length; i++) {

        if (columnAverages[i] === 0) {

            zeroStreak++;

            if (zeroStreak > 3) {

                isValidTonic = false;

                errors.push(‘Найдено более трёх безударных позиций подряд.’);

                break;

            }

        } else {

            zeroStreak = 0;

        }

    }

    // Формируем итоговое заключение

    if (isValidTonic) {

        resultDiv.innerHTML += ‘<b>Стихи соответствуют тонической системе. Обнаружен ‘ + stressCount + ‘-х ударный тонический ритм.<br></b>’;

    } else {

        resultDiv.innerHTML += ‘<b>Ритм НЕ соответствует тонической системе. Ошибки:<br></b>’;

        resultDiv.innerHTML += errors.join(‘<br>’) + ‘<br>’;

    }

}

Финальная проверка оценивает, соответствует ли выявленный ритмический рисунок критериям тонического стихосложения, включая требования к количеству ударений, их окружению и максимальной длине безударных последовательностей.

Пример работы программы (вид интерфейса)

Анализ подготовлен интеллектуальной системой Fet.Online (свидетельство Роспатента от 22.03.2021 №2021614295)

Исходные строки:

на святОй русИ, нАшей мАтушке,
нЕ найтИ, не сыскАть такОй красАвицы:
хОдит плАвно — бУдто лебЕдушка;
смОтрит слАдко — кАк голУбушка;

мОлвит слОво — соловЕй поЁт;
горЯт щЁки еЁ румЯные,
как зарЯ нА нЕбе бОжием;
кОсы рУсые, золотИстые,

в лЕнты Яркие заплетЁнные,
пО плечАм бегУт, извивАются,
с грУдью бЕлою цалУются.

Наиболее часто встречающееся количество ударных гласных: 4

Схема ударных и безударных гласных для строк с 4 ударными гласными:

Исключённые строки:

нЕ найтИ, не сыскАть такОй красАвицы:
кОсы рУсые, золотИстые,
в лЕнты Яркие заплетЁнные,
с грУдью бЕлою цалУются.

Схема ударных и безударных гласных, включая исправленные строки:


Итоговый ритм: 0 0 2 0 0 2 0 0 0 2 0 0 2 0 0.

Стихи соответствуют тонической системе. Обнаружен 4-х ударный тонический ритм.

Конец примера.

Таким образом, программа последовательно:

  1. Разбивает текст на строки.
  2. Определяет, что наиболее часто встречается 4 ударения в строке.
  3. Исключает строки с другим количеством ударений (4 строки).
  4. Корректирует исключённые строки, меняя ударения в односложных словах.
  5. Строит матрицу гласных с равномерным распределением ударений.
  6. Визуализирует матрицу с цветовым выделением ударных гласных.
  7. Определяет итоговый ритмический рисунок: 0 2 0 0 2 0 0 2 0 2 0.
  8. Делает вывод о соответствии тонической системе: «Стихи соответствуют тонической системе. Обнаружен 4-х ударный тонический ритм».

Заключение и перспективы развития

Представленная программа обеспечивает комплексный анализ тонических стихотворений, сочетая статистические методы с визуализацией результатов. Алгоритм включает:

  1. Определение ритмического рисунка за счёт равномерного распределения ударений.
  2. Визуальную схему расположения ударных и безударных слогов.
  3. Автоматическую коррекцию незначительных отклонений от основного ритма.
  4. Проверку соответствия критериям тонического стихосложения.

Сервис доступен для исследователей по адресу https://fet.vpoezii.online/tonic/ и является частью интеллектуальной системы Fet.Online (свидетельство Роспатента от 22.03.2021 №2021614295).

Направления дальнейшего развития

  1. Многоязычная поддержка: Адаптация алгоритма для анализа стихов на других языках с фиксированным или предсказуемым ударением (романские, славянские, финно-угорские языки).
  2. Контекстный анализ: Интеграция словарей ударений и морфологического анализа для автоматического определения ударений в случаях, когда они не обозначены явно.
  3. Машинное обучение: Применение методов классификации для автоматического определения типа стихосложения и выявления скрытых ритмических паттернов.
  4. Расширенная визуализация: Разработка интерактивных схем ритма с возможностью навигации по отдельным строкам и их сравнения.
  5. Исторический анализ: Создание базы данных ритмических паттернов для изучения эволюции тонического стихосложения в разные периоды.

Автоматизированный анализ тонических стихотворений открывает новые возможности для исследователей поэзии, педагогов и самих поэтов, предоставляя инструменты для глубокого понимания ритмической структуры стиха.

Список литературы

  1. Гаспаров, М. Л. Собрание сочинений в шести томах. Т. 4: Стиховедение / Михаил Леонович Гаспаров; сост. И. А. Пильщикова, Д. В. Сичинавы, А. Б. Устинова. – М.: Новое литературное обозрение, 2022. 
  2. Пильщиков И.А., Старостин А.С. Проблема автоматического распознавания метра: силлаботоника, дольник, тактовик. Отечественное стиховедение: 100-летние итоги и перспективы развития. Материалы Международной научной конференции. 25–27 ноября 2010 г. СПб.; 2010: 397–406.
  3. Брейдо Е.М. Интервальная модель русской метрики и строгий тонический стих. Вопросы языкознания. 2021; (5):106–136.
  4. Кожемякина О.Ю. Информационные системы анализа поэтических текстов: история, методы и алгоритмы. 2023; 28(3):136–166. DOI:10.25743/ICT.2023.28.3.009.
  5. Барахнин В.Б., Кожемякина О.Ю., Забайкин А.В., Хаятова В.Д. Автоматизация комплексного анализа русского поэтического текста: модели и алгоритмы. Вестник НГУ. Сер.: Информационные технологии. 2015; 13(3):5–18.
  6. Свидетельство о государственной регистрации программы для ЭВМ «Программа метрико-ритмического анализа стихотворений, написанных в силлабо-тонической системе (интеллектуальная система «Fet.Online»)», Морозов А.Ю., Свидетельство о регистрации программы для ЭВМ RU 2021614295 от 22.03.2021. Заявка № 2021613231 от 11.03.2021.