Программа для расстановки ударений в тексте

Программа расстановки ударений

Осталось 2 000 символов

Программа использует данные
словаря Зализняка,
Викисловаря
и словаря odict.ru.

Заказать профессиональную расстановку ударений

Купить модуль расстановки ударений на Питоне

 

Для расстановки ударений в текстах предлагаем два сервиса: RussianGram , Морфер. Простые. Бесплатные. 

RussianGram (https://russiangram.com/) помогает читать и понимать по-русски, автоматически добавляя знаки ударения и точки над буквой Ё.

Анализ текста. Расстановка ударений в русских текстах

Морфер (https://morpher.ru/accentizer/)  – сервис расстановки ударений и др.

Анализ текста. Расстановка ударений в русских текстах

Дополнительно:

  • https://www.readyrussian.org/WebApps/StressFinder/
  • https://accentonline.ru/
  • https://udarenie.su/
  • https://textometr.ru/

Просмотров: 30582

Время на прочтение
8 мин

Количество просмотров 11K

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

Мой опыт

Я знаком с одной девушкой, которая изучает русский язык в университете Лейдена. Однажды я написал приложение для изучения русского, одной из функций которого была расстановка ударений. Я просто проверял каждое слово по словарю. Однако, это часто приводило к ситуации неоднозначности, когда ударение зависит от контекста. Например: «два сло́ва», но «длинные слова́». В подобных ситуациях мне ничего не оставалось делать, кроме как оставлять слово без ударения.

Идея

Но ведь неоднозначность возникает из-за того, что ударение зависит от того, в какой форме употреблено слово, от его морфологических показателей. Если мы сможем найти словарь ударений в зависимости от формы слова + научимся определять форму слова по контексту, то мы сможем разрешить неоднозначность. Морфологический анализ — одна из стандартных задач NLP, для ее решения воспользуемся библиотекой Spacy.

Данные

Где же нам найти подходящий словарь ударений? Интересующая нас информация есть в wiktionary.

Wiktionary

Wiktionary

Для парсинга wiktionary существует либа wiktionaryparser. Впрочем, для наших целей подойдёт уже готовый результат её работы. Json-файл содержит набор словоформ, для каждой из которых доступно ее написание с ударением, набор определений, а также маркер части речи. Кроме того, я распарсил словарь Зализняка и добавил те формы оттуда, которых не нашлось в wiktionary.

Для одного токена может быть несколько объектов-словоформ, которые отличаются частью речи (военный как прилагательное и военный как существительное) или смыслом (писа́ть и пи́сать).

Новый формат словаря

Новый формат словаря

Я перевел словарь в новый формат: каждому токену соответствует массив словоформ, для каждой словоформы определены поля accentuated (вид словоформы с ударением), form (морфологические показатели) и lemma (ссылка на лемму). Словарь сериализован с помощью pickle в wordforms.dat.

Словарь лемм

Словарь лемм

Кроме этого, я создал словарь лемм. Леммы содержат массив возможных частей речи + частотный ранг. Словарь лемм также сериализован с помощью pickle, в lemmas.dat.

Spacy

Spacy — это библиотека для NLP. Она умеет делать такие вещи как токенизация, морфологический анализ, синтаксический анализ, Named Entity Recognition. Нас интересуют первые две функции.

Мы будем использовать natasha-spacy, реализацию русского языка для spacy на основе natasha, поскольку она поддерживает более сложный морфологический анализ (падежи, времена), чем стандартная версия. Инструкция по настройке находится здесь.

Инициализация

import spacy
import pickle
ru_nlp = spacy.load('ru_core_news_md')

def load():
    with open(file="lemmas.dat", mode='rb') as f:
        lemmas = pickle.loads(f.read())
    with open(file="wordforms.dat", mode='rb') as f:
        wordforms = pickle.loads(f.read())
    return lemmas, wordforms
  
  
def introduce_special_cases_from_dictionary(dictionary):
    for word in dictionary:
        if (" " in word) or ("-" in word):
            if len(dictionary[word]) == 1:
                ru_nlp.tokenizer.add_special_case(word, [{"ORTH": dictionary[word][0]["accentuated"]}])
                ru_nlp.tokenizer.add_special_case(word.capitalize(), [{"ORTH": dictionary[word][0]["accentuated"].capitalize()}])
                
lemmas, wordforms = load()
introduce_special_cases_from_dictionary(wordforms)

f = open("in.txt", mode='r', encoding='utf-8')
text = f.read()
f.close()

res = accentuate(text, wordforms, lemmas) 

f = open("out.txt", mode='w', encoding='utf-8')
f.write(res)
f.close()

Сначала загрузим наши словари, затем модифицируем токенизатор: добавим нестандартные (содержащие дефис или пробел) токены из нашего словаря. Это нужно из-за случаев наподобие «по-моему»: иначе слово будет разделено на «по», «-» и «моему», с неправильным ударением в «моему».

Токенизация и морфологический анализ

def tokenize(text, wordforms):
    res = []
    doc = ru_nlp(text)
    for token in doc:
        if token.pos_ != 'PUNCT':
            word = {"token": token.text, "tag": token.tag_}
            if word["token"] in wordforms:
                word["interpretations"] = wordforms[word["token"]]
            if word["token"].lower() in wordforms:
                word["interpretations"] = wordforms[word["token"].lower()]
            word["lemma"] = token.lemma_
            word["is_punctuation"] = False
            word["uppercase"] = word["token"].upper() == word["token"]
            word["starts_with_a_capital_letter"] = word["token"][0].upper() == word["token"][0]
        else:
            word = {"token": token.text, "is_punctuation": True}
        word["whitespace"] = token.whitespace_
        res.append(word)
    return res

Делаем одновременно токенизацию и морфологический анализ.

Каждое слово представляем в виде словаря со значениями:

  • token — собственно запись словоформы (в нижнем регистре)

  • tag — набор морфологических показателей. Строка tag может выглядеть, например, так: «NOUN__Animacy=Inan|Case=Gen|Gender=Masc|Number=Plur» или «‘VERB__Aspect=Perf|Mood=Imp|Number=Plur|Person=Second|VerbForm=Fin|Voice=Act'»

  • interpretations — набор объектов из словаря (возможно, с различными ударениями), которыми может быть наш токен

  • lemma — исходная лемма токена с точки зрения spacy

  • is_punctuation — признак принимает значение True не только для знаков пунктуации, но и для «специальных случаев» (см. предыдущий раздел про инициализацию spacy).

  • starts_with_a_capital_letter — мы переводим все токены в нижний регистр, и отдельно запоминаем, а было ли слово изначально написано с большой буквы

  • uppercase — написано ли слово полностью в верхнем регистре

  • whitespace — содержит пробел, если после токена идёт пробел. Нужно для восстановления результата

Совместимость морфологических показателей

Для каждой возможной «интерпретации» токена мы будем проверять, совместима ли она с морфологическими тегами, которые выдал spacy.

def compatible(interpretation, lemma, tag, lemmas):
    if lemma in lemmas:
        pos_exists = False
        possible_poses = lemmas[lemma]["pos"]
        for i in range(len(possible_poses)):
            if possible_poses[i] in tag:
                pos_exists = True
                break
        if not (pos_exists):
            return False

    if interpretation == "canonical":
        return True
    if "plural" in interpretation and not ("Number=Plur" in tag):
        return False
    if "singular" in interpretation and not ("Number=Sing" in tag):
        return False
    if not ("nominative" in interpretation) and ("Case=Nom" in tag):
        return False
    if not ("genitive" in interpretation) and ("Case=Gen" in tag):
        return False
    if not ("dative" in interpretation) and ("Case=Dat" in tag):
        return False
    if not ("accusative" in interpretation) and ("Case=Acc" in tag):
        adj = False
        if "ADJ" in tag and "Animacy=Inan" in tag:
            adj = True
        if not adj:
            return False
    if not ("instrumental" in interpretation) and ("Case=Ins" in tag):
        return False
    if not ("prepositional" in interpretation) and not ("locative" in interpretation) and ("Case=Loc" in tag):
        return False
    if (("present" in interpretation) or ("future" in interpretation)) and ("Tense=Past" in tag):
        return False
    if (("past" in interpretation) or ("future" in interpretation)) and ("Tense=Pres" in tag):
        return False
    if (("past" in interpretation) or ("present" in interpretation)) and ("Tense=Fut" in tag):
        return False

    return True

Аргументы:

  • interpretation — строка с морфологическими показателями из словаря wordforms. Пример: «genitive plural»

  • lemma — лемма токена по версии natasha-spacy

  • tag — морфологический тег от spacy. Пример: «NOUN__Animacy=Inan|Case=Gen|Gender=Masc|Number=Plur»

  • lemmas — словарь лемм

Сначала проверим, что лемма lemma вообще может быть частью речи, указанной в tag. Это позволяет отфильтровать случаи вроде «потом» как наречие, чтобы не интерпретировать его как форму слова «пот».

Далее, проверяем различные несовместимые условия (только если interpretation не ‘canonical’):

  • В interpretation написано и в tag явно указано разное грамматическое число

  • В tag указан падеж, а в interpretation соответствующего падежа нет

  • Явное противоречие во времени глагола

Обрабатываем все токены

def accentuate(text, wordforms, lemmas):
    res = ""
    words = tokenize(text, wordforms)
    for i in range(len(words)):
        accentuated = accentuate_word(words[i], lemmas)
        if "starts_with_a_capital_letter" in words[i] and words[i]["starts_with_a_capital_letter"]:
            accentuated = accentuated.capitalize()
        if "uppercase" in words[i] and words[i]["uppercase"]:
            accentuated = accentuated.upper()
        res += accentuated
        res += words[i]["whitespace"]
    return res
  
  
def accentuate_word(word, lemmas):
    if ("tag" in word) and ("PROPN" in word["tag"]):
        return word["token"]

    if word["is_punctuation"] or (not "interpretations" in word):
        return word["token"]
    else:
        res = derive_single_accentuation(word["interpretations"])
        if not (res is None):
            return res
        else:
            compatible_interpretations = []
            for i in range(len(word["interpretations"])):
                if compatible(word["interpretations"][i]["form"], word["interpretations"][i]["lemma"], word["tag"], lemmas):
                    compatible_interpretations.append(word["interpretations"][i])
            res = derive_single_accentuation(compatible_interpretations)

            if not (res is None):
                return res
            else:
                new_compatible_interpretations = []
                for i in range(len(compatible_interpretations)):
                    if compatible_interpretations[i]["lemma"] == word["lemma"]:
                        new_compatible_interpretations.append(compatible_interpretations[i])
                res = derive_single_accentuation(new_compatible_interpretations)
                if not (res is None):
                    return res
                else:
                    return word["token"]

                  
def derive_single_accentuation(interpretations):
    if len(interpretations) == 0:
        return None
    res = interpretations[0]["accentuated"]
    for i in range(1, len(interpretations)):
        if interpretations[i]["accentuated"] != res:
            return None
    return res

В accentuate_word сначала проверяем, не является ли слово именем собственным. Если является, ничего с ним не делаем. Если этого не делать, могут возникнуть случаи вроде интерпретации «Же́не» как «жене́».

derive_single_interpretation проверяет, существует ли единственный способ постановки ударения. Если да, она возвращает этот способ, иначе возвращается None.

Постановка ударения происходит в 3 этапа

  • Если у нас сразу получилось так, что можно однозначно поставить ударение, то мы ничего дальше не делаем. Большинство слов в реальных текстах будут попадать в эту категорию.

  • Если есть различные варианты ударения, отфильтруем interpretations, оставив только те, которые проходят процедуру compatible. После данного этапа снова проверяем, остался ли у нас лишь один вариант ударения.

  • Если даже это не помогло, оставим только те interpretations, у которых лемма совпадает с той, которую дает natasha-spacy (в определении леммы spacy нередко ошибается).

  • Возвращаем просто сырой токен без ударения, если даже после этого у нас не образовалось единственного варианта.

Результаты

Код и данные: https://github.com/einhornus/russian_accentuation

Замечание: алгоритм не делает ёфикацию, поэтому текст следует предварительно пропустить через ёфикатор.

Литературный текст

Жил на опу́шке дрему́чего ле́са бе́дный дровосе́к со свое́й жено́й и двумя́ детьми́; ма́льчика зва́ли Гензель, а де́вочку — Гретель. Жил дровосе́к впроголодь; вот наступи́ла одна́жды в той земле́ така́я дорогови́зна, что не на что бы́ло ему́ купи́ть да́же хлеба на пропита́ние. И вот, под ве́чер, лёжа в посте́ли, стал он разду́мывать, и всё одолева́ли его́ ра́зные мы́сли и забо́ты; повздыхал он и говори́т жене́:

— Что же тепе́рь бу́дет с на́ми? Как нам прокорми́ть бе́дных дете́й, нам-то ведь и сами́м есть не́чего!

— А зна́ешь что, — отвеча́ла жена́, — дава́й-ка пораньше у́тром, то́лько начнёт света́ть, заведём дете́й в лес, в са́мую глуху́ю ча́щу; разведём им костёр, дади́м ка́ждому по куску́ хлеба, а са́ми уйдём на рабо́ту и оста́вим их одни́х. Доро́ги домо́й они́ не найду́т, вот мы от них и изба́вимся.

Ошибок нет. Однако, слова «впроголодь», «повздыхал» и «пораньше» не были найдены в словаре, и для них ударения не проставлены. Кроме того, не поставлено ударение в слове «хлеба»: в словаре не записано, что «хлеба́» — множественное число, а «хле́ба» — родительный падеж (парсер немного запутался из-за того, что нормальная форма множественного числа — «хлебы»). Проблемы подобного рода со словарем есть, но они довольно редки.

Некоторые сложные случаи

Я стою у окна́. В до́ме больши́е о́кна.

Ну, «стоить у окна» в теории тоже возможно. Слово «большие» иногда получает ударение на и (работа spacy стохастическая), иногда остается без него.

Я куплю́ немно́жко земли́. Не смей претендова́ть на мои́ зе́мли.

Без ошибок

Нам нужны́ учителя́. Я процити́ровал своего́ учи́теля.

Без ошибок

Мы зале́зли на строи́тельные леса́.

Без ошибок

Самолёт жда́ли два дире́ктора. Дире́ктора бы́ли пожило́го во́зраста.

Увы, ошибка natasha-spacy со словом «директора»

Ключ снача́ла находи́лся в двери, а пото́м лежа́л на полу́.

Не разрешена неоднозначность со словом «двери»

Солда́ты вы́строились в ка́ре.

К сожалению, слово «каре» не нашлось в словаре.

По-мо́ему, Маше стоит купи́ть маши́ну.

Не разрешена неоднозначность со словом «стоит»

По ле́су броди́л медве́дь. Мы наткну́лись на него́, когда́ гуля́ли в лесу́.

Без ошибок.

  • {{ error }}

Ударение — это отделение одного слога в слове с помощью голоса.

Слог — это звук, произносимый одним выдыхательным толчком воздуха.

Например: ко-жа, ру-ка.

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

Например, слово «сыр» — один слог. А в слове «рыбак» — два слога.

Не удивительно, что ударение используется при фонетическом разборе слова. Ведь, если неправильно поставить ударение, слово лишится смысла.

Также, ударение очень важно для правильного написании омографов.

Омографы (в переводе с греческого «одинаково пишу») — это такие слова, которые на письме выглядят идентично, а произносятся по-разному. Омографы, также, имеют различные смыслы.

Например, бЕрегу — берегУ, бЕлки — белкИ.

При написании ударение выделяется знаком ` над ударной гласной.

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

Данная программа предоставляет все существующие версии постановки ударений в соответствии со смыслом слова.

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

*расшифровку можно посмотреть в Словаре сокращений.

Внимание! Буквы е и ё — две самостоятельные буквы в русском алфавите. Поэтому, «тёлок» и «телок» — это разные слова.

Данный софт нацелен на литературную расстановку ударений.

К примеру, слово «кружка».

крУжка — (сущ.) полная крУжка.

кружкИ — (сущ.) кружкИ на воде.

кружкИ — (сущ.) она ходила на разные кружкИ.

Занимательные факты про ударения.

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

Какого-то определённого правила расстановки ударения в русском языке не создано. Поэтому, со временем, произношение некоторых слов меняется (звОнит — звонИт).

Однако, существуют негласные правила.

Например, в глаголах на -ить, есть тенденция ставить ударение на окончание (басИть — басИшь).

А когда в слове присутствует буква Ё, то, как правило, она будет под ударением (свЁкла, тЁзка, берЁзка).

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

Например, в словах, заимствованных из французского языка, ударение должно падать исключительно на последний слог (автобУс, ажиотАж, диспансЕр).

Быстрая цифровизация с внедрением возможности автоматического исправления ошибок (Т9, умные клавиатуры), к сожалению, приводит к обесцениванию грамотности нового поколения.

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

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

Напишите в комментариях понравилась ли вам эта программа!

Как поставить ударение. Автоматические программы и клавиши в программах Word и PowerPoint

Проголосовали: 0

  • Рейтинг:

  • Теги:

    • ударение
    • программа
    • буква «ё»

Расстановка ударений — занятие, которому преподаватель РКИ посвящает много времени. Этот процесс можно сделать более лёгким, если использовать автоматические сервисы, которые есть в интернете, и возможности программ Word и PowerPoint.

Автоматическая расстановка ударений

Если текст большой, то удобнее использовать автоматическую программу, которая сама поставит ударение в нужных местах. Например, Морфер. В тех словах, когда выбор ударения не очевиден для программы, например, в слове «дома», вам предлагаются разные варианты, и вы сами выбираете подходящий. С помощью этого сервиса можно поставить ударения в тексте из 2000 знаков. Если вы часто работаете с текстами большего размера, то оформите платную подписку.

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

StressFinder тоже обрабатывает тексты большого объёма, но ударения ставятся не во всех словах, поэтому эту программу можно использовать с осторожностью. На этом ресурсе вы можете сразу отправить текст на печать или сделать файл pdf.

Проверка ударения

Кстати, на тот случай, если вы не уверены, на правильном ли месте стоит ударение в слове (а программы тоже надо проверять!), есть сайты, которые позволяют проверить ударение.

Один из самых известных ресурсов для проверки — словари на портале грамота.ру, среди которых есть и словарь «Русское словесное ударение». Пожалуй, на этом ресурсе можно получить самую полную информацию об ударении в слове, а заодно почерпнуть знания из других словарей.

Простая проверка ударения есть на accentonline.ru. Кроме того, на сайте имеются справочные материалы, например, слова с двойным ударением или стихи для запоминания ударений. Ещё есть список слов, в которых ударение падает не на «ё». Мне этот список кажется полезным, потому что выяснилось, что таких слов больше, чем я привыкла думать. К тому же на начальном уровне мы учим студентов, что ударение в русских словах падает на «ё», но всегда нужно помнить, что на продвинутых уровнях студенты встретятся со словами, в которых это правило не соблюдается.

Использование клавиш для расстановки ударений

Однако вернёмся к теме расстановки ударений. Если нужно поставить ударения не в тексте, а в отдельных словах, то можно использовать возможности программы Word («Ворд») или PowerPoint для презентаций. В этих программах ударение ставится с помощью числового кода и комбинации клавиш.

Первый вариант:

  1. Надо установить курсор после буквы, над которой вы хотите поставить ударение.
  2. Наберите после буквы числовой код «301» (без пробелов, без кавычек).
  3. Затем нажимаете клавишу ALT и клавишу X, после чего появится ударение.

Если этот вариант не срабатывает, то можно попробовать другой. Он подходит тем, у кого справа на клавиатуре есть цифровой блок:

  1. Установите курсор после буквы, над которой вы хотите поставить ударение.
  2. Нажимаете и удерживаете клавишу ALT и набираете числовой код «769» на цифровом блоке.
  3. Как только вы отпустите клавишу ALT, появится ударение.

Если вы нажимаете ALT + 769, но в программе Word ударение не появляется, а в PowerPoint слова начинают переворачиваться, то сначала нажмите клавишу Num Lock в цифровом блоке.

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

Понравилась статья? Поделить с друзьями: