关于机器学习:使用马尔可夫链构建文本生成器

41次阅读

共计 5005 个字符,预计需要花费 13 分钟才能阅读完成。

本文中将介绍一个风行的机器学习我的项目——文本生成器,你将理解如何构建文本生成器,并理解如何实现马尔可夫链以实现更快的预测模型。

文本生成器简介

文本生成在各个行业都很受欢迎,特地是在挪动、利用和数据迷信畛域。甚至新闻界也应用文本生成来辅助写作过程。

在日常生活中都会接触到一些文本生成技术,文本补全、搜寻倡议,Smart Compose,聊天机器人都是利用的例子,

本文将应用马尔可夫链构建一个文本生成器。这将是一个基于字符的模型,它承受链的前一个字符并生成序列中的下一个字母。

通过应用样例单词训练咱们的程序,文本生成器将学习常见的字符程序模式。而后,文本生成器将把这些模式利用到输出,即一个不残缺的单词,并输入实现该单词的概率最高的字符。

文本生成是自然语言解决的一个分支,它依据之前察看到的语言模式预测并生成下一个字符。

在没有机器学习之前,NLP 是通过创立一个蕴含英语中所有单词的表,并将传递的字符串与现有的单词匹配来进行文字生成的。这种办法有两个问题。

  • 搜寻成千上万个单词会十分慢。
  • 生成器只能补全它以前见过的单词。

机器学习和深度学习的呈现,使得 NLP 容许咱们大幅缩小运行时并减少通用性,因为生成器能够实现它以前从未遇到过的单词。如果须要 NLP 能够扩大到预测单词、短语或句子!

对于这个我的项目,咱们将专门应用马尔可夫链来实现。马尔可夫过程是许多波及书面语言和模仿简单散布样本的自然语言解决我的项目的根底。

马尔可夫过程是十分弱小的,以至于它们只须要一个示例文档就能够用来生成外表上看起来实在的文本。

什么是马尔可夫链?

马尔可夫链是一种随机过程,它为一系列事件建模,其中每个事件的概率取决于前一个事件的状态。该模型有一组无限的状态,从一个状态挪动到另一个状态的条件概率是固定的。

每次转移的概率只取决于模型的前一个状态,而不是事件的整个历史。

例如,假如想要构建一个马尔可夫链模型来预测天气。

在这个模型中咱们有两种状态,晴天或雨天。如果咱们明天始终处于晴朗的状态,今天就有更高的概率 (70%) 是晴天。雨也是如此; 如果曾经下过雨,很可能还会持续下雨。

然而天气会扭转状态是有可能的(30%),所以咱们也将其蕴含在咱们的马尔可夫链模型中。

马尔可夫链是咱们这个文本生成器的完满模型,因为咱们的模型将仅应用前一个字符预测下一个字符。应用马尔可夫链的长处是,它是精确的,内存少 (只存储 1 个以前的状态) 并且执行速度快。

文本生成的实现

这里将通过 6 个步骤实现文本生成器:

  1. 生成查找表: 创立表来记录词频
  2. 将频率转换为概率: 将咱们的发现转换为可用的模式
  3. 加载数据集: 加载并利用一个训练集
  4. 构建马尔可夫链: 应用概率为每个单词和字符创立链
  5. 对数据进行采样: 创立一个函数对语料库的各个局部进行采样
  6. 生成文本: 测试咱们的模型

1、生成查找表

首先,咱们将创立一个表,记录训练语料库中每个字符状态的呈现状况。从训练语料库中保留最初的 ’ K ‘ 字符和 ’ K+1 ‘ 字符,并将它们保留在一个查找表中。

例如,设想咱们的训练语料库蕴含,“the man was, they, then, the, the”。那么单词的呈现次数为:

  • “the”— 3
  • “then”— 1
  • “they”— 1
  • “man”— 1

上面是查找表中的后果:

在下面的例子中,咱们取 K = 3,示意将一次思考 3 个字符,并将下一个字符 (K+1) 作为输入字符。在下面的查找表中将单词 (X) 作为字符,将输入字符 (Y) 作为单个空格(” “),因为第一个 the 前面没有单词了。此外还计算了这个序列在数据集中呈现的次数,在本例中为 3 次。

这样就生成了语料库中的每个单词的数据,也就是生成所有可能的 X 和 Y 对。

上面是咱们如何在代码中生成查找表:

 def generateTable(data,k=4):
 
 T = {}
     for i in range(len(data)-k):
         X = data[i:i+k]
         Y = data[i+k]
         #print("X  %s and Y %s"%(X,Y))
         if T.get(X) is None:
             T[X] = {}
             T[X][Y] = 1
         else:
             if T[X].get(Y) is None:
                 T[X][Y] = 1
             else:
                 T[X][Y] += 1
     return T
 T = generateTable("hello hello helli")
 print(T)
 
 #{'llo': {'h': 2}, 'ello': {'': 2},'o he': {'l': 2},'lo h': {'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 =the 时 Y = n 的频率:2,表中总频率:8,因而:P = 2/8= 0.125= 12.5%

