文本表示分类(基于表示方法)
- 离散表示
- one-hot表示
- 词袋模型与TF-ID
- 分布式表示
- 基于矩阵的表示方法
- 降维的方法
- 聚类的方法
- 基于神经网络的表示方法
- NNLM
- CBOW
- Skip-gram
- GloVe
- ELMo
- GPT
- BERT
- 基于矩阵的表示方法
目录
2.2.3 word2vec(CBOW和Skip-Gram)存在的问题
本博客总结到2014年GloVe,全部都是对于word embedding的总结,近写年的文本表示总结会在下篇呈现。
下篇:https://blog.csdn.net/qq_35883464/article/details/100173045
一、文本离散表示
1.1 文本离散表示:one-hot
单独讲one-hot挺简单的,我就把One-Hot Encoder独热编码、Label Encoder标签编码、Binary Encoder二进制编码,合起来写了一篇博客:https://blog.csdn.net/qq_35883464/article/details/90573416
1.2 文本离散表示:词袋模型与TF-IDF
1.2.1 词袋模型(bag of words)
这个很简单就少用些笔墨
词袋模型是一种非常经典的文本表示。顾名思义,它就是将字符串视为一个 “装满字符(词)的袋子” ,袋子里的 词语是随便摆放的。而两个词袋子的相似程度就以它们重合的词及其相关分布进行判断。
词袋模型的优点
- 简单,方便,快速
- 在语料充足的前提下,对于简单的自然语言处理任务效果不错。如文本分类。
词袋子模型的缺点
- 其准确率往往比较低。凡是出现在文本中的词一视同仁,不能体现不同词在一句话中的不同的重要性。
- 无法关注词语之间的顺序关系,这是词袋子模型最大的缺点。如“武松打老虎”跟“老虎打武松”在词袋子模型中是认为一样的。
1.2.2 对词袋模型的改进:TF-IDF
- 不仅考虑词语是否出现,还考虑其出现的次数或者频率(TF)
“的”这个次占了词频的很大的比重,而它对确定文本信息几乎没什么用。所以我们应该忽略掉这些词,取消掉它们的影响。一种方法是维护一个停用词表。但这种方式太粗暴。
改进方式:一个词预测主题的能力越强(与主题的关联程度),权重越大,反之,权重越小。
在网页中看到“原子能”这个词,或多或少能够了解网页的主题,而看到“应用”一词,则对主题基本上还是一无所知。因此,“原子能”的权重应该比应用大。
容易发现,如果一个关键词只在很少的网页出现,通过它就容易锁定搜索目标,它的权重也就应该比较大。反正,如果一个词在大量的网页中出现,看到它仍然不清楚要找什么内容,因此它的权重应该小。
- 统计逆文档频率(IDF)
不仅考虑这个词在当下文本的出现的概率,还考虑出现该词语的文档占总文档出现的频率(DF)。
其基本假设是如果一个词语在不同的文档中反复出现,那么它对于识别该文本并不重要。如高频词“我们”、“那么”之类。
严格来说,逆文档频率的公式为-log(出现该词语的文档占总文档出现的频率)
这里具体不做TF-IDF的公式讲解。
二、文本分布式表示
我们刚刚讲了词向量的one-hot表示,包括词向量的其他表示新式,主要目的就是让计算机认识这些词。
究其根本你会发现,这些词向量的表示是开了一个极高维度的空间,然后每个词语都会占据一个维度,因此没有办法在空间中关联起来。
因此我们可能可以把词向量的维度降低一些,在这样一个子空间中,可能原本没有关联的词就关联起来了。
所以基于矩阵方法的目标就是:把词向量的维度降低
2.1 基于矩阵
2.1.1 基于矩阵的SVD降维
这是一种词向量的方法,我们首先会遍历所有的文本数据集,然后统计词出现的次数,接着用一个矩阵X来表示所有的次数情况,紧接着对X进行奇异值分解得到一个的分解。然后用U的行(rows)作为所有词表中词的词向量。
- 基于窗口的共现矩阵X:
把矩阵?X记录的词频变成一个相关性矩阵。我们先规定一个固定大小的窗口,然后统计每个词出现在窗口中次数,这个计数是针对整个语料集做的。可能说得有点含糊,咱们一起来看个例子,假定我们有如下的3个句子,同时我们的窗口大小设定为1(把原始的句子分拆成一个一个的词):
- I enjoy flying.
- I like NLP.
- I like deep learning.
由此产生的计数矩阵如下:
然后我们对X做奇异值分解,观察观察奇异值(矩阵的对角元素),并根据我们期待保留的百分比来进行截断(只保留前k个维度)
对X采用奇异值分解,再通过选择前K个奇异向量来进行降维:
基于矩阵的SVD降维能够充分地编码语义和句法的信息,但同时也带来了其他的问题:
- 矩阵的维度会经常变化(新的词语经常会增加,语料库的大小也会随时变化)。
- 矩阵是非常稀疏的,因为大多数词并不同时出现。
- 矩阵的维度通常非常高(≈10的6次方)
- 训练需要?(?平方)的复杂度(比如SVD)
- 需要专门对矩阵X进行特殊处理,以应对词组频率的极度不平衡的状况
当然,有一些办法可以缓解一下上述提到的问题:
- 忽视诸如“he”、“the” 、“has”等功能词。
- 应用“倾斜窗口”(ramp window),即:根据文件中词组之间的距离给它们的共现次数增加相应的权重。
- 使用皮尔森的相关性(Pearson correlation),将0记为负数,而不是它原来的数值。
不过缓解终归只是缓解,不能根本的解决这些问题,这也就是我们马上要提到的基于神经网络的方法。
2.1.1 基于矩阵的聚类方法
因为基于矩阵的聚类方法,现在基本不用了,我就不总结了,上个图,大家了解下降维。
2.2 基于神经网络的表示方法
现在我们退后一步,来尝试一种新的方法。在这里我们并不计算和存储全局信息,因为这会包含太多大型数据集和数十亿句子。我们尝试创建一个模型,它能够一步步迭代地进行学习,并最终得出每个单词基于其上下文的条件概率。
2.2.1 神经网络语言模型(NNLM)
具体介绍:https://blog.csdn.net/qq_35883464/article/details/99692610
这种方法能让我们有非常显著的进步。考虑到前面 “词-词”矩阵的情况,我们至少可以算出两个词语共同出现的概率。但是,旧话重提,这仍然要求储存和计算一个非常的大数据集里面的全部信息。 现在我们理解了“分词序列”的概率(其实就是N-gram语言模型啦),让我们观察一些能够学习到这些概率的例子。
2.2.2 word2vec:CBOW(连续词袋模型)
Word2Vec模型中,主要有Skip-Gram和CBOW两种模型。
从直观上理解,Skip-Gram是给定input word(中间的词)来预测上下文。CBOW是给定上下文,来预测input word(中间的词)
图形理解CBOW:
我们把整个过程拆分成以下几步:
总结下特点:
2.2.2 CBOW:层次Softmax和负例采样
我们再次观察一下步骤,特别是步骤5,注意到对整个单词表|V|求softmax的计算量是非常巨大的,任何一个对目标函数的更新和求值操作都会有O(|V|)的时间复杂度。我们需要一个思路去简化一下,我们想办法去求它的近似。
- CBOW:层次Softmax
在机器学习中,如果要输出特征的预测结果中的重要性,会用到树模型,因为树在选择分裂的时候,就是选择包含的信息量大的特征进行分裂的。这里运用了HUffman Tree.
使用Huffman Tree ,原本我们计算的是10^8的概率向量,但是现在就可以转换为一个二分类问题,二分类中最简单的直接的就是LR模型的,假设Xw就是一个词向量表示,在每个非叶子节点处(途中黄色的圆点)还会有一个参数θwi,那我们的在LR中可以用一个sigmoid函数来映射,最后变成一个最小化损失函数的优化问题。
特点:
- 使用Huffman tree 来编码输出层的词典
- 只需要计算路径上所有非叶子节点的词向量的贡献
- 计算量为树的深度 log2V
- CBOW:负例采样
核心思想:一个正样本,V-1个负样本,对负样本做采样,使得正负样本相当。
在我们的例子中,预测“我喜欢观看巴西足球世界杯“这句话中的“巴西“这个词为我们的标准答案,(假设词库中有10**8个词)其他的10**8个就都不是标准答案.既然这样,干脆就在这10**8个负样本中抽取负样本来计算。
意思就是每个词一段距离。
2.2.3 Word2Vec: Skip-Gram模型
Skip-Gram模型实际上分为了两个部分,第一部分为建立模型,第二部分是通过模型获取嵌入词向量。Skip-Gram模型的整个建模过程实际上与自编码器(auto-encoder)的思想很相似,即先基于训练数据构建一个神经网络,当这个模型训练好以后,我们并不会用这个训练好的模型处理新的任务,我们真正需要的是这个模型通过训练数据所学得的参数。
Skip-Gram模型图示:
特点:
举个例子理解:
假如我们有一个句子“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')。
-
神经网络基于这些训练数据将会输出一个概率分布,这个概率代表着我们的词典中的每个词是output word的可能性。这句话有点绕,我们来看个栗子。第二步中我们在设置skip_window和num_skips=2的情况下获得了两组训练数据。假如我们先拿一组数据 ('dog', 'barked') 来训练神经网络,那么模型通过学习这个训练样本,会告诉我们词汇表中每个单词是“barked”的概率大小。
模型的输出概率代表着到我们词典中每个词有多大可能性跟input word同时出现。
我们选定句子“The quick brown fox jumps over lazy dog”,设定我们的窗口大小为2(window_size=2),也就是说我们仅选输入词前后各两个词和输入词进行组合。下图中,蓝色代表input word,方框内代表位于窗口内的单词。
以上就是Skip-Gram模型的例子,应该有个大致的了解。
2.2.3 word2vec(CBOW和Skip-Gram)存在的问题
2.2.3 GloVe
在2013年,word2vec如日中天的时候,斯坦福nlp组发表于2014年的一篇论文(引用量直破5k)。该论文提出的Glove词向量也是自Word2vec推出后另一个比较有影响力的词向量生成方法。
这里不讲GloVe的数学公式,只讲结果和自己的认识。
Cbow/Skip-Gram 是一个local context window的方法,缺乏了整体的词和词的关系,负样本采用sample的方式会缺失词的关系信息。
另外,直接训练Skip-Gram类型的算法,很容易使得高曝光词汇得到过多的权重。
Global Vector融合了 矩阵分解(LSA)的全局统计信息 和 local context window(局部窗口)优势。融入全局的先验统计信息,可以加快模型的训练速度,又可以控制词的相对权重。
我的理解是skip-gram、CBOW每次都是用一个窗口中的信息更新出词向量,但是Glove则是用了全局的信息(共线矩阵),也就是多个窗口进行更新
到目前为止,文本表示总结已经总结到2014年了,近写年的文本表示总结会在下篇呈现。