在本文中,我们将介绍一个流行的机器学习项目-文本生成器,您将学习如何构建文本生成器,并学习如何实现马尔可夫链以获得更快的预测模型。文本生成器简介文本生成在各行各业都很流行,尤其是在移动、应用程序和数据科学领域。甚至新闻业也使用文本生成来帮助写作过程。日常生活中会遇到一些文本生成技术,比如文本补全、搜索建议、SmartCompose、聊天机器人等都是应用的例子。本文将使用马尔可夫链构建一个文本生成器。这将是一个基于字符的模型,它采用链中的前一个字符并生成序列中的下一个字母。通过使用示例单词训练我们的程序,文本生成器将学习常见的字符顺序模式。然后,文本生成器会将这些模式应用于输入(一个不完整的单词),并输出完成该单词的概率最高的字符。文本生成是自然语言处理的一个分支,它根据先前观察到的语言模式预测并生成下一个字符。在机器学习之前,NLP通过创建一个包含所有英语单词的表并将传递的字符串与现有单词进行匹配来进行文本生成。这种方法有两个问题。搜索数千个单词会很慢。生成器只能完成它以前见过的单词。随着机器学习和深度学习的出现,NLP使我们能够大幅减少运行时间并提高通用性,因为生成器可以完成它以前从未遇到过的单词。如果需要,NLP可以扩展到预测单词、短语或句子!对于这个项目,我们将专门使用马尔可夫链来完成。马尔可夫过程是许多自然语言处理项目的基础,涉及书面语言和复杂分布的建模样本。马尔可夫过程非常强大,仅需一个示例文档即可使用它们生成表面上看起来真实的文本。什么是马尔可夫链?马尔可夫链是一个随机过程,它模拟一系列事件,其中每个事件的概率取决于前一个事件的状态。该模型具有一组有限的状态,并且从一种状态移动到另一种状态的条件概率是固定的。每个转换的概率仅取决于模型的先前状态,而不取决于事件的整个历史。例如,假设您要构建马尔可夫链模型来预测天气。在这个模型中,我们有两个状态,晴天或雨天。如果我们今天一直处于晴天状态,那么明天晴天的概率更高(70%)。下雨也是如此。如果下雨了,很可能会继续下雨。但天气有可能(30%)会改变状态,因此我们也将其包含在我们的马尔可夫链模型中。马尔可夫链是我们文本生成器的完美模型,因为我们的模型只会使用前一个字符来预测下一个字符。使用马尔可夫链的优点是准确,使用更少的内存(仅存储1个先前状态)并且执行速度快。文本生成的实现将在这里通过6个步骤完成文本生成器:生成查找表:创建表来记录词频将频率转换为概率:将我们的发现转换为可用的形式加载数据集:加载并构建训练集马尔可夫链:使用概率为每个单词和字符创建链示例数据:创建一个函数来对语料库的部分进行采样生成文本:测试我们的模型1.生成一个查找表首先,我们将创建一个表,记录每个字符状态的出现情况训练语料库。从训练语料库中保存最后“K”个字符和“K+1”个字符,并将它们保存在查找表中。例如,假设我们的训练语料库包含“themanwas,they,then,the”。那么单词出现的次数为:"the"—3"then"—1"they"—1"man"—1下面是查找表中的结果:在上面的例子中,我们取K=3,表示一次考虑3个字符,取下一个字符(K+1)作为输出字符。在上面的查找表中将单词(X)作为一个字符,会将字符(Y)输出为单个空格(""),因为第一个the之后没有单词。此外,统计该序列在数据集中出现的次数,在本例中为3次。这会为语料库中的每个单词生成数据,即所有可能的X和Y对。下面是我们如何在代码中生成查找表:defgenerateTable(data,k=4):T={}foriinrange(len(data)-k):X=data[i:i+k]Y=data[i+k]#print("X%sandY%s"%(X,Y))如果T.get(X)为无:T[X]={}T[X][Y]=1else:如果T[X].get(Y)为None:T[X][Y]=1else:T[X][Y]+=1returnTT=generateTable("hellohellohelli")print(T)#{'llo':{'h':2},'ello':{'':2},'ohe':{'l':2},'loh':{'e':2},'hell':{'i':1,'o':2},'hel':{'l':2}}代码简单解释:在第3行,创建了一个字典,它将存储X及其相应的Y和频率值。第9到17行,检查X和Y的出现次数,如果查找字典中已经有一对X和Y,则只需将其加1。2.将频率转换为概率一旦我们有了这张表和出现次数很多时候,您可以获得在给定x发生后Y发生的概率。公式是:比如如果X=the,Y=n,我们的公式是这样的:当X=Y=n的频率:2,表中的总频率:8,所以:P=2/8=0.125=12.5%以下是我们如何应用此公式将查找表转换为马尔可夫链可用概率:defconvertFreqIntoProb(T):forkxinT.keys():s=float(sum(T[kx].values()))forkinT[kx].keys():T[kx][k]=T[kx][k]/sreturnTT=convertFreqIntoProb(T)print(T)#{'llo':{'h':1.0},'ello':{'':1.0},'ohe':{'l':1.0},'loh':{'e':1.0},'hell':{'i':0.3333333333333333,'o':0.6666666666666666},'hel':{'l':1.0}}简单解释:将特定键的频率值相加,然后除以该键的每个频率值通过这个sum提高的值给出了概率。3.加载数据集接下来,将加载真正的训练语料库。可以使用任何需要的长文本(.txt)文档。为简单起见,将使用政治演讲来提供足够的词汇来教授我们的模型。text_path="train_corpus.txt"defload_text(filename):withopen(filename,encoding='utf8')asf:returnf.read().lower()text=load_text(text_path)print('加载数据集。')这个数据集为我们的示例项目提供了足够的事件来做出相当准确的预测。与所有机器学习一样,更大的训练语料库将产生更准确的预测。4.建立一个马尔可夫链让我们建立一个马尔可夫链,并为每个字符关联一个概率。在这里,我们将使用在步骤1和2中创建的generateTable()和convertFreqIntoProb()函数来构建马尔可夫模型。defMarkovChain(text,k=4):T=generateTable(text,k)T=convertFreqIntoProb(T)returnTmodel=MarkovChain(text)第1行创建了一个生成马尔可夫模型的方法。此方法接受一个文本语料库和一个K值,该值告诉马尔可夫模型考虑K个字符并预测下一个字符。第2行,通过将文本语料库和K提供给我们在上一节中创建的方法generateTable()来生成查找表。第3行,使用我们在上一课中创建的convertFreqIntoProb()方法将频率转换为概率值。5.TextSampling创建一个采样函数,使用未完成的词(ctx)、来自第4步的马尔可夫链模型(model),以及用于构成词库的字符数(k)。我们将使用此函数对传递的上下文进行采样,并返回下一个可能的字符以及它是正确字符的概率。importnumpyasnpdefsample_next(ctx,model,k):ctx=ctx[-k:]ifmodel.get(ctx)isNone:return""possible_Chars=list(model[ctx].keys())possible_values=list(model[ctx].values())print(possible_Chars)print(possible_values)returnnp.random.choice(possible_Chars,p=possible_values)sample_next("commo",model,4)#['n']#[1.0]代码解释:函数sample_next接受三个参数:ctx、model和k的值。ctx是用于生成一些新文本的文本。但是这里模型只会使用ctx中的最后K个字符来预测序列中的下一个字符。例如,我们传递common,K=4,模型用来生成下一个字符的文本是ommo,因为马尔可夫模型只使用之前的历史记录。在第9行和第10行,打印了可能的字符及其概率值,因为这些字符也存在于我们的模型中。我们得到下一个预测字符n的概率为1.0。因为commo这个词在第12行生成下一个字符后更可能更常见,所以我们根据上面讨论的概率值返回一个字符。6.生成文本最后结合以上所有函数生成一些文本。defgenerateText(starting_sent,k=4,maxLen=1000):sentence=starting_sentctx=starting_sent[-k:]forixinrange(maxLen):next_prediction=sample_next(ctx,model,k)sentence+=下一个预测ctx=sentence[-k:]returnsentenceprint("FunctionCreatedSuccessfully!")text=generateText("dear",k=4,maxLen=2000)print(text)结果如下:亲爱的国家带来了新的意识。我衷心地为他们的生命服务,我们的国家,今天许多人在他们的生命独立时插上了三色旗。我致力于压迫独立。今天,obc共同许多国家,数以百万计的印第安人被屠杀。我亲爱的国家不是在70年代经历了严苛的耕作,在这个国家的信息中被压迫,妇女,南方多年来过度拥挤,就像立宪国家的ashok脉轮被交叉,被剥夺,压迫自由,我鞠躬为我们的国家感到骄傲。我亲爱的国家,数百万人将成为一百年的南方人,这是他们的英雄。上述函数接受三个参数:生成文本的起始词、K的值和所需的文本以最大字符长度运行代码将产生以“dear”开头的2000个字符的文本。虽然演讲可能没有多大意义,但单词是完整的,并且经常模仿熟悉的单词模式。接下来要学什么这是一个简单的文本生成项目。通过此项目了解自然语言处理和马尔可夫链的实际工作原理,您可以在继续深度学习之旅时使用它们。本文只是介绍马尔可夫链的实验项目,因为在实际应用中不会起到任何作用。如果想获得更好的文本生成效果,请学习GPT-3等工具。