以下是咱们如何利用这个公式将查找表转换为马尔科夫链可用的概率:

 def convertFreqIntoProb(T):     
     for kx in T.keys():
         s = float(sum(T[kx].values()))
         for k in T[kx].keys():
             T[kx][k] = T[kx][k]/s
 
     return T
 
 T = convertFreqIntoProb(T)
 print(T)
 #{'llo': {'h': 1.0}, 'ello': {'': 1.0},'o he': {'l': 1.0},'lo h': {'e': 1.0},'hell': {'i': 0.3333333333333333,'o': 0.6666666666666666},' hel': {'l': 1.0}}

简略解释:

把一个特定键的频率值加起来,而后把这个键的每个频率值除以这个加起来的值,就失去了概率。

3、加载数据集

接下来将加载真正的训练语料库。能够应用任何想要的长文本 (.txt) 文档。

为了简略起见将应用一个政治演讲来提供足够的词汇来传授咱们的模型。

 text_path = "train_corpus.txt"
 def load_text(filename):
     with open(filename,encoding='utf8') as f:
         return f.read().lower()
 
 text = load_text(text_path)
 print('Loaded the dataset.')

这个数据集能够为咱们这个样例的我的项目提供足够的事件,从而做出正当精确的预测。与所有机器学习一样,更大的训练语料库将产生更精确的预测。

4、建设马尔可夫链

让咱们构建马尔可夫链,并将概率与每个字符分割起来。这里将应用在第 1 步和第 2 步中创立的 generateTable()和 convertFreqIntoProb()函数来构建马尔可夫模型。

 def MarkovChain(text,k=4):
     T = generateTable(text,k)
     T = convertFreqIntoProb(T)
     return T
 
 model = MarkovChain(text)

第 1 行,创立了一个办法来生成马尔可夫模型。该办法承受文本语料库和 K 值,K 值是通知马尔可夫模型思考 K 个字符并预测下一个字符的值。第 2 行,通过向办法 generateTable()提供文本语料库和 K 来生成查找表,该办法是咱们在上一节中创立的。第 3 行,应用 convertFreqIntoProb()办法将频率转换为概率值,该办法也是咱们在上一课中创立的。

5、文本采样

创立一个抽样函数,它应用未实现的单词 (ctx)、第 4 步中的马尔可夫链模型(模型) 和用于造成单词基的字符数量(k)。

咱们将应用这个函数对传递的上下文进行采样,并返回下一个可能的字符,并判断它是正确的字符的概率。

 import numpy as np
 
 def sample_next(ctx,model,k):
 
     ctx = ctx[-k:]
     if model.get(ctx) is None:
         return " "
     possible_Chars = list(model[ctx].keys())
     possible_values = list(model[ctx].values())
 
     print(possible_Chars)
     print(possible_values)
 
     return np.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、生成文本

最初联合上述所有函数来生成一些文本。

 def generateText(starting_sent,k=4,maxLen=1000):
 
 sentence = starting_sent
     ctx = starting_sent[-k:]
 
     for ix in range(maxLen):
         next_prediction = sample_next(ctx,model,k)
         sentence += next_prediction
         ctx = sentence[-k:]
     return sentence
 
 print("Function Created Successfully!")
 
 text = generateText("dear",k=4,maxLen=2000)
 print(text)

后果如下:

 dear country brought new consciousness. i heartily great service of their lives, our country, many of tricoloring a color flag on their lives independence today.my devoted to be oppression of independence.these day the obc common many country, millions of oppression of massacrifice of indian whom everest.
 my dear country is not in the sevents went was demanding and nights by plowing in the message of the country is crossed, oppressed, women, to overcrowding for years of the south, it is like the ashok chakra of constitutional states crossed, deprived, oppressions of freedom, i bow my heart to proud of our country.my dear country, millions under to be a hundred years of the south, it is going their heroes.

下面的函数承受三个参数: 生成文本的起始词、K 的值以及须要文本的最大字符长度。运行代码将失去一个以“dear”结尾的 2000 个字符的文本。

尽管这段讲话可能没有太多意义,但这些词都是残缺的,通常模拟了单词中相熟的模式。

接下来要学什么

这是一个简略的文本生成我的项目。通过这个我的项目能够理解自然语言解决和马尔可夫链理论工作模式,能够在持续您的深度学习之旅时应用。

本文只是为了介绍马尔可夫链来进行的试验我的项目,因为它不会再理论利用中起到任何的作用,如果你想取得更好的文本生成成果,那么请学习 GPT- 3 这样的工具,因为:别问,问就是 GPT-3😁

https://avoid.overfit.cn/post/20212b30f7b94f2cacd66e8386626fcf

作者:Educative Team

正文完
 0