Documentation

This commit is contained in:
Alexander Yakovlev 2011-04-22 19:49:59 +07:00
parent 769fef28aa
commit cdc8956991
9 changed files with 1834 additions and 0 deletions

18
README.markdown Normal file
View File

@ -0,0 +1,18 @@
#Тогаталту
Перевод стихов с любого языка на русский
##Инструкции по запуску
Программа требует Ruby 1.9+, на 1.8 даже не пробуйте запускать. Также нужен php5 (CLI). На Windows лучше, если оба интерпретатора прописаны в PATH. Для GUI нужен wxRuby.
Программа имеет две оболочки:
* Console.rb — консольный интерфейс. Запустить и ждать.
* Main.rb — графический интерфейс. Требует wxRuby:
gem install wxruby
##Portable mode
Если вы хотите записать программу на флешку, скиньте куда-нибудь Ruby с установленным wxRuby (можно просто скопировать все файлы из уже установленного) и PHP.
Затем надо отредактировать файл morphology.rb, прописать там путь к PHP.
Запускать через батник или командную строку.
##Документация
Основная документация находится в папке doc, собирается командой make. Она написана на XeLaTeX.

53
doc/01.Title.tex Normal file
View File

@ -0,0 +1,53 @@
\usepackage[T2A]{fontenc}
\usepackage{fontspec}
\usepackage{xunicode}
\usepackage{xltxtra}
\usepackage{polyglossia}
\setdefaultlanguage{russian}
\defaultfontfeatures{Mapping=tex-text, Scale=MatchLowercase}
\setmainfont{FreeSerif}
\newfontfamily{\cyrillicfont}{FreeSerif}
\setromanfont{FreeSerif}
\setsansfont{FreeSans}
\setmonofont{FreeMono}
\frenchspacing
\usepackage[labelsep=period]{caption}
\usepackage{indentfirst}
\usepackage{fncychap}
\ChNameVar{\large}
\ChTitleVar{\Large \rm \bfseries}
\ChNameUpperCase
\setcounter{secnumdepth}{-1}
\setcounter{tocdepth}{2}
\usepackage{geometry}
\geometry{left=3cm}
\geometry{right=2cm}
\geometry{top=2cm}
\geometry{bottom=2cm}
\marginparwidth=0cm
\renewcommand{\theenumi}{\arabic{enumi}.}
\renewcommand{\labelenumi}{\arabic{enumi}.}
\renewcommand{\theenumii}{\arabic{enumii}.}
\renewcommand{\labelenumii}{\arabic{enumi}.\arabic{enumii}.}
\renewcommand{\theenumiii}{\arabic{enumiii}.}
\renewcommand{\labelenumiii}{\arabic{enumi}.\arabic{enumii}.\arabic{enumiii}.}
\renewcommand{\baselinestretch}{1.5}
\righthyphenmin=2
\pagestyle{myheadings}
\begin{document}
\title{Документация системы «Тогаталту»}
\author{Oreolek}
\maketitle
\renewcommand{\contentsname}{Содержание}
\setlength{\parskip}{0ex plus 0.5ex minus 0.2ex}
\tableofcontents
\clearpage

44
doc/02.Theory.tex Normal file
View File

