首页 > 编程知识 正文

nlp各个语言模型动漫人物,用python语言实现

时间:2023-05-05 20:42:07 阅读:232818 作者:3672

NLP - ngram - N元语言模型 python 实现


一、说明
N-Gram N元语言模型:    
    N-Gram(有时也称为N元模型)是自然语言处理中一个非常重要的概念,通常在NLP中,人们基于一定的语料库,可以利用N-Gram来预计或者评估一个句子是否合理。另外一方面,N-Gram的另外一个作用是用来评估两个字符串之间的差异程度。这是模糊匹配中常用的一种手段。
    N-Gram 表示,定义一个长度为 N,步长为 1 的滑动窗口,切分原字符串得到的词段。假设 N = 2 时得到一个词段 w1w2,得到 P(w2|w1) 即 w1 出现时 w2 的概率,计算所有滑动窗口中词段的概率。
常用的有三种模型:
    unigram:一元模型,单个word
    bigram: 二元模型,双word
    trigram:三元模型,3 word   
使用场景:
    1.使用马尔科夫假设生成文本;
    2.使用语言模型验证生成的文本是否合理;

二、NGram 算法模型推导:
使用 bigram 对语料进行建模,可以得到三张表;

1.统计字的词频:单个字在语料中出现的次数
对,有,些,人,来,说
3,24,6,26,9,4

2.统计词段的词频表:
\ 对,有,些,人,来,说
对 1,2,3,4,5,6
有 1,2,3,4,5,6
些 1,2,3,4,5,6
人 1,2,3,4,5,6
来 1,2,3,4,5,6
说 1,2,3,4,5,6

上表中第一行的第二列 2 表示,前缀=对,后缀=有的词段,在语料中出现的次数;

3.词段的概率表
\ 对,有,些,人,来,说
对 0.33,0.083,0.5,0.15,0.5,1.5
有 x,x,x,x,x,x
些 x,x,x,x,x,x
人 x,x,x,x,x,x
来 x,x,x,x,x,x
说 x,x,x,x,x,x

上表中第一行的第二列 0.083 表示,“有”在“对”后面出现的概率;
公式:p(有|对) = 2/24 ≈ 0.083 ,即:“对”出现时“有”字出现的概率;
验证一句话是否合理可以表示为:
p(对有些人来说)=p(有|对)*p(些|有)*...

二、代码示例

#!/usr/瘦瘦的鼠标/env python3# coding=utf-8import urllibimport reimport randomimport stringimport operator'''实现了 NGram 算法,并对 markov 生成的句子进行打分;'''class ScoreInfo: score = 0 content = ''class NGram: __dicWordFrequency = dict() #词频 __dicPhraseFrequency = dict() #词段频 __dicPhraseProbability = dict() #词段概率 def printNGram(self): print('词频') for key in self.__dicWordFrequency.keys(): print('%st%s'%(key,self.__dicWordFrequency[key])) print('词段频') for key in self.__dicPhraseFrequency.keys(): print('%st%s'%(key,self.__dicPhraseFrequency[key])) print('词段概率') for key in self.__dicPhraseProbability.keys(): print('%st%s'%(key,self.__dicPhraseProbability[key])) def append(self,content): ''' 训练 ngram 模型 :param content: 训练内容 :return: ''' #clear content = re.sub('s|n|t','',content) ie = self.getIterator(content) #2-Gram 模型 keys = [] for w in ie: #词频 k1 = w[0] k2 = w[1] if k1 not in self.__dicWordFrequency.keys(): self.__dicWordFrequency[k1] = 0 if k2 not in self.__dicWordFrequency.keys(): self.__dicWordFrequency[k2] = 0 self.__dicWordFrequency[k1] += 1 self.__dicWordFrequency[k2] += 1 #词段频 key = '%s%s'%(w[0],w[1]) keys.append(key) if key not in self.__dicPhraseFrequency.keys(): self.__dicPhraseFrequency[key] = 0 self.__dicPhraseFrequency[key] += 1 #词段概率 for w1w2 in keys: w1 = w1w2[0] w1Freq = self.__dicWordFrequency[w1] w1w2Freq = self.__dicPhraseFrequency[w1w2] # P(w1w2|w1) = w1w2出现的总次数/w1出现的总次数 = 827/2533 ≈0.33 , 即 w2 在 w1 后面的概率 self.__dicPhraseProbability[w1w2] = round(w1w2Freq/w1Freq,2) pass def getIterator(self,txt): ''' bigram 模型迭代器 :param txt: 一段话或一个句子 :return: 返回迭代器,item 为 tuple,每项 2 个值 ''' ct = len(txt) if ct<2: return txt for i in range(ct-1): w1 = txt[i] w2 = txt[i+1] yield (w1,w2) def getScore(self,txt): ''' 使用 ugram 模型计算 str 得分 :param txt: :return: ''' ie = self.getIterator(txt) score = 1 fs = [] for w in ie: key = '%s%s'%(w[0],w[1]) freq = self.__dicPhraseProbability[key] fs.append(freq) score = freq * score #print(fs) #return str(round(score,2)) info = ScoreInfo() info.score = score info.content = txt return info def sort(self,infos): ''' 对结果排序 :param infos: :return: ''' return sorted(infos,key=lambda x:x.score,reverse=True)def fileReader(): path = "../test_ngram_data.txt" with open(path,'r',encoding='utf-8') as f: rows = 0 # 按行统计 while True: rows += 1 line = f.readline() if not line: print('读取结束 %s'%path) return print('content rows=%s len=%s type=%s'%(rows,len(line),type(line))) yield line passdef getData(): #使用相同语料随机生成的句子 arr = [] arr.append("对有些人来说,困难是成长壮大的机遇。") arr.append("对有些人来说,困难是放弃的借口,而对另外一部分人来说,困难是放弃") arr.append("世上有很多时候,限制我们自己配不上优秀的人生色彩。") arr.append("睡一睡,精神好,烦恼消,快乐长;睡一睡,精神好,做美梦,甜蜜蜜;") arr.append("睡一睡,精神好,烦恼消,快乐长;睡一睡,身体健,头脑清,眼睛明。") arr.append("思念;展转反侧,是因为它的尽头,种着“梦想”。") arr.append("思念不因休息而变懒,祝福不因疲惫而变懒,祝福不因休息而变懒,祝福") arr.append("思念无声无息,弥漫你的心里。") arr.append("希望每天醒来,都是不是他人的翅膀,心有多大。很多不可能会造就你明") arr.append("一条路,人烟稀少,孤独难行。却不得不坚持前行。因为有人在想念;展") arr.append("找不到坚持前行。却不得不坚持下去的理由,生活本来就这么简单。") arr.append("找不到坚持下去的理由,生活本来就这么简单。") return arrdef main(): ng = NGram() reader = fileReader() #将语料追加到 bigram 模型中 for row in reader: print(row) ng.append(row) #ng.printNGram() #测试生成的句子,是否合理 arr = getData() infos= [] for s in arr: #对生成的句子打分 info = ng.getScore(s) infos.append(info) #排序 infoArr = ng.sort(infos) for info in infoArr: print('%st(得分:%s)'%(info.content,info.score)) passif __name__ == '__main__': main() pass

