Оцените фонематическое сходство двух слов
Я работаю над обнаружением рифм в Python с использованием словаря произношения Университета Карнеги-Меллона и хотел бы знать: как я могу оценить фонематическое сходство между двумя словами? Другими словами, существует ли алгоритм, который может идентифицировать тот факт, что "руки" и "планы" ближе к рифмованию, чем "руки" и "картофель фри"?
Немного контекста. Сначала я хотел сказать, что два слова рифмуются, если их основной ударный слог и все последующие слоги идентичны ( 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"]
Я вижу, что руки и планы звучат очень похоже. Я мог бы самостоятельно заняться оценкой этого сходства, но я подумал, что мне следует спросить: существуют ли сложные алгоритмы, которые могут связать математическое значение с такой степенью звукового (или слухового) сходства? То есть какие алгоритмы или пакеты можно использовать для математизации степени фонемного сходства между двумя словами? Я понимаю, что это большой вопрос, но я был бы очень признателен за любые советы, которые другие могут дать по этому вопросу.
2 ответа
1) получить все аудио TTS для всех слов через веб-API или локальный SAPI,
2) Извлечение речевых функций, если вы можете ( 1, 2) или, по крайней мере, получить мощность речевых данных
3) Зависит от того, какая функция у вас есть, вот несколько подходов.
Если вы можете получить мощность каждого сэмпла (кадра) речевых данных (Dim=1), несомненно, одним простым способом будет вычисление корреляции двух наборов признаков.
Если у вас есть другие типы объектов, которые, скорее всего, будут иметь больше измерений, вы можете рассматривать их как изображение и проверить 2-ую свертку или динамическое искажение времени
4) Если у вас нет знаний об обработке речи для задания 1,2,3, ознакомьтесь с пифонетикой
#pip install pyphonetics
>>> from pyphonetics import RefinedSoundex
>>> rs = RefinedSoundex()
>>> rs.distance('Rupert', 'Robert')
0
>>> rs.distance('assign', 'assist', metric='hamming')
2
Чит.
#!/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, вы ограничены какой-то манипуляцией с вводом текста; но, на мой взгляд, доступно только ограниченное количество фонем, поэтому вы можете взять самые важные и назначить им "фонематические веса". В словаре CMU только 74 из них вы указали:
% cat cmudict.06.txt | grep -v '#' | cut -f 2- -d ' ' | tr ' ' '\n' | sort | uniq | wc -l
75
(75 минус один для пустой строки)
Вы, вероятно, получите лучшие результаты, если проделаете что-то более продвинутое на шаге 2: назначьте веса конкретным комбинациям фонем. Затем вы можете изменить некоторую метрику расстояния типа Левенштейна, например, в приведенной выше библиотеке, чтобы получить разумно выполняющуюся метрику "фонематического расстояния", работающую с текстовыми вводами.
Не так много работы для шага 3: прибыль.