2014-10-20 9 views
8

Я работаю над обнаружением рифм в Python, используя словарь словаря Carnegie Mellon University, и хотел бы знать: как я могу оценить фонематическое сходство между двумя словами? Другими словами, существует ли алгоритм, который может идентифицировать тот факт, что «руки» и «планы» ближе к рифму, чем «руки» и «фри»?Оценить фонематическое сходство между двумя словами

Некоторые контекст: Во-первых, я был готов сказать, что два слова рифмуются, если их основной ударный слог и все последующие слоги идентичны (c06d, если вы хотите скопировать в Python):

def create_cmu_sound_dict(): 

    final_sound_dict = {} 

    with open('resources/c06d/c06d') as cmu_dict: 
     cmu_dict = cmu_dict.read().split("\n") 
     for i in cmu_dict: 
      i_s = i.split() 
      if len(i_s) > 1: 
       word = i_s[0] 
       syllables = i_s[1:] 

       final_sound = "" 
       final_sound_switch = 0 

       for j in syllables: 
        if "1" in j: 
         final_sound_switch = 1 
         final_sound += j 
        elif final_sound_switch == 1: 
         final_sound += j 

      final_sound_dict[word.lower()] = final_sound 

    return final_sound_dict 

Если я затем запустить

print cmu_final_sound_dict["hands"] 
print cmu_final_sound_dict["plans"] 

Я вижу, что руки и планы звучат очень похожи. Я мог бы попытаться оценить это сходство самостоятельно, но я подумал, что должен спросить: существуют ли сложные алгоритмы, которые могут привязать математическое значение к этой степени звукового (или слухового) сходства? То есть, какие алгоритмы или пакеты можно использовать для математизации степени фонематического сходства между двумя словами? Я понимаю, что это большой вопрос, но я был бы очень благодарен за любой совет, который другие могут предложить по этому вопросу.

+0

Зачем голосовать и двигаться, чтобы закрыть? Что я могу сделать, чтобы улучшить вопрос? – duhaime

+2

Вы ищете что-то вроде алгоритма Soundex (http://en.wikipedia.org/wiki/Soundex)? – acfrancis

+0

Я не могу говорить за нисходящего, но причина, на которую дается за закрытое голосование, заключается в том, что ваш вопрос выглядит так: [запрашивать рекомендации] (http://meta.stackoverflow.com/questions/254393/what-exactly-is -a-рекомендация-вопрос). Вы можете перефразировать его, чтобы более четко спросить «Как я могу сделать X? *», А не «* Какой инструмент я должен использовать для выполнения X?» –

ответ

3

Cheat.

#!/usr/bin/env python 

from Levenshtein import * 

if __name__ == '__main__': 
    s1 = ['HH AE1 N D Z', 'P L AE1 N Z'] 
    s2 = ['HH AE1 N D Z', 'F R AY1 Z'] 
    s1nospaces = map(lambda x: x.replace(' ', ''), s1) 
    s2nospaces = map(lambda x: x.replace(' ', ''), s2) 
    for seq in [s1, s2, s1nospaces, s2nospaces]: 
     print seq, distance(*seq) 

Выход:

['HH AE1 N D Z', 'P L AE1 N Z'] 5 
['HH AE1 N D Z', 'F R AY1 Z'] 8 
['HHAE1NDZ', 'PLAE1NZ'] 3 
['HHAE1NDZ', 'FRAY1Z'] 5 

Библиотека: https://pypi.python.org/pypi/python-Levenshtein/0.11.2

серьезно, однако, так как у вас есть только текст в качестве входных данных и в значительной степени на основе текста CMU Dict, вы ограничены некоторые вид манипуляции с текстовым вводом; но, как я вижу, существует только ограниченное количество доступных вам фонем, поэтому вы можете взять самые важные и назначить им «фонемные веса». Там только 74 из них в словаре CMU вы указали на:

% cat cmudict.06.txt | grep -v '#' | cut -f 2- -d ' ' | tr ' ' '\n' | sort | uniq | wc -l 
75 

(75 минус один для пустой строки)

Вы, вероятно, получить лучшие результаты, если вы сделали что-л более продвинутыми в шаге 2 : присваивать веса конкретным комбинациям фонем. Затем вы можете изменить некоторую метрику расстояния Левенштейна, например. в библиотеке выше, чтобы придумать разумно выполняющую метрику «фонемного расстояния», работающую над текстовыми вводами.

Не много работы для шага 3: прибыль.

+0

Это полностью игнорирует фонематические особенности, которые делают «nd» склонны ассимилироваться к «n», тогда как, например, «nk» не (или стремится к «ngk», или действительно регулярно реализуется как «ngk»). – tripleee

0

1) получить все TTS аудио для всех слов через веб-API или местного SAPI,

2) Extract функции речи, если вы можете (1, 2) или, по крайней мере, получить силу речевых данных

3) В зависимости от функции у вас есть несколько подходов.

Если вы можете получить мощность каждой выборки (кадров) речевых данных (Dim = 1), то один простой способ, без сомнения, вычислить correlation двух наборов функций.

Если у вас есть другой тип объектов, которые, скорее всего, будет иметь больше размеры, вы можете рассматривать его как изображение и проверить 2d convolution или Dynamic time warping

4) Если у вас нет знания об обработке речи для выполнения этой задачи 1,2,3, выезд pyphonetics

#pip install pyphonetics 
>>> from pyphonetics import RefinedSoundex 
>>> rs = RefinedSoundex() 
>>> rs.distance('Rupert', 'Robert') 
0 
>>> rs.distance('assign', 'assist', metric='hamming') 
2