文章目录
一、语言模型
语言模型可以说是自然语言处理中最重要的模型。语言模型可以看做是一个函数,用于计算一个句子出现的概率,即语言模型可以判断某一句话从语法上是否通顺(是不是人话),从语义上是否有歧义。在很多时候,我们都要度量一句话的出现概率,一句话的出现概率等同于一句话语法的流畅程度。通过语言模型,我们可以知道:
P
L
M
(
今
天
天
气
真
不
错
)
>
P
L
M
(
真
不
错
天
气
今
天
)
P
L
M
(
全
民
A
I
是
趋
势
)
>
P
L
M
(
全
民
趋
势
是
A
I
)
P_{LM}(今天天气真不错)>P_{LM}(真不错天气今天)\\P_{LM}(全民AI是趋势)>P_{LM}(全民趋势是AI)
PLM(今天天气真不错)>PLM(真不错天气今天)PLM(全民AI是趋势)>PLM(全民趋势是AI)
语言模型可以用于语音识别,机器翻译。
那么,如何计算每句话出现的概率?每句话出现的概率等于单词序列出现的概率。
P
L
M
(
s
)
=
P
L
M
(
w
1
,
w
2
,
.
.
.
,
w
n
)
P_{LM}(s)=P_{LM}(w_1,w_2,...,w_n)
PLM(s)=PLM(w1,w2,...,wn)
根据链式法则,可以表示为
P
L
M
(
s
)
=
P
L
M
(
w
1
,
w
2
,
.
.
.
,
w
n
)
=
P
L
M
(
w
1
)
P
L
M
(
w
2
∣
w
1
)
.
.
.
P
L
M
(
w
n
∣
w
1
w
2
.
.
.
w
n
−
1
)
P_{LM}(s)=P_{LM}(w_1,w_2,...,w_n)=P_{LM}(w_1)P_{LM}(w_2|w_1)...P_{LM}(w_n|w_1w_2...w_{n-1})
PLM(s)=PLM(w1,w2,...,wn)=PLM(w1)PLM(w2∣w1)...PLM(wn∣w1w2...wn−1)
因此,语言模型是一个概率模型,所谓的通顺,就是出现的概率高。比如:今天天气真不错应该怎样建模呢?
P
L
M
(
今
天
天
气
真
不
错
)
=
P
L
M
(
今
天
,
天
气
,
真
,
不
错
)
=
P
L
M
(
今
天
)
P
L
M
(
天
气
∣
今
天
)
P
L
M
(
真
∣
今
天
,
天
气
)
P
L
M
(
不
错
∣
今
天
,
天
气
,
真
)
P_{LM}(今天天气真不错)=P_{LM}(今天,天气,真,不错)=P_{LM}(今天)P_{LM}(天气|今天)P_{LM}(真|今天,天气)P_{LM}(不错|今天,天气,真)
PLM(今天天气真不错)=PLM(今天,天气,真,不错)=PLM(今天)PLM(天气∣今天)PLM(真∣今天,天气)PLM(不错∣今天,天气,真)
然而,对于长序列来说,当前条件很长的时候,许多条件概率也非常稀疏(概率值很小)。前面的条件(单词)都需要考虑进来嘛?如果假设每个词的出现概率是独立的,那样,就可以将上面的条件概率分布简化为如下一元语言模型(Unigram Model):
P
L
M
(
w
)
=
∏
i
=
1
n
P
L
M
(
w
i
)
P_{LM}(w)=\prod_{i=1}^nP_{LM}(w_i)
PLM(w)=i=1∏nPLM(wi)
但是很明显每个词出现的概率不可能是独立的,所以我们可以放宽假设,这就涉及到NLP领域最重要的假设:马尔科夫假设,假设任意一个词,它的出现概率只与前面出现的一个词(或者几个词)有关,那么,基于这个假设就可以将上面的条件概率分布简化为如下二元语言模型(Bigram Model):
P
L
M
(
s
)
=
P
L
M
(
w
1
)
P
L
M
(
w
2
∣
w
1
)
P
L
M
(
w
3
∣
w
2
)
.
.
.
P
L
M
(
w
n
∣
w
n
−
1
)
P_{LM}(s)=P_{LM}(w_1)P_{LM}(w_2|w_1)P_{LM}(w_3|w_2)...P_{LM}(w_n|w_{n-1})
PLM(s)=PLM(w1)PLM(w2∣w1)PLM(w3∣w2)...PLM(wn∣wn−1)
依次类推,还有三元语言模型(Trigram Model):
P
L
M
(
s
)
=
P
L
M
(
w
1
)
P
L
M
(
w
2
∣
w
1
)
P
L
M
(
w
3
∣
w
2
,
w
1
)
.
.
.
P
L
M
(
w
n
∣
w
n
−
1
,
w
n
−
2
)
P_{LM}(s)=P_{LM}(w_1)P_{LM}(w_2|w_1)P_{LM}(w_3|w_2,w_1)...P_{LM}(w_n|w_{n-1},w_{n-2})
PLM(s)=PLM(w1)PLM(w2∣w1)PLM(w3∣w2,w1)...PLM(wn∣wn−1,wn−2)
这类模型统称为N-gram Model。
使用神经网络构建语言模型与使用N-gram Model的思路是一样的,使用神经网络构建语言模型时,仍然会使用条件概率分解的形式,唯一的不同是在N-gram 语言模型中使用的是基于统计的方法估计每一个条件概率分布,而在神经网络中,我们使用的是神经网络近似每一个条件概率。
1. 如何评价语言模型的好坏?
理想情况下,
- 假设有两个语言模型A,B
- 选定一个特定的任务,比如拼写纠错
- 把两个模型A,B都应用在此任务中
- 最后比较准确率,从而判断A,B的表现
下面介绍一种新的评价指标—perplexity(困惑度)
perplexity越低,表明语言模型认为这句话出现的概率越高,这句话越有可能出现。困惑度最小是1,perplexity越小,确定性越高,perplexity越低越好。
2. 语言模型的平滑概念
平滑概念指的是试图给没有出现的N-gram分配一个比较合理的数值出来,不至于直接为0。下面介绍多种平滑策略:
- Add-one Smoothing—拉普拉斯平滑
V V V指的是词库的大小。 - Add-K Smoothing—拉普拉斯平滑
k是一个超参数,需要训练 - lnterpolation—插值
高阶的N-gram是很难出现的,我们可以将高阶的N-gram拆解出低阶的N-gram,低阶的N-gram出现的频率还是有的
核心思路:在计算Trigram概率时同时考虑Unigram,Bigram,Trigram出现的频次
我们可以选取一些超参数
OOV问题
OOV= out of vocab,没有出现在词典中的单词
3.语言模型在拼写纠错中的应用
拼写错误在英语中比汉语中更加常见。拼写纠错的前提是你所要输入的词是在词典中的,所使用的词典是非常完备的。我们可以将拼写错误分成两种情况:一种是错别字错误;另一种是语法错误。
3.1 如何解决错别字错误?
- 首先是发现错误
假设有一个非常完备的包含所有正确单词的词典,将用户的词在词典中寻找,如果没有发现,那么认为用户单词拼写错误 - 纠正错误
纠正错误的核心是如何生成候选的单词,要求候选的词与输入非常相近,这时,我们就需要一个度量方式(编辑距离),来度量两个单词之间是否相似,我们把编辑距离最小的词当成它的候选。
- 输入(用户输入)
- 从词典中寻找编辑距离最小的候选(生成编辑距离为1,2的字符串)
- 过滤
我们如何进行过滤呢?
这里要用到noisy channel model
贝叶斯公式:
其中, P ( c ) P(c) P(c)就是一个语言模型,P(s|c)就是在字符串c出现的前提下,字符串s出现的概率。这样处理相当于将一个复杂问题划分成两个子问题乘积的形式来考虑。- 返回
最小编辑距离Minimum Edit Distance(MED)
:
两个字符串之间的最小编辑距离可以定义为将字符串1转化为字符串2的最小的[插入/删除/替换]的操作数。
字符串"ABC"到字符串“BC”的操作数为1。
字符串“INTENTION”转变成字符串“EXECUTION”的操作数为5。
最小编辑距离有如下应用:拼写纠错,基因序列对齐;评估机器翻译与语音识别中的错误。
那么,如何计算两个字符串的最小编辑距离?
这是一个DP问题,需要使用动态规划算法,两个字符串的最小编辑距离可以划分成计算两个子串的最小编辑距离。
如果两个子串Am == Bn
,则两个字符串的最小编辑距离等于去掉这个子串的最小编辑距离。
如果两个子串Am != Bn
,则分别计算三种操作的最小编辑距离,选择编辑距离最小的,即为最小编辑距离。
二、文本表示
1. 词集模型—onthot编码
词集模型是指基于词典的句子的one-hot编码。词集模型只能统计这句话是否出现过这个词,而不能记录词之间的顺序,词出现的个数。one-hot编码表达方式有如下缺点:不能捕捉词之间的意思;新词不容易泛化,无法利用现有的词典解决新词编码。举个例子:词典:[今天,天气,真,不错]
- 每个单词的表示:
今天:[1,0,0,0]
天气:[0,1,0,0]
真:[0,0,1,0]
不错:[0,0,0,1]- 每个句子表示:
今天真不错:[1,0,1,1]
2.词袋模型—Bag of Words
鉴于词集模型只能统计这句话是否出现过这个词,而不能记录词之间的顺序,词出现的个数;词袋模型进行了改进,可以记录词出现的个数。当然,并不是词出现的次数越多就越重要,也并不是词出现的越少就越不重要。此时,就需要分别从本句子与全局角度来查看这个词重不重要,这也就是TF-IDF的核心思想。
词袋模型是最基础的文本表示模型。词袋模型是将每篇文章看成一袋子词,并忽略每个词出现的顺序。具体来说,就是将整段文本以词为单位切分开,然后每篇文章可以表示成一个长向量,向量中的每一维代表一个单词,而该维对应的权重则反映这个词在原文章中的重要程度。常用TF-IDF来计算权重,公式为:
T
F
−
I
D
F
(
t
,
d
)
=
T
F
(
t
,
d
)
×
I
D
F
(
t
)
TF-IDF(t,d)=TF(t,d)×IDF(t)
TF−IDF(t,d)=TF(t,d)×IDF(t)
其中,
T
F
(
t
,
d
)
TF(t,d)
TF(t,d)为单词
t
t
t在文档
d
d
d中出现的频率;
I
D
F
(
t
)
IDF(t)
IDF(t)是逆文档频率,用来衡量单词
t
t
t对表达语义所起的重要性,表示为
I
D
F
(
t
)
=
l
o
g
N
N
(
w
)
+
1
IDF(t)=log\frac{N}{N(w)+1}
IDF(t)=logN(w)+1N
其中,N表示语料库中的文章总数,N(w)表示词语w出现在多少个文档中
逆文档频率最直观的解释是:如果一个单词在非常多的文章里面出现,那么它很可能是一个通用词汇,对于区分某篇文章特殊语义的贡献越小,因此对权重做一定惩罚。
3.Word2Vec—词嵌入模型
什么才算是一个好的文本表示?相似词的表征之间的相似度要比不相似词的表征之间的相似度大。显然,不管是词集模型还是词袋模型,都不能满足这个要求。并且,不管是词集模型还是词袋模型,文本表示都是非常稀疏的,占用内存大,有用信息少。所以,我们想要更少的维度,更合理的表达方式来表达文本。研究者们利用词向量模型来进行词向量表示。传统的词向量模型有:SkipGram,Glove,CBOW;考虑上下文的词向量模型有ELmo,Bert,XLNet。
分布式词表示能够很好的表示新词,提升模型的泛化性能;更容易表示语义信息。分布式词表示基于假设:利用上下文的统计信息来表示这个词的意思。分布式词表示介绍两种形式:Counting Based, Prediction Based。
-
Counting Based:统计共现矩阵得到不同词的表现信息(共现关系)。
利用共现矩阵得到词的表现信息有如下问题: -
增加词汇量
-
高维
-
稀疏
有如下解决方法:
- Matrix Factorization—矩阵压缩
思想是将大部分重要信息存储在一个小的维度上(稠密向量)(比如将N维的表示向量压缩成n维的表示向量,n << N),可以利用奇异值分解进行矩阵分解,然后进行矩阵压缩进行简化,将简化后的矩阵乘起来得到 X ^ \hat{X} X^矩阵, X X X矩阵与 X ^ \hat{X} X^矩阵维度相同,并且 X ^ \hat{X} X^矩阵是在 X X X矩阵的基础上丢弃部分信息(只保留关键信息)得到的。
其中,U、V均为正交矩阵,S为对角矩阵
我们如何利用矩阵压缩思想呢?
将上文得到的共现矩阵进行SVD分解,然后将U、S、V矩阵进行压缩,分别得到 U ^ \hat{U} U^、 S ^ \hat{S} S^、 V ^ \hat{V} V^矩阵,保留 U ^ \hat{U} U^矩阵,相当于将词向量压缩成300~500维的词向量。经过实践表明,通过 U ^ \hat{U} U^矩阵得到的词向量已经足够好了,因此不需要 V ^ \hat{V} V^矩阵。
但是,这种方式也有如下问题:- SVD的高计算代价
- 难以合并新的单词或者新文档,泛化性能比较低
- 难以与深度学习(DL)模型集成
- Word2Vec—Prediction Based
基于假设:基于上下文信息来表示词的意思,我们用到了共现矩阵来表示词的相关性。鉴于共现矩阵压缩存在许多问题,那么,我们不妨用一个词来预测与它在同一个context中的其他的词的思想来代替利用共现矩阵来捕捉词线性关系的操作。如果一个词的表示可以预测与它在同一个context中的上下文中的其他的词,那么我们认为这个词表示向量一定程度上捕捉了上下文的信息,这也是Word2Vec的中心思想。
根据Word2Vec的中心思想就可以引出许多预测方式。如果预测方式是利用中心词预测周围的词,那么这种方式为skip-Gram。如果预测方式是利用两侧的词预测中心词,那么这种方式为CBOW。如果预测方式是利用前面的词预测中心词,那么这种方式为MVLM。
谷歌2013年提出的Word2Vec是目前最常用的词嵌入模型之一。Word2Vec实际上是一种浅层的神经网络,它有两种网络结构,分别是CBOW和Skip-gram。
CBOW是预测中间单词,这个模型涉及window size,如果window size=2,那么用前两个单词与后两个单词来预测中间的词。如上图中的CBOW,
输入:前后两个单词的onehot向量表示,如果词集大小为10000,则输入向量为(4×10000)
隐藏层大小为(10000×100)
输出:输出向量为(1×10000)
权重W:权重W的大小为(10000×100)
权重 W ′ W' W′:权重$W’的大小为(100×10000)输入乘以权重W得到分布式向量表示再乘 W ′ W' W′后进行累加(或者平均)得到向量表征,通过向量表征softmax,依据概率值最大,从词集中找出最应该出现的单词。
skip-gram是利用中心词预测上下文的单词。下面我们介绍这个模型是如何优化与预测的?我们要优化的是根据语料得到的条件概率分布,即优化给定中心词
w
w
w,上下文中的词
c
c
c出现的概率。
m
a
x
θ
∏
w
∈
T
e
x
t
∏
c
∈
C
o
n
t
e
x
t
P
(
c
∣
w
,
θ
)
\underset {\theta}{max}\prod_{w∈Text}\prod_{c∈Context}P(c|w,θ)
θmaxw∈Text∏c∈Context∏P(c∣w,θ)
用softmax形式参数化条件概率:
P
(
c
∣
w
,
θ
)
=
e
u
c
⋅
v
w
∑
c
′
e
u
c
′
v
w
P(c|w,θ)=\frac{e^{u_c·v_w}}{\sum_{c'}{e^{u_{c'}v_w}}}
P(c∣w,θ)=∑c′euc′vweuc⋅vw
∑
c
′
∈
C
o
n
t
e
x
t
P
(
c
′
∣
w
,
θ
)
\sum_{c'∈Context}P(c'|w,θ)
∑c′∈ContextP(c′∣w,θ) = 1,表示
w
,
c
w,c
w,c的语义相似性概率。我们在skip-Gram Model中需要维护两个词向量矩阵,这两个词向量矩阵一个是中心词Text矩阵
v
v
v,一个是上下文词Context矩阵
u
u
u。优化这个目标函数,就是优化
θ
\theta
θ,也就是固定
u
i
u_i
ui,基于梯度,更新中心词
v
v
v。
为什么中心词矩阵与Context矩阵要区分出来?事实上,完全可以使用同样的矩阵,不过,在使用中心词预测两侧的词时,中心词与两侧的词所扮演的角色是不同的。如果使用同样的分布,一定程度上削减模型的表达性能,如果使用不同的分布,一定程度上会增强模型的性能。
由于log函数是递增函数,因此两个最优化目标是等价的,这样转化会给计算带来便利。
针对求和是基于整个词表进行的,它的时间复杂度非常大,是与词表大小呈线性关系的,出现了两个
t
r
i
c
k
trick
trick:
-
Negative sampling(负采样)
采样得到一个上下文词和一个目标词,生成一个正样本(positive example),生成一个负样本(negative example),则是用与正样本相同的上下文词,再在字典中随机选择一个单词,这就是负采样(negative sampling)。
现在我们来看看如何进行负采样,得到neg个负例。word2vec采样的方法并不复杂, 如果词汇表的大小为 V V V,那么我们就将一段长度为1的线段分成 V V V份,每份对应词汇表中的一个词。 当然每个词对应的线段长度是不一样的,高频词对应的线段长,低频词对应的线段短。 每个词 w w w的线段长度由下式决定: -
Hierarchical Softmax
原先的softmax是从字典大小的词中预测属于哪个词。Hierarchical Softmax采用树的结构,减少搜索路径。
回到基于Hierarchical Softmax的word2vec本身,我们的目标是找到合适的所有节点的词向量和所有内部节点 θ \theta θ,使训练样本达到最大似然。
更新流程:1.基于语料训练样本建立霍夫曼树,会倾向于将词频比较大的放在树的前面。
2. 随机初始化所有的模型参数 θ \theta θ,所有的词向量 w w w
3. 进行梯度上升迭代过程,对于训练集中的每一个样本做梯度更新,更新: θ \theta θ和 w
4. 如果梯度收敛,则结束梯度迭代,否则回到步骤3继续迭代这一部分没有理解的可以参考:https://www.cnblogs.com/pinard/p/7243513.html
如果对您有帮助,麻烦点赞关注,这真的对我很重要!!!如果需要互关,请评论或者私信!