其他分享
首页 > 其他分享> > NLP文本表示总结

NLP文本表示总结

作者:互联网

目的:为了更系统的学习,在这里总结了NLP文本表示的若干方法,部分代码,仅供参考,欢迎交流。

代码

文本表示

离散表示:代表:词袋模型,one-hot,TF-IDF, N-gram。

分布式表示:词嵌入(word embedding),经典模型:词向量(word2vec)、Glove、ELMo、GPT、BERT。

一. 离散表示

One-hot encoded

one-hot向量不是一个好的选择,one-hot词向量无法表达不同词之间的相似度,例如任何一对词的one-hot向量的余弦相似度为0

Label Encoder标签编码

将离散的数据转换成(0,n-1)之间的数,n表示数据的不同取值,用代码表示以下:

from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
le.fit([1,5,67,100])
le.transform([1,1,100,67,5])

//输出 array([0,0,3,2,1])

缺点:类别数量很大时,特征空间会非常大,比如10000个单词的one-hot编码为一个10000*10000的矩阵。参数非常多。

Binary Encoder二进制编码

二进制编码,用序号给每个类别赋一个ID,根据这个ID对应的二进制编码作为结果。

Bag-of-words模型原理

忽略文本的语法和语序,用一组无序的单词来表达一段文字或一个文档。

John likes to watch movies. Mary likes too.

John also likes to watch football games.

根据上诉两句话中出现的单词,构建一个dict:{"John": 1, "likes": 2, "to": 3, "watch": 4, "movies": 5, "also": 6, "football": 7, "games": 8, "Mary": 9, "too": 10}

该字典包含两句话中全部词语,字典中的顺序与他们出现在句子中的顺序没有关系,根据这个词典上述两句话数字化为:

[1, 2, 1, 1, 1, 0, 0, 0, 1, 1]  即John出现1次,likes出现2次。。。

[1, 1, 1, 1, 0, 1, 1, 1, 0, 0]

 其中第i个元素表示字典中第i个单词在句子中出现的次数。

使用场景:在一个巨大的文档集合D,里面一共有M个文档,而文档里面的所有单词提取出来后,一起构成一个包含N个单词的词典,利用Bag-of-words模型,每个文档都可以被表示成为一个N维向量。

之后就可以对向量进行一系列的处理。。。

优点:简单

缺点:无法关注词语之间的顺序关系。

TF-IDF(Bag-of-words)

TF:给定词语在该文档(有多个文档)中出现的次数,归一化为(词频除以文章总词数)。

IDF:反应一个词在所有文档中出现的频率,如果一个词在多个文本中出现,那么他的IDF值应该很低,相反一个词在较少了文本中出现,那么IDF值应该很好,如果在每个文本中都出现IDF值为0。

综合TF和IDF值,来判断一个词的重要性。TF-IDF的值,用以评估词对于一个文件集或则语料库的重要程度。字词的重要性随着他在该文档中出现的次数成正比,但同时会随着他在(所有文档)语料库中出现的频率成反比下降。比如“machine learning”在该文档中出现的次数越多,而在其他文档出现频率低,说明该词在该文档的重要性很高。又比如“the,for”等词在该文档出现次数很多,但在所有文档出现的次数都很多,说明该词并不是那么重要。

 

其中,N_{w}是某词在该文档中出现的次数,N表示该所有文档中的总词数(也可以是该文档的总词数?)。

其中,Y是语料库的文档总数,Y_{w}是包含词条w的文档数。

TF-IDF就是将TF-IDF相乘。

根据上述公式,某一特定文档内的高频词汇,同时该词语在整个文档集合中的低文件频率,可以产生高权重的TF-IDF。因此,TF-IDF倾向于过滤掉常见的词语,保留重要的词语。

N-gram

词袋模型(bag-of-words)不考虑单词的顺序,就想把单词全装到一个袋子里,而接下来的N-gram模型就会考虑句子中单词之间的顺序。

N-gram模型是一种语言模型(Language model, LM),语言模型是一个基于概率的判别模型,它的输入是一句话(单词的顺序序列),输出是这句话的概率,即这些单词的联合概率(joint prpbability)

如果一个词的出现仅依赖它前面出现的词,称之为Bi-gram

如果一个词的出现仅依赖它前面出现的两个词,称之为 Tri-gram

è¿éåå¾çæè¿°

根据上面的Bi-gram公式,我们可以得出句子:<s> I want Chinese food <s>的概率为:

已知p(I|<s>) = 0.25,p(want|I) = 0.33...于是:

p(<s> I \, \ want \, Chinese\, food <s>) = 0.25\times 0.33\times 0.0065\times 0.52\times 0.68 = 1.896\times 10^{-4}

