Arpabet语音到一个单词的子串,用Python

时间:2017-11-28 10:02:13

标签: python nltk

这样做的目的是,我希望能够将一个单词转换为不仅仅是它的音素,还包括与它们对应的子串。例如,像:

public static void main(...)

我希望我可以研究一些NLTK或广泛可用的资源,但任何解决这个问题的方法都会受到欢迎。

此外,我宁愿任何解决方案都不必在cmudict中查找'perfect'的子串。有时,子串将具有与完整单词不同的发音。

加成: 我意识到当多个音素应该对应一个子串(如果我错了,请纠正我,而不是语言学家)时,这可能很难:

from nltk.corpus import cmudict
d = cmudict.dict()
...
print foo('perfect', d['perfect']) 
>>> (['p','er','f','e','c','t'], [u'P', u'ER0', u'F', u'EH1', u'K', u'T'])

对于上述情况,L和E是否应同时对应AH0和L?

1 个答案:

答案 0 :(得分:0)

事实证明,对于字符串和arpabet列表,使用音节语法排序。

def str_syllables(s):
    k = ['V' if x in list('aeiouy') else 'C' for x in s]
    k = ''.join(k)
    syl_list = []
    while k:
        end = 0
        if(k.startswith('CVCC') or k.startswith('CCCV')):
            end = 4
        elif(k.startswith('CCV') or k.startswith('CVC') or k.startswith('VCC')):
            end = 3
        elif(k.startswith('VC') or k.startswith('CV')):
            end = 2
        elif(k.startswith('V')):
            end = 1
        else:
            print "Syllables couldn't be computed: ", k, s
            return None
        syl_list.append(s[0:end])
        s = s[end:]
        k = k[end:]
    return syl_list

def phoneme_syllables(l):
    arp_vowels = ['AA','AE','AH','AO','AW','AY','EH','ER','EY','IH',
                    'IY','OW','OY','UH','UW']
    pk = ['V' if any(v in x for v in arp_vowels) else 'C' for x in l]
    pk = ''.join(pk)
    syl_list = []
    while pk:
        end = 0
        if(pk.startswith('CVCC') or pk.startswith('CCCV')):
            end = 4
        elif(pk.startswith('CCV') or pk.startswith('CVC') or pk.startswith('VCC')):
            end = 3
        elif(pk.startswith('VC') or pk.startswith('CV')):
            end = 2
        elif(pk.startswith('V')):
            end = 1
        else:
            print "Syllables couldn't be computed: ", pk, syl_list, l
            return None
        syl_list.append(l[0:end])
        l = l[end:]
        pk = pk[end:]
    return syl_list

def str_phonem_match(s, p_list):
    """
    Input: string
    Output:
        [('per', [P, ER0]), ('fect', [F, EH1, K, T])]
    """
    syl_list = str_syllables(s)
    syl_p_list = phoneme_syllables(p_list[0])
    if len(syl_p_list) == len(syl_list):
        return zip(syl_list, syl_p_list)
    print k, s, syl_p_list, syl_list
    return [(None, None)]

print str_phonem_match('perfect', arpabet['perfect'])

它给出了

[('perf', [u'P', u'ER0', u'F']), ('ect', [u'EH1', u'K', u'T'])]

我意识到我的具体情况,我不需要实际分开每个arpabet音素 - 只需音节即可。 如果有人对更有效/更好的解决方案有一些建议,请告诉我!

编辑:等等没有...因为我想要“per”而不是“perf”,有时订单会不正确(应该是递归的,这样我就可以检查CVC,CVCC是对还是V或VC是对。) 我不确定我是否真的对语言学或音节知之甚少,不确定应该遵循哪些规则。但对于我的具体用例,我认为这样可以正常使用。