@ -0,0 +1,44 @@
\chapter{Краткое теоретическое вступление}
\subsection{Основные понятия}
Существует два основных типа стихотворных переводов:
\begin{enumerate}
\item Перестраивающий (содержание, форму)
\item Воссоздающий --- то есть, воспроизводящий с возможной полнотой и точностью содержание и форму.
\end{enumerate}
Первый вид перевода также часто называют вольным. Он не так высоко ценится, как воссоздающий (точный) перевод, но легче выполняется человеком (так как позволяет не следить за точным совпадением содержания и формы).
Для машинного перевода более подойдёт точный тип поведения, так как он наиболее формализован.
Важные отличия стихотворной формы от прозаической -- это наличие ритма и чёткого разбиения на строки, строфы и стихи. И хотя наличие ритма не является обязательным (так, у некоторых народов мира он может отсутствовать; кроме того, некоторые авторы намеренно отходят от ритма), будем рассматривать его как необходимый признак стихотворения.
Ритмичность складывается из чередования ударных и безударных слогов, тем более, что ударение в русском языке подвижно (к противному примеру, французский язык имеет ударение только на последний слог).
Ритм обычно един для всего стихотворения и позволяет лишь незначительные отклонения. Тем не менее, слова также имеют ударные и безударные слоги -- например, в литературном русском нет слова <<\'{о}кно>> с ударением на первый слог. На безударный слог нельзя ставить ударение, иначе это может сильно повредить прочтению вслух. Важно оговориться, что ударные слоги напротив, могут стать безударными.\label{distance}
Итак, перевод должен максимально точно сохранять форму и содержание исходного документа.
\bigskip
%Вариантов этих определений так много, что я смело взял самые удобные.
\begin{description}
\item[Фраза] --- это законченное высказывание.
\end{description}
Как \textbf{предложение} удобно понимать последовательность идущих друг за другом фраз, возможно, соединённых сочинительным союзом.
Фразы являются смысловыми единицами -- например, они могут быть однородными; в этом предложении их три.
\bigskip
\begin{description}
\item[Стопа] --- постоянная единица деления стиха, определяющая его метр. В силлабо-тонике это повторяющееся в пределах стихотворной строки сочетание одного ударного слога и определённого числа безударных слогов, \cite{literature-rosman}
\item[Вольный стих] --- форма стихотворного произведения, в которой все строки выдержаны в едином силлаботоническом метре, но неравностопны, \cite{literature-rosman}
\item[Метр] --- абстрактная, предельно общая ритмическая схема для каждой из строк стихотворного произведения, \cite{literature-rosman}
\item[Размер] --- абстрактная ритмическая схема, которой подчиняется индивидуальный ритм каждой строки отдельного стихотворного текста. Размер определяют в зависимости от системы стихосложения. В силлабике по постоянному числу слогов, составляющих каждый стих. В силлабо-тонике по постоянному числу стоп конкретного метра во всех строках текста или в тех, что занимают определённые позиции в каждой его строфе. В тонике размер определяют по постоянному числу ударений, \cite{literature-rosman}
\item[Рифма] --- полное или частичное совпадение звуков в конце стиха, начиная с последней ударной гласной.
\end{description}
Я не буду приводить теорию по переводу, так как в реализованной программе используется простая пословная подстановка.

190
doc/03.Algorithm.tex Normal file
View File