于是就算出了“I want chinese food”这句话的概率,同理你可以得到“want i chinese food”的概率值很小,远小于1.896\times 10^{-4},说明前一个句子更像人话。但有时候这句话会很长,那么概率(都是小于1的常数)的相乘很可能造成数据下溢(downflow),即很多个小于1的常数相乘会约等于0,此时可以使用log概率解决。

N-gram用途

N-gram的一些方法

N-gram中的N越大,模型的Perplexity越小,模型效果越好,因为依赖的词越多,获得的信息就越多,对未来的预测就越准确,但是当N很大时,会出现稀疏问题

n-gram最大的问题就是稀疏问题(Sparsity)。例如,在bi-gram中,若词库中有20k个词,那么两两组合\left ( C_{20k}^{2} \right )就有近2亿个组合。其中的很多组合在语料库中都没有出现,根据极大似然估计得到的组合概率将会是0,从而整个句子的概率就会为0。最后的结果是,我们的模型只能计算零星的几个句子的概率,而大部分的句子算得的概率是0,这显然是不合理的。

因此,要进行数据平滑(data Smoothing),数据平滑的作用:一个是使所有的N-gram的概率之和为1,使所有的n-gram概率都不为0。
具体讲解可看这篇文章

 

二. 分布式表示 Word Embedding(词嵌入)

Word Embedding(词嵌入)是将文本中从词转换为数字向量的方法,把一个维度很大的词向量嵌入到一个维度低得多的向量空间中,每个单词或词组被映射为实数域上的向量,词嵌入的结果就是生成了词向量Word2VecGlove都是Word Embedding的经典算法。

1. Word2Vec

Word2Vec:词到向量,是word embedding(词嵌入)的一种。只有把(抽象,符号)转到向量(数值),计算机才能明白。语义相同的词的词向量接近。

1.1 语言模型

f(x) \rightarrow y

如果用一个词语作为输入,来预测他上下文的词汇,这个模型就叫做Skip-gram模型

如果用一个词语的上下文来作为输入,来预测这个词语本身,这就是CBOW(Continuous Bag-of-words)模型

用当前词x预测它的下一个词y

这里的x的原始输入只能是数值类型,显然是one-hot encoder,通过输入one-hot格式,得到word2vec格式。

Skip-gram模型(y只有一个词)

X = \left \{ {x_{1},...,x_{V}} \right \}即one-hot格式的输入,隐藏层的权重矩阵H = \left \{ {h_{1},...,h_{N}} \right \}即为该词的词向量,Y = \left \{ {y_{1},...,y_{V}} \right \}为输出向量,也是one-hot格式。V即使词语的个数,隐藏层的激活函数是线性的,相当于没有做任何的处理,训练这个神经网络采用反向传播算法。这里的输入和输出维数相同,但在一般情况下输出的维度要远小于V,所以word2vec也是一种降维操作,把词语从one-hot encoder形式的表示降维到word2vec形式表示。

