1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > python英语词汇读音_40行Python代码区分英语单词和汉语拼音

python英语词汇读音_40行Python代码区分英语单词和汉语拼音

时间:2022-03-14 12:14:48

相关推荐

python英语词汇读音_40行Python代码区分英语单词和汉语拼音

前天在一个群里有人问:利用一些英语语料,如何训练一个模型来识别出测试语句中的汉语拼音。我的第一反应想到了语言模型中的拼写纠错模型,但是纠错模型应该更复杂一些,需要实现的功能也多,比如英语单词拼错之后,纠错模型还要给出最适合的候选单词,这个涉及到编辑距离的问题。

所以我们现在只要从英语单词中区分出来哪些是汉语拼音,并不需要给出候选单词。可能有人说从英语中区分出拼音很简单啊,比如我收集所有英语单词存储下来做一个字典,然后将每一个测试词在字典中查找,找不到就是汉语拼音啊。这样确实是一个简单的办法,但是你怎么能确保你能收集到所有英语单词呢,而且很多英语单词都有派生词,各种时态的变形……另外最关键的是,我们的训练语料库数据有限,更不可能包含所有英语单词了。

今天正好有空,而且我目前也在总结自然语言处理的相关知识,于是,我就来用前几天讲的语言模型知识来解决这个问题,正所谓活学活用。本文所用的方法是二元语言模型,相关知识回顾看这里。

在文章中有一个例子,就是判断一句话的合理性,我们将一句话表示为

,而且我们有计算公式如下:

即,使用条件概率的累乘来算一个句子的合理性。而我们现在的任务是检测一个单词是否是拼音,如果我们将一个单词看做上面描述的句子,把单词中的每个字母看做句子中的单词,如果一个词不是英语单词,那么是不是意味着这个词就是不合理的呢?而如果测试语句里只有英语单词和汉语拼音,那么一个词不是英语单词,不就是汉语拼音了么?所以我们使用和那篇文章中的例子相同的方法来计算一个词是不是合理的英语单词。参照上式,计算一个单词的合理问题公式如下:

由于计算条件概率需要知道单词中的字母频数

因此,我们首先实现一个计算单字母和双字母(因为只做到二元语音模型)频数的函数。

def frequency(symbol,corpus):

l = len(symbol)

freq = 0

for word in corpus.keys():

freq_i = 0

for i in range(len(word)):

if l == 1:

if word[i] == symbol:

freq_i += 1

if l == 2:

if word[i:i+2] == symbol:

# print(word)

freq_i += 1

freq_i = freq_i * corpus[word]

freq += freq_i

return freq

symbol是我们要计数的单字母或者双字母,corpus是我们利用语料库所生产的一个单词字典dict。

然后实现一个计算条件概率公式。

def condition_prob(w1,w2,corpus):

freq_w1 = frequency(w1,corpus)

freq_w2 = frequency(w2,corpus)

return (float(freq_w2)+1)/(float(freq_w1)+len(corpus.keys()))

w1表示单字母,w2表示双字母;计算条件概率时加入平滑技术,但是我们在介绍语言模型时已经说过这种平滑会使得语言模型效果不好的,但是因为我这个只是一个小demo,只追求实现简单,其他不做太多要求,所以就这样了。

接下来就是关键部分了,也就是公式

的实现。

def testing(word,corpus):

cond_probs = []

cond_p = condition_prob('>','>'+word[0],corpus)

cond_probs.append(cond_p)

for i in range(len(word)-1):

cond_p = condition_prob(word[i],word[i:i+2],corpus)

cond_probs.append(cond_p)

cond_p = condition_prob(word[-1],word[-1]+'<',corpus)

cond_probs.append(cond_p)

reliability = reduce(mul, cond_probs) * math.pow(10,len(word))

return reliability

word是需要区分的词,区分它是英语单词还是汉语拼音。由于每个单词都有开始位置和结束位置,开始位置我用'>'符号标记,结束位置我用'<'标记。

到这里整个模型就写完了,只有3个函数,当然,处理语料库(语料库是我从维基百科和China Daily Website 随便复制过来的,里面有一些人名地名的汉语拼音,因此语料库不太好,这样也会直接影响模型的性能)还有一个函数,就是用来获得corpus字典的函数。如下所示

def load_corpus(file_path):

corpus = {}

with open(file_path,'r') as f:

for line in f.readlines():

line_words = line.strip().split()

if len(line_words) > 1:

for word in line_words:

word = re.findall('[a-z]+', word.lower())

if len(word) > 0:

word = '>'+word[0]+'<'

if word in corpus.keys():

corpus[word] += 1

else:

corpus[word] = 1

pickle.dump(corpus,open('corpus.pkl','wb'))

return corpus

最后,我们试试效果

if __name__ == "__main__":

if os.path.exists('corpus.pkl'):

corpus = pickle.load(open('corpus.pkl','rb'))

else:

corpus = load_corpus('corpus.txt')

test = 'Changan President Zhu Huarong said the investment\will baohan a xuduo of thing'

test = test.split()

for test_word in test:

test_word = test_word.lower()

reliability = testing(test_word,corpus)

# print(reliability)

if reliability >= 1e-3:

print("'%s' is a english word" % test_word)

else:

print("'%s' is a pinyin" % test_word)

对“Changan President Zhu Huarong said the investment will baohan a xuduo of thing.”一句话进行测试之后的输出结果如下所示:

'changan' is a english word

'president' is a english word

'zhu' is a pinyin

'huarong' is a pinyin

'said' is a english word

'the' is a english word

'investment' is a pinyin

'will' is a english word

'baohan' is a pinyin

'a' is a english word

'xuduo' is a pinyin

'of' is a english word

'thing' is a english word

其中'changan','investment',2个词区分错了。出现错误的原因可能有以下几方面:语料库太小,语料源不干净。

条件概率的平滑处理不太好。

计算一个词是英语单词的可信度reliability阈值设置问题,需要进行调试,本文设置的是

二元模型本身的性能问题,可以试试三元模型。

有任何疑问或者建议,欢迎在评论区交流。

原创文章,码字不易,未经许可,。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。