@ -0,0 +1,190 @@
\chapter{Алгоритм работы}
\begin{enumerate}
\item Получение исходного текста из оболочки
\item Составление карты ударений
\item Поиск рифмованных строк
\item Замена фразеологизмов
\item Пословный перевод — слова складываются в стек
\item Оформление перевода
\begin{enumerate}
\item Деление карты ударений на строки. Начало цикла по строкам.
\item Установка счётчика на начало строки.
\item Начало цикла по счётчику. Цикл продолжается, пока счётчик не пройдёт конец строки.
\item Получение слова из стека переведённых слов.
\item Получение всех словоформ этого слова.
\item Если слово — последнее или предпоследнее в строке, то отсеивание всех не рифмующихся (или плохо рифмующихся) форм. Если все формы не подходят — отсеивание не используется.
\item Вычисление для каждой формы различия с отрезком карты ударений.
\item Любой (первый) вариант из подходящих записывается в перевод.
\item Счётчик передвигается вперёд на количество слогов в поставленной форме. Конец цикла по счётчику.
\item Вывод новой строки в перевод. Конец цикла по строкам.
\end{enumerate}
\item Вывод результата в оболочку
\end{enumerate}
Возможна паралеллизация пунктов 2 и 3, а также на пунктах 1, 2, 4 и 5.
\subsection{Составление карты ударений}
Так как ударения должны быть уже проставлены в исходном тексте, этот этап алгоритма тривиален. Текст сканируется на гласные; при обнаружении гласной с проставленным ударением, или знака ударения\footnote{Апостроф не считается знаком ударения. Во-первых, потому что он может использоваться в тексте, во-вторых, потому что программа работает в кодировке UTF-8 и может использовать все знаки этой кодировки.} в карту ставится знак «!», при обнаружении безударной гласной — знак «-». Пробелы не отслеживаются, переносы строк записываются.
Важно отметить,что ритм не обязан быть чётким, например:
\begin{verse}
Ярко солнце светит,\\
Щебечет воробей.\\
Добрым жить на белом свете\\
Веселей.
\end{verse}
\hskip 6cm \textit{(А. Хайт)}
Именно поэтому анализ идёт построчно.
\subsection{Поиск рифмованных строк}
Используются два вложенных цикла по строкам. В каждом из них находятся ударные гласные последних слов строк. Если гласные совпадают, то сравниваются также ударные гласные предпоследних слов строк. Количество совпадающих гласных записывается в хэш по номерам строк.
\subsection{Замена фразеологизмов}
Замена идиом, фразеологизмов и сленга на общеупотребительную лексику. К этому моменту ритм уже должен быть вычислен, а рифмы — найдены.
\subsection{Определение рифмы}
Один из самых сложных алгоритмов --- алгоритм подбора рифмы. Здесь нужно остановиться и описать варианты поподробнее. Не будем рассматривать внутреннюю рифму, когда рифмуются также середины строк, так как в этом случае каждую строку можно разбить на две.
\subsubsection{Точное совпадение}
В самом абстрактном приближении рифма --- это совпадение последних букв в строках:
\begin{verse}
Упал со стола ботинок,\\
За ним --- полуботинок.\\
Украл ботинки инок.
\end{verse}
Как видно из примера, этот алгоритм имеет существенный недостаток: он может зарифмовать все строки одним словом или его производными. Это плохо читается, это очень сильно порицается поэтами и это практически относится к тавтологии. Такие стихи могут существовать, но они все будут очень низкой пробы. Кроме того, в этом алгоритме нет никакой фантазии. Как известно, в русском языке есть несколько слов, не имеющих рифмы вообще (т.н. арифматы), например, <<ж\'{и}вопись>>. Подобный алгоритм будет просто повторять эти слова из строки в строку.
\subsubsection{Точное совпадение гласных}
Этот подход чуть вольнее предыдущего; в нём имеют значение только \textbf{гласные} в окончаниях строк. Гласные должны совпадать, совпадение же согласных необязательно. Вот демонстрация такого алгоритма:
\begin{verse}
Трам-парам-парам-опилки!\\
Пум-шурум-бурум-шуминги!
\end{verse}
Это был вариант среднего удобочитания. Есть и похуже:
\begin{verse}
Всё будет сегодня отлично!\\
Нашёл я коробку ботинков!
\end{verse}
Даже если потребовать,чтобы рифмующиеся слова имели одинаковую длину и окончания, рифма <<отлично---ботинко>> не совсем радует слух. Поэтому этот алгоритм имеет ещё более серьёзный недостаток: он очень редко работает. Удачная рифма в таком алгоритме --- не более,чем совпадение; действительно, согласных в словах намного больше,чем гласных, и получить рифмующиеся слова будет очень сложно.
Для ускорения работы можно потребовать совпадения лишь ударных гласных. Это и используется в программе.
\subsubsection{Созвучие букв в слогах}
Рифма всегда определяется произношением. В любой рифме окончания строк всегда созвучны. Но при этом рифмы принято делить на точные и неточные.
При использовании точной рифмы созвучными оказываются не только ударные звуки в окончаниях строк, но и слоги, расположенные за ними. Неточная рифма характеризуется различиями в звучании согласных в свободных от ударения слогах, расположенных в окончаниях строк.
Пример точной рифмы:
\begin{verse}
Я встретил слонопопотама\\
С фамилией Ятутатама...
\end{verse}
Пример неточной рифмы:
\begin{verse}
Я встретил слонопопотама\\
С фамилией Нипокадрано...
\end{verse}
В этих примерах очень мало смысла, но они прекрасно демонстрируют принцип рифмовки.
Ударные слоги должны быть созвучными. Совпадение --- частный случай созвучия.
Чем дальше ударный слог рифмы от конца строки, тем менее важно всё,что стоит перед ним. В трёхсложных и четырёхсложных рифмах созвучие пятых слогов от конца уже не так важно. При этом созвучие ударных слогов должно быть точным, а для безударных это необязательно. Если слоги, стоящие после ударного, малосозвучны, это тоже считается рифмой (хотя и плохой). Но важно созвучие всего ударного слога, а не только гласной в нём.
Созвучие проще всего определить при помощи видовых и родовых пар. Видовые пары --- это взаимозаменяемые гласные звуки в рифме. Каждая видовая пара состоит из твёрдой и мягкой гласной.
\begin{itemize}
\item А
\item О
\item У
\item Э-Е
\item Ы-И
\end{itemize}
Любой ударный твёрдый гласный звук рифмуется с его мягкой парой, и наоборот.
Согласные звуки объединены в родовые пары и тройки:
\begin{itemize}
\item Б-П
\item В
\item Д-Т
\item Ж-Ш
\item З-С
\item К-Г-Х
\item Ц-Ч-Щ
\end{itemize}
Звонкая согласная в контексте рифмы всегда рифмуется с её глухой парой, и наоборот.
Насчёт троек следует оговориться. К-Х, как и Ц-Щ, не являются парными согласными. Рифмы с ними допустимы при определённых обстоятельствах, но они не будут высоки по качеству:
\begin{verse}
Как тогда один пустяк\\
Уничтожил в один взмах.
\end{verse}
\begin{verse}
Как из города Елец\\
К нам пришёл огромный клещ
\end{verse}
Поэтому при реализации лучше опираться на \textbf{пары} согласных, разбивая тройки надвое.
Этот алгоритм также не гарантирует защиту от повторения арифматов, но он имеет б\'{о}льшую гибкость в подборе, а значит, и меньшую склонность к тавтологии.
\subsubsection{Созвучие слогов}
Предыдущий алгоритм хорош, но всё-таки не выдерживает критики. Почему для определения созвучия слогов используются буквы, а не звуки? Логичнее использовать другой подход: составлять звуковые транскрипции слов и определять созвучие по ним. Этот метод точнее, но также сложнее. Количество звуков в слове чаще всего не равно количеству букв, и гласные буквы могут выражаться несколькими звуками. Следовательно, разбиение слова по слогам несколько затрудняется.
Основных звуков 43: [а э и о у ы п п' б б' м м' ф ф' в в' т т' д д' н н' с с' з з' р р' л л' ш ж щ җ ц ч й к к' г г' х х']
Также стоит выделять звуки с оттенками: так, в слове <<йети>> транскрипция выглядит как [йэт’и$^э$]. Оттенков может быть шесть, и они применяются ко всем согласным. То есть, общее число звуков равно 6+1+35*7=252.
Но это -- всего лишь мелкое неудобство. Дело в том,что сейчас нет верного алгоритма для автоматической расстановки транскрипции. Более того: многие слова в словаре имеют несколько верных транскрипций. Таким образом, необходимо составлять словарь произношений, в связи с чем сложность реализации алгоритма по сравнению со сложностью реализации предыдущего алгоритма значительно возрастает\footnote{Можно отказаться от оттенков - в таком случае автотранскрипция возможна, но это снизит возможности для перебора рифм.}.
Защиты от повторения арифматов алгоритм не имеет.
Сложность этого этапа алгоритма состоит в огромном количестве комбинаций и перестановок, которые потребуется просчитать.
\subsection{Разбивка русского слова на слоги}
В одном слоге не может быть больше одной гласной.
\subsection{Расстановка ударения на русском}
В русском языке слово может иметь, помимо основного, второстепенное (побочное) ударение ~\cite{udar}.
Если в слове есть буква <<ё>>, на неё всегда ставится ударение.
В односложных словах ударение ставится однозначно, если это не служебное слово или частица. Односложные предлоги и союзы чаще являются безударными словами.
Также возможен перенос ударения на предлог (н\'{а} воду), если существительное не имеет достаточной важности в тексте. Перенос возможен для односложных предлогов; чаще всего это НА, ЗА, ПОД, ПО, ИЗ, БЕЗ. Ударение не переносится на предлог в сочетании с числительными ~\cite{orfo}.
Из двусложных предлогов безударными являются ИЗ-ЗА, ИЗ-ПОД, ПОДО, НАДО, ОБО, ОТО, ИЗО.
Слабоударяемые слова\footnote{После, кругом, мимо, вокруг, напротив, поперёк, около и др. ~\cite{rosental}} являются особенностью русского языка и в исследование не берутся, так как ритм стихотворения берётся из перевода.
Вычисленные частоты можно посмотреть в коде программы. Из списков убраны высокочастотные шумы.
Разбивка на слоги производилась автоматически в соответствии с указанными правилами. Всего было обработано 20140 слов.
Относительные частоты высчитывались от всего количества слогов из данной группы (под ударением, без ударения, побочное ударение).

BIN
doc/Classes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

63
doc/Main.tex Normal file
View File

@ -0,0 +1,63 @@
\documentclass[a4paper,14pt]{extreport}
\input{01.Title}
\input{02.Theory}
\input{03.Algorithm}
\chapter{Реализация}
Модуль вызова системы включает в себя пользовательский интерфейс. Он отвечает за ввод и представление данных.
Главный класс Source (модуль source.rb) отвечает за основную логику.
Класс Translator (translator.rb) содержит функцию перевода слов. Логика программы не зависит от языка исходного текста, так как ударения указываются вручную, но словари готовы только для английского языка.
Класс Morphology сожержит функцию, которая вызывает библиотеку phpmorphy, чтобы получить все словоформы заданного слова. Библиотека phpmorphy распространяется по лицензии LGPL и использует словари Ispell, а также пытается угадать склонение слов.
Система рассчитана на работу с латинским алфавитом\footnote{На это настроен отлов гласных.} и использует кодировку UTF-8.
Система получает на входе текстовый документ и выдаёт переведённый текстовый документ.
\subsection{Формат словарей}
Словари имеют расширение \verb/.txt/.
Переводы слов идут сразу после слов. Перед переводами ставится ровно два пробела.
Количество переводов не ограничено, но выбирается только один. Это поведение может измениться в будущем.
\begin{verbatim}
ово
перевод1
перевод2
...
\end{verbatim}
Для перевода может использоваться онлайн-сервис переводческой памяти \linebreak \underline{http://mymemory.translated.net.} Он собирает переводы слов по Интернету (используя Википедию, Google Translate и поиск по сайтам) и объединяет их в одну базу переводов. Сервис поддерживает 69\footnote{Считал вручную, мог ошибиться. Замечу, что в списке есть даже староанглийский.} языков. Собственная реализация была отложена ввиду низкого качества и огромной трудоёмкости.
Файл console.rb запускает консольный интерфейс. Информационные сообщения и вывод текста идут в окно терминала. Ввод текста пока что не реализован.
Файл main.rb запускает графический интерфейс, используя библиотеку wx\-Ruby. Информационные сообщения выводятся в специальном текстовом поле. Ввод текста осуществляется в левом текстовом поле; вывод появляется в правом.
Ударения указываются вручную. Это необходимо, так как поэты могут переставлять ударения по своей воле, и определить автоматически его не получится. Так как автоматического проставления ударения нет, то программа зависит от языка исходного текста только в ядре перевода. Опять же, ядро перевода поддерживает 69 языков -- то есть, программа может работать с 69 языками.
Язык вывода — только русский. Морфология вынесена в отдельный класс, но добавление нового языка потребует составления словаря либо модели.
\chapter{Что можно сделать}
Задача огромна, поэтому на многое у меня не хватило времени. Вот список того, что остаётся сделать.
\begin{itemize}
\item Словарь ударений либо усовершенствовать автоопределение.
\item Качественное ядро перевода (словарное либо вероятностное). Я достаточно плохо себе представляю этот пункт, поэтому не буду уточнять
\item Перебор нескольких вариантов перевода.
\item Память перевода (translated.net не в счёт) -- чтобы не переводить одни и те же строки (слова) дважды.
\item Переписать рифмовку так, чтобы она работала по строфам, а не по строкам.
\end{itemize}
Кстати, я бы не делал ставки на качество. Сложность одного алгоритма определения рифмы очень велика (а вызывается эта функция очень часто), а значит, программа будет работать ОЧЕНЬ долго. Заранее предопределённый ритм помогает решить, но не решает этой проблемы.
\bibliographystyle{utf8gost780u}
\bibliography{bibliography}
\end{document}

6
doc/Makefile Normal file
View File

@ -0,0 +1,6 @@
all:
xelatex Main.tex
bibtex Main.aux
xelatex Main.tex
xelatex Main.tex
rm -f *.aux *.log *.toc *.bbl *.blg *.out *.idx *.ind *.ilg *~

32
doc/bibliography.bib Normal file
View File

@ -0,0 +1,32 @@
@BOOK{udar,
composer = "Зарва, М. В.",
title = "Русское словесное ударение: Словарь",
address = "М.",
publisher = "НЦ ЭНАС",
year = 2001,
language = "russian"
}
@BOOK{orfo,
title = "Орфoэпичеcкий cлoварь руccкoгo языка",
address = "М.",
editor = "Р. И. Аванеcoва",
year = 1983,
language = "russian"
}
@BOOK{rosental,
author = "Розенталь, Д. Э. and Джанджакова, Е. В. and Кабанова, Н. П.",
title = "Справочник по правописанию, произношению, литературному редактированию",
address = "М.",
publisher = "ЧеРо",
year = 1999,
language = "russian"
}
@BOOK{literature-rosman,
editor = "проф. Горкина А.П.",
title = "Литература и язык. Современная иллюстрированная энциклопедия",
address = "М.",
publisher = "Росмэн",
year = 2006,
language = "russian"
}
%Да, Росмэн. Да, иллюстрированная. Но всё-таки редактора не с улицы взяли.

1428
doc/utf8gost780u.bst Normal file

File diff suppressed because it is too large Load Diff