费曼说:学习一件事情最好的方式是做它的老师,这也是写这篇博文的目的,写这篇博文,即便有其他原因,但更多的还是写给自己,话不多说,让我们开始进入NLP吧
本次的内容主要还是对赛题进行基于深度学习的文本分类的问题,我们用到的内容有:wordvec进行词汇编码,TEXTCNN或TEXTRNN用于特征的提取,HAN用于文本分类的一种操作
任务说明:任务task5
基座课程:基座课程
1.方法解释
1.词向量:1.词向量,因为本次的输入是字符串的编码形式,每个数字都代表着一个字符,word2vec要做的事情就是将词汇词表示成一个定长的连续的稠密向量。
而另一种形式则是我们在上一讲中更为熟悉的独热编码的形式。传统的基于规则或基于统计的自然语义处理方法将单词看作一个原子符号被称作one-hot representation。one-hot representation把每个词表示为一个长向量。这个向量的维度是词表大小,向量中只有一个维度的值为1,其余维度为0,这个维度就代表了当前的词。
例如:
苹果 [0,0,0,1,0,0,0,0,0,……]
one-hot representation相当于给每个词分配一个id,这就导致这种表示方式不能展示词与词之间的关系。另外,one-hot representation将会导致特征空间非常大,但也带来一个好处,就是在高维空间中,很多应用任务线性可分。
而比较来说,词向量的优点在于:
① 词之间存在相似关系:
是词之间存在“距离”概念,这对很多自然语言处理的任务非常有帮助。
② 包含更多信息:
词向量能够包含更多信息,并且每一维都有特定的含义。在采用one-hot特征时,可以对特征向量进行删减,词向量则不能。
而词向量的缺点也很明显,那就是需要通过一定的训练和编码才能得到词汇的词向量,同时,词向量的维度也更大,带来训练上的更多时间。
2.词向量的生成:本文主要介绍的是datawhale中的word2vec方法,其他方法在前面做简要介绍:
1.基于统计方法:
1.1 共现矩阵
通过统计一个窗口下word的出现次数,得到词汇的共同出现矩阵。
1.2 奇异值分解:既然共现矩阵存在着离散词向量具有稀疏性的问题,一个思路是对原始的词向量进行降维,得到一个稠密的矩阵。
进行SVD分解,得到矩阵正交矩阵U,对U进行归一化得到矩阵如下:
2.word2vec的主要思路:训练神经网络语言模型NNLM(neural network language model),词向量做为语言模型的附带产出。NNLM背后的基本思想是对出现在上下文环境里的词进行预测,这种对上下文环境的预测本质上也是一种对共现统计特征的学习。
通过单词和上下文彼此预测,对应的两个算法分别为:
-
Skip-grams (SG):预测上下文
-
Continuous Bag of Words (CBOW):预测目标单词
另外提出两种更加高效的训练方法:
-
Hierarchical softmax
-
Negative sampling
1.CBOW
CBOW模型是预测上下文已知的情况下,当前词出现的概率。上下文的选取采用窗口方式,即只将当前词窗口范围内的词作为上下文。中心词概率公式如下:
P(wt|wt-k,wt-(k-1)…,wt-1,wt+1,wt+2…,wt+k)= P(wt|context)
2. Skip-grams原理和网络结构
Word2Vec模型中,主要有Skip-Gram和CBOW两种模型,从直观上理解,Skip-Gram是给定input word来预测上下文。而CBOW是给定上下文,来预测input word。
Word2Vec模型的建立可以分为两个主要部分:模型构建和嵌入词向量获取。
1. 模型构建:Word2Vec的建模过程类似于自编码器。首先,基于训练数据构建一个神经网络模型。常用的两种Word2Vec模型是Skip-gram和CBOW(Continuous Bag of Words)。这些模型的目标是通过训练数据学习词语的分布式表示,即词向量。模型的训练过程使用文本数据来预测上下文或目标词语,以优化模型的参数。
2. 嵌入词向量获取:在模型训练完成后,我们不会直接使用整个模型来处理新的任务。相反,我们更关注模型学习到的参数,尤其是隐藏层的权重矩阵。在Word2Vec中,这些权重实际上是所谓的“词向量”,它们是用于表示词语的向量形式。
通过模型的训练过程,Word2Vec能够学习到词语之间的语义关系,并将其编码为分布式的词向量。这些词向量可以用于各种自然语言处理任务,如文本分类、语义相似度计算等。
Skip-grams过程
假如我们有一个句子“The dog barked at the mailman”。
-
首先我们选句子中间的一个词作为我们的输入词,例如我们选取“dog”作为input word;
-
有了input word以后,我们再定义一个叫做skip_window的参数,它代表着我们从当前input word的一侧(左边或右边)选取词的数量。如果我们设置skip_window=2,那么我们最终获得窗口中的词(包括input word在内)就是['The', 'dog','barked', 'at']。skip_window=2代表着选取左input word左侧2个词和右侧2个词进入我们的窗口,所以整个窗口大小span=2x2=4。另一个参数叫num_skips,它代表着我们从整个窗口中选取多少个不同的词作为我们的output word,当skip_window=2,num_skips=2时,我们将会得到两组 (input word, output word) 形式的训练数据,即 ('dog', 'barked'),('dog', 'the')。
-
神经网络基于这些训练数据将会输出一个概率分布,这个概率代表着我们的词典中的每个词作为input word的output word的可能性。
input word和output word都会被我们进行one-hot编码。仔细想一下,我们的输入被one-hot编码以后大多数维度上都是0(实际上仅有一个位置为1),所以这个向量相当稀疏,那么会造成什么结果呢。如果我们将一个1 x 10000的向量和10000 x 300的矩阵相乘,它会消耗相当大的计算资源,为了高效计算,它仅仅会选择矩阵中对应的向量中维度值为1的索引行:
2. Skip-grams训练
由上部分可知,Word2Vec模型是一个超级大的神经网络(权重矩阵规模非常大)。例如:我们拥有10000个单词的词汇表,我们如果想嵌入300维的词向量,那么我们的输入-隐层权重矩阵和隐层-输出层的权重矩阵都会有 10000 x 300 = 300万个权重,在如此庞大的神经网络中进行梯度下降是相当慢的。更糟糕的是,你需要大量的训练数据来调整这些权重并且避免过拟合。百万数量级的权重矩阵和亿万数量级的训练样本意味着训练这个模型将会是个灾难
解决方案:
-
将常见的单词组合(word pairs)或者词组作为单个“words”来处理
-
对高频次单词进行抽样来减少训练样本的个数
-
对优化目标采用“negative sampling”方法,这样每个训练样本的训练只会更新一小部分的模型权重,从而降低计算负担
2.1 Word pairs and "phases"
一些单词组合(或者词组)的含义和拆开以后具有完全不同的意义。
在Google发布的模型中,它本身的训练样本中有来自Google News数据集中的1000亿的单词,但是除了单个单词以外,单词组合(或词组)只有3百万之多。
2.2 对高频词抽样
在上一部分中,对于原始文本为“The quick brown fox jumps over the laze dog”,如果使用大小为2的窗口,那么我们可以得到图中展示的那些训练样本。
但是对于“the”这种常用高频单词,这样的处理方式会存在下面两个问题:
-
当我们得到成对的单词训练样本时,("fox", "the") 这样的训练样本并不会给我们提供关于“fox”更多的语义信息,因为“the”在每个单词的上下文中几乎都会出现
-
由于在文本中“the”这样的常用词出现概率很大,因此我们将会有大量的(”the“,…)这样的训练样本,而这些样本数量远远超过了我们学习“the”这个词向量所需的训练样本数
Word2Vec通过“抽样”模式来解决这种高频词问题。它的基本思想如下:对于我们在训练原始文本中遇到的每一个单词,它们都有一定概率被我们从文本中删掉,而这个被删除的概率与单词的频率有关。
ωi 是一个单词,Z(ωi) 是 ωi 这个单词在所有语料中出现的频次,例如:如果单词“peanut”在10亿规模大小的语料中出现了1000次,那么 Z(peanut) = 1000/1000000000 = 1e - 6。
P(ωi) 代表着保留某个单词的概率:
2.3 Negative sampling(负采样)
当使用负采样时,我们将随机选择一小部分的negative words(比如选5个negative words)来更新对应的权重。我们也会对我们的“positive” word进行权重更新(在我们上面的例子中,这个单词指的是”quick“)。
PS: 在论文中,作者指出指出对于小规模数据集,选择5-20个negative words会比较好,对于大规模数据集可以仅选择2-5个negative words。
我们使用“一元模型分布(unigram distribution)”来选择“negative words”。个单词被选作negative sample的概率跟它出现的频次有关,出现频次越高的单词越容易被选作negative words。
每个单词被选为“negative words”的概率计算公式:
其中 f(ωi)代表着单词出现的频次,而公式中开3/4的根号完全是基于经验的。
有了这张表以后,每次去我们进行负采样时,只需要在0-1亿范围内生成一个随机数,然后选择表中索引号为这个随机数的那个单词作为我们的negative word即可。一个单词的负采样概率越大,那么它在这个表中出现的次数就越多,它被选中的概率就越大。
3. Hierarchical Softmax
3.1 霍夫曼树(一种数据结构)
输入:权值为(w1,w2,…wn)的n个节点
输出:对应的霍夫曼树
-
将(w1,w2,…wn)看做是有n棵树的森林,每个树仅有一个节点
-
在森林中选择根节点权值最小的两棵树进行合并,得到一个新的树,这两颗树分布作为新树的左右子树。新树的根节点权重为左右子树的根节点权重之和
-
将之前的根节点权值最小的两棵树从森林删除,并把新树加入森林
-
重复步骤 2 和 3 直到森林里只有一棵树为止
那么霍夫曼树有什么好处呢?一般得到霍夫曼树后我们会对叶子节点进行霍夫曼编码,由于权重高的叶子节点越靠近根节点,而权重低的叶子节点会远离根节点,这样我们的高权重节点编码值较短,而低权重值编码值较长。
在word2vec中,约定编码方式和上面的例子相反,即约定左子树编码为1,右子树编码为0,同时约定左子树的权重不小于右子树的权重。
更多原理可参考:霍夫曼树原理
3.2Hierarchical Softmax过程
为了避免要计算所有词的softmax概率,word2vec采样了霍夫曼树来代替从隐藏层到输出softmax层的映射。
霍夫曼树的建立:
-
根据标签(label)和频率建立霍夫曼树(label出现的频率越高,Huffman树的路径越短)
-
Huffman树中每一叶子结点代表一个label
哈夫曼树是一种针对词频进行分类的高效的数据结构
2.TextCNN
下面是TEXTCNN完整的机器学习的各部分组成,这里,我们只取TEXTCNN中用于特征提取的精华思想:基于TextCNN原始论文的设定,分别采用了100个大小为2,3,4的卷积核,最后得到的文本向量大小为100*3=300维。
TextRNN
T extRNN是一种利用循环神经网络(RNN)进行文本特征抽取的模型。由于文本是一种序列数据,而长短期记忆(LSTM)是RNN的一种具有记忆能力的变体,因此LSTM天然适合用于建模文本数据。
TextRNN的工作流程如下:
1. 输入层:将文本中的每个词转换为对应的词向量表示。常见的词向量表示方法包括Word2Vec、GloVe等。
2. 双向双层LSTM:将每个词的词向量依次输入到双向双层LSTM中。双向LSTM由两个方向的LSTM组成,分别从前向和后向对输入序列进行处理。双层LSTM表示LSTM的堆叠,其中每一层都接收上一层的输出作为输入。
3. 隐藏层拼接:在TextRNN中,将两个方向最后一个有效位置的隐藏层输出进行拼接,形成一个向量。这个向量可以看作是对整个句子的抽象表示。
3.使用HAN用于文本分类
Hierarchical Attention Network for Document Classification (HAN) 是一种基于层级注意力的模型,用于文档分类任务。它在单词级别和句子级别对文本进行编码,并使用注意力机制获取文档的表示,然后通过 Softmax 进行分类。
HAN 模型的主要流程如下:
1. 单词编码(Word Encoder):首先,对文档中的每个单词进行编码。在原始的 HAN 模型中,使用的单词编码器可以是 TextCNN 或 TextRNN,用于捕捉单词级别的特征。TextCNN 利用卷积神经网络对单词序列进行特征提取,而 TextRNN 利用循环神经网络对单词序列进行建模。
2. 句子编码(Sentence Encoder):在单词编码的基础上,对文档中的句子进行编码。这一步骤通过使用注意力机制来捕捉每个句子的重要性。注意力机制允许模型自动关注句子中最相关的部分。通常,使用双向 LSTM 或 GRU 对句子进行建模,并计算每个句子的注意力权重。
3. 文档表示(Document Representation):通过结合句子编码和注意力权重,计算文档的表示。这可以通过对句子编码的输出进行加权平均或加权求和来实现。注意力权重决定了每个句子对于整个文档的重要性。
4. 分类(Classification):最后,使用 Softmax 分类器对文档表示进行分类,将文档分配到相应的类别中。
在 HAN 模型中,Word Encoder 的作用是获取句子的表示。可以替换为 TextCNN、TextRNN 或 BERT 等其他单词级别的编码器。这样做可以根据任务需求选择更适合的模型来捕捉单词级别的语义和特征。例如,TextCNN 适用于捕捉局部特征,TextRNN 适用于捕捉上下文信息,而 BERT 则能够利用预训练的语言表示进行更全面的语义建模。
2.作业一:尝试通过Word2Vec训练词向量
使用T-SNE降维绘制词向量图
3.作业二:尝试使用TextCNN、TextRNN完成文本表示
问题:内存不足
DataWhale-TEXTRNN代码实践(kaggle平台实践):
输出结果为0.8,可能是由于训练时间过长,且早停机制设置失误导致的
4.作业三:尝试使用HAN进行文本分类
有在本机运行时间过长的问题,由于平台使用有限制,未进入kaggle平台进行实践
5.总结
我们用到的内容有:wordvec进行词汇编码,TEXTCNN或TEXTRNN用于特征的提取,HAN用于文本分类,进行了一次较为完整的机器学习流程