估计两个词之间的音素相似性

duh*_*ime 10 python algorithm nlp linguistics phoneme

我正在使用卡内基梅隆大学的发音词典检测Python中的押韵,并且想知道:我如何估计两个单词之间的音素相似度?换句话说,是否有一种算法可以识别"手"和"计划"比"手"和"薯条"更接近押韵的事实?

一些上下文:首先,我愿意说两个单词押韵,如果它们的主要重读音节和所有后续音节相同(如果你想在Python中复制,则为c06d):

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
Run Code Online (Sandbox Code Playgroud)

如果我然后跑

print cmu_final_sound_dict["hands"]
print cmu_final_sound_dict["plans"]
Run Code Online (Sandbox Code Playgroud)

我可以看到手和计划听起来非常相似.我可以自己估计这种相似性,但我想我应该问:是否有复杂的算法可以将数学值与这种声音(或听觉)相似度联系起来?也就是说,可以使用哪些算法或包来对两个单词之间的音素相似度进行数学计算?我意识到这是一个很大的问题,但我非常感谢其他人可以就这个问题提出的建议.

mrk*_*afk 3

欺骗。

#!/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)
Run Code Online (Sandbox Code Playgroud)

输出:

['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
Run Code Online (Sandbox Code Playgroud)

库: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
Run Code Online (Sandbox Code Playgroud)

(75 为空行减一)

如果您在步骤 2 中进行了更高级的操作,您可能会获得更好的结果:为特定音素组合分配权重。然后,您可以修改一些 Levenshtein 类型的距离度量(例如在上面的库中),以在文本输入上合理地执行“音位距离”度量。

第三步:利润,不需要太多工作。