Skip-gram模型(y有多个词

 

CBOW的一般情况

使用多个词预测一个词。

1.2 训练策略

前面了解了skip-gram的输入层,隐藏层,输出层。在第二部分,会继续深入讲如何在skip-gram模型上进行高效的训练。

Word2Vec模型是一个超级大的神经网络,10000个单词的词汇表,嵌入到300维的词向量,那么我们的输入-隐层权重矩阵隐层-输出层的权重矩阵都会有 10000 x 300 = 300万个权重。

Word2Vec的作者在他的第二篇论文中强调了这些问题,提出三点:

  1. 将常见的单词组合(word pairs) 或者词组作为单个的“words”来处理,减少输入维数。
  2. 对高频单词进行抽样来减少训练样本的个数。
  3. 对优化目标采用“negative sampling(负采样)”方法。不仅降低了训练过程中的计算负担,还提高了训练的词向量的质量。

1.2.1 Word pairs and 'phases'

作者指出,一些单词组合(或词组)的含义和拆开以后具有完全不同的意义。比如“New York”,当文章中出现这种词时,我们应该把它作为一个单独的词来训练生成词向量,而不是拆开。

1.2.2 对高频词抽样

训练过程中的高频词,the,for,is等等对训练没有帮助。Word2Vec通过抽样模式解决这种高频词问题,根据在文本中出现的概率,来删除高频词。

抽样率

w_{i}是一个单词,Z(w_{i})w_{i}这个单词在所有语料中出现的频次,代码中有一个参数交sample,表示一个阈值,这个值越小意味着这个单词被保留下来的概率越小(即词频越容易达到阈值,越容易被删除)。

P(w_{i})代表保留某个单词的概率:

可以自己修改这些参数。

1.2.3 负采样(negative sampling)

解决大规模参数的问题

负采样能够提高训练速度,改善得到词向量的质量。以前是对每个样本进行训练更新所有的权重,而负采样每次让一个训练样本仅仅更新一小部分权重。

当我们用训练样本 ( input word: "fox",output word: "quick") 来训练我们的神经网络时,“fox”和“quick”都是经过one-hot编码的。如果我们的vocabulary大小为10000时,在输出层,我们期望对应“quick”单词的那个神经元结点输出1,其余9999个都应该输出0。在这里,这9999个我们期望输出为0的神经元结点所对应的单词我们称为“negative” word。

当采用负采样时,我们将随机选择一小部分的negative words(比如5个),来更新对应的权重,也会对"positive" word进行权重更新。同时更新negative sampling和positive word。(在论文中,作者指出指出对于小规模数据集,选择5-20个negative words会比较好,对于大规模数据集可以仅选择2-5个negative words。)

如何选择negative words

使用“一元模型分布(unigram distribution)”来选择negative words。

一个单词被选作negative word的概率和它出现的频次有关,频次越高越容易被选作negative words。

其中f(w_{i})表示单词出现的频次。

Word2Vec(CBOW和Skip-gram)存在的问题

优点:会考虑上下文,比Embedding方法更好;维度更小,速度更快;通用性很强,适用于各种NLP任务

缺点:对多义词无法很好的表示和处理,因为使用了唯一的词向量。Cbow/Skip-Gram 是一个local context window的方法,缺乏了整体的词和词的关系,负样本采用sample的方式会缺失词的关系信息。

 

2. Glove

Global Vector融合了 矩阵分解(LSA)的全局统计信息local context window(局部窗口)优势。融入全局的先验统计信息,可以加快模型的训练速度,又可以控制词的相对权重。

skip-gram、CBOW每次都是用一个窗口中的信息更新出词向量,但是Glove则是用了全局的信息(共现概率矩阵Co-occurrence Probabilities Matrix),也就是多个窗口进行更新。矩阵中的每一个元素X_{i,j}代表单词i和上下文单词j在特定大小的上下文窗口(context window)内共同出现的次数

构建词向量(Word Vector)和共现矩阵之间的近似关系,通过下面的公式表示:

其中,w_{i}^{T}\tilde{w}_{j}是我们最终求解的词向量b_{i}\tilde{b}_{j}分别是两个词向量的偏执。详细推导这里

通过公司1就可以得到loss function:

loss function的最简单函数就是MES,只不过在此基础上加上了权重函数f(X_{ij})。作用

根据论文\alpha取值为0.75,x_{max}取值100。

缺点:一词多义的问题尚未解决,因此,引出下面的模型。

 

3. ELMo

在此之前的Word Embedding本质上是一个静态的方式,即训练好的词向量就固定不变了,不论新句子的上下文是什么,这个单词的Word Embedding不会跟着语境变化。

ELMo的本质思想:事先用语言模型在一个大的语料库上学习好词的word embedding,此时的多义词任然无法区分,接着用特定的训练数据来fine-tuning预训练好的ELMo模型。(domain transfer)

1. 预训练

ELMo使用双向LSTM语言模型,由一个前向和后向语言模型构成。语言模型的训练任务是:根据单词w_{i}的上下文取正确预测w_{i}。每个编码器的深度都是两层LSTM叠加。

前向LSTM模型计算序列的概率,输入为从左到右顺序的除了w_{i}的上文:

反向LSTM根据未来的内容预测之前的token,输入为从右到左的逆序的句子的下午:

双向BiLM结合两者,联合最大化log似然函数:其中\Theta _{x}是token,\Theta _{s}是softmax层表示。

使用这个网络,利用大量语料预先训练好这个网络,之后输入一个新的句子,句子中的每一个单词都能得到三个Embedding:

2. 下游任务

  1. 先将句子X作为预训练好的ELMo网络的输入,这样句子X中每个单词在ELMo网络上都能获得三个embedding;
  2. 给予这三个embedding中每一个embedding权重a,这个权重可以学习得到,也可以累加求和,将三个embedding整合成一个;
  3. 将整合后的embedding作为X句在自己任务的网络结果中对应单词的输入。

4. OpenAI-GPT

OpenAI GPT

5. BERT

BERT笔记

任重道远啊~

参考

NLP自然语言处理:文本表示总结 - 上篇word embedding(基于降维、基于聚类、CBOW 、Skip-gram、 NNLM 、TF-ID、GloVe )

Bag-of-words模型入门

Tf-Idf详解及应用

自然语言处理中N-Gram模型介绍

自然语言处理NLP中的N-gram模型

Word2Vec

[NLP] 秒懂词向量Word2vec的本质

关于词嵌入(Word Embedding)的一些总结

GloVe详解通俗易懂理解——Glove算法原理

 

 

 

 

 

 

 

 

 

 

 

标签:总结,NLP,模型,单词,文档,gram,words,文本,向量
来源: https://blog.csdn.net/qq_38317254/article/details/117629316