三、运行结果
对有些人来说,困难是成长壮大的机遇。    (得分:8.308410644531251e-07)
思念无声无息,弥漫你的心里。    (得分:3.955078125e-10)
找不到坚持下去的理由,生活本来就这么简单。    (得分:2.0349836718750006e-11)
对有些人来说,困难是放弃的借口,而对另外一部分人来说,困难是放弃    (得分:1.3253699988126758e-12)
思念;展转反侧,是因为它的尽头,种着“梦想”。    (得分:4.6318359375e-13)
世上有很多时候,限制我们自己配不上优秀的人生色彩。    (得分:1.5611191204833988e-14)
找不到坚持前行。却不得不坚持下去的理由,生活本来就这么简单。    (得分:3.777438440917971e-18)
希望每天醒来,都是不是他人的翅膀,心有多大。很多不可能会造就你明    (得分:1.722941717610095e-22)
一条路,人烟稀少,孤独难行。却不得不坚持前行。因为有人在想念;展    (得分:3.3191106102e-24)
思念不因休息而变懒,祝福不因疲惫而变懒,祝福不因休息而变懒,祝福    (得分:2.4259587960937513e-24)
睡一睡,精神好,烦恼消,快乐长;睡一睡,身体健,头脑清,眼睛明。    (得分:1.6347894912958154e-24)
睡一睡,精神好,烦恼消,快乐长;睡一睡,精神好,做美梦,甜蜜蜜;    (得分:3.0210909799146667e-25)


四、test_ngram_data.txt 语料内容
对有些人来说,困难是放弃的借口,而对另外一部分人来说,困难是成长壮大的机遇。
你从不担心自己配不上优秀的人,你只会担心自己配不上喜欢的人。
一息ggdbg,希望不灭。
来属于那些坚信自己梦想之美的家伙。
心是一个人的翅膀,心有多大,世界就有多大。很多时候,限制我们的,不是周遭的环境,也不是他人的言行,而是我们自己:看不开,忘不了,放不下,把自己囚禁在灰暗的记忆里;不敢想,不自信,不行动,把自己局限在固定的空间里。
找不到坚持下去的理由,那就找一个重新开始的理由,生活本来就这么简单。
一条路,人烟稀少,孤独难行。却不得不坚持前行。因为它的尽头,种着“梦想”。
生活的有趣还在于,你昨日的最大痛楚,极可能会造就你明日的最大力量。
如果没有那些愚蠢的想法, 我们也压根不可能有什么有趣的想法。
世上有很多不可能,不过不要在你未尽全力之前下结论。
希望每天醒来,都是不一样的人生色彩。
思念无声无息,弥漫你的心里。当夜深人静的时候,是不是又感到了寂寞,感到了心烦?那就送你一个好梦吧,愿你梦里能回到你媳妇的娘家……高老庄!
暮春之夜,微风渐暖,睡意缱绻,移身临窗,近看柳枝月色下翩舞摇曳,遥听池塘绵绵蛙鸣。携一份恬淡,悍然入梦。晚安。
睡一睡,精神好,烦恼消,快乐长;睡一睡,心情好,做美梦,甜蜜蜜;睡一睡,身体健,头脑清,眼睛明。愿你酣然入梦,晚安!
思念不因劳累而改变,问候不因疲惫而变懒,祝福不因休息而变缓,关怀随星星眨眼,牵挂在深夜依然,轻轻道声:祝你晚安!
如隔三秋,是因为有人在思念;长夜漫漫,是因为有人在想念;展转反侧,是因为有人在品味孤独;孤枕难眠,是因为有人在数绵羊,爱就两个字:晚安。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。