当前位置:   article > 正文

Word2Vec模型详解

word2vec模型

文本向量化表示

对文本进行完预处理后,接下来的重要任务就是将文本用向量化的形式进行表达。在本章节中,我们将尽量全面地覆盖文本向量化表示方法,重点关注Word2Vec以及目前各种常用的词向量。

基于统计方法

首先,我们来看基于统计方法的向量化表示,包括One-Hot Encoding,,BOW,TF-IDF,矩阵分解

One-Hot Encoding

独热编码是比较容易想到的一种编码方式,但独热编码显然无法表示语义信息和词语之间的关系,而且独热编码矩阵是一个庞大并且稀疏的矩阵。

import numpy as np
def one_hot_encoding(tokenized_corpus, word2idx):
    vocab_size = len(word2idx)
    one_hot_array = np.zeros((vocab_size, vocab_size))
    m, n = tokenized_corpus.shape[0], tokenized_corpus.shape[1]
    for i in range(m):
        for j in range(n):
            token = tokenized_corpus[i, j]
            index = word2idx[token]
            one_hot_array[i, index] = 1
            
    return one_hot_array 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

BOW(Bag of Words)

词袋模型是将句子中每一个词用其在句子中出现的次数来表示(Count-based),这种做法考虑到了单词的重要性,但仍然无法理解语义信息和词语关系,同样是一个庞大的稀疏矩阵。

from sklearn.feature_extraction.text import CountVectorizer
corpus = [
    'I like this course',
    'I like this game',
    'I like this course, but I also like that game'
]
vectorizer = CountVectorizer()
counte_based_array = vectorizer.fit_transform(corpus)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

TF-IDF向量

词频-逆文本频率是一种同统计方法,用于统计每个词对一份文件的重要程度。换言之,一个词在整个语料库中出现的次数越多,它的重要性越低(例如a, the);而一个词在一份文件中出现次数越多,则其重要性越高。TF-IDF的公式如下
T F − I D F ( w i ) = T F ( d , w ) ∗ I D F ( w ) TF-IDF(w_{i}) = TF(d, w)*IDF(w) TFIDF(wi)=TF(d,w)IDF(w)

T F ( d , w ) : 单词 w 在文档 d 中的频率 TF(d, w):单词w在文档d中的频率 TF(d,w):单词w在文档d中的频率

I D F ( w ) = l o g N N ( w ) ( N 为语料库中的文档总数, N ( w ) 为有词语 w 出现的文档数 ) IDF(w)=log{\frac{N}{N(w)}}(N为语料库中的文档总数,N(w)为有词语w出现的文档数) IDF(w)=logN(w)N(N为语料库中的文档总数,N(w)为有词语w出现的文档数)

TF-IDF向量在机器学习中比较常见

from sklearn.feature_extraction.text import TfidfVectorizer

corpus = [
    'I like this course',
    'I like this game',
    'I like this course, but I also like that game'
]
vectorizer = TfidfVectorizer(use_idf=True, smooth=True)
tfidf_array = vectorizer.fit_transform(corpus)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

矩阵分解

首先介绍矩阵分解SVD。若矩阵 A m ∗ n A_{m*n} Amn​​满足 A A T = A T A = I AA^{T}=A^{T}A=I AAT=ATA=I,则称矩阵 A A A为正交矩阵。而酉矩阵是正交矩阵在复数域上的推广。(判断正交矩阵的充要条件: A T = A − 1 A^{T}=A^{-1} AT=A1)​​

对任意的矩阵 A m ∗ n A_{m*n} Amn,都能被奇异值分解为: A = U ( ∑ r 0 0 0 ) V T A=U(

r000
)V^{T} A=U(r000)VT

其中 U U U m ∗ m m*m mm的正交矩阵, V V V n ∗ n n*n nn的正交矩阵, ∑ r \sum_{r} r是由矩阵 A A A特征值从大到小排列成的方阵。

利用矩阵分解获得词向量:

我们定义一个 V ∗ V V*V VV的方阵 X X X V V V​是词库大小, X i , j X_{i,j} Xi,j表示单词 i i i和单词 j j j同时出现的次数。

将矩阵 X X X进行SVD分解,得到的矩阵 U U U V V V即为词向量矩阵。

基于语言模型

在传统的向量化表示方法中,词向量矩阵的维度都是N*V的,一旦词库中单词数量很多,那么维度就会爆炸。而且,不论是独热编码还是BOW,文本都被表示成一个由0、1组成的稀疏向量。因此,我们希望能够训练出一种分布式的、可以指定维度的稠密的词向量,并且希望这种词向量能够有效表示出单词之间的关系。

Word2Vec

分布式假设

you shall know a word by the company it keeps(Harris, 1954; Firth, 1957)

分布式假设是说我们可以通过周围的词来预测当前词,基于这个假设,我们来研究Word2Vec两种著名的算法Skip-Gram和CBOW

Skip-Gram

Skip-Gram做的事情是根据中心词来预测上下文,即根据 w t w_{t} wt​来预测 [ w t − w i n d o w _ s i z e , w t − w i n d o w _ s i z e + 1 . . . w t − 1 ] [w_{t-window\_size}, w_{t-window\_size+1}...w_{t-1}] [wtwindow_size,wtwindow_size+1...wt1]​和 [ w t + 1 , w t + 2 . . . w t + w i n d o w _ s i z e ] [w_{t+1}, w_{t+2}...w_{t+window\_size}] [wt+1,wt+2...wt+window_size]​​。

Skip-Gram模型的细节如下:

  1. 使用一层隐藏层
  2. 模型输入 w t w_{t} wt​使用独热编码
  3. 输出层采用 s o f t m a x softmax softmax函数
  4. 训练好的输入层与隐藏层之间的权重,即下图的矩阵 W W W即为词向量

在这里插入图片描述

下面,我们来详细地学习一下Skip-Gram

假设我们的语料库是:I am a student studying in NUS. 我们定义 w i n d o w _ s i z e = 1 window\_size=1 window_size=1​,那么我们需要做的是:
m a x i m i z e : p ( I ∣ a m ) p ( a m ∣ I ) p ( a m ∣ a ) p ( a ∣ a m ) p ( a ∣ s t u d e n t ) p ( s t u d e n t ∣ a ) p ( s t u d e n t ∣ s t u d y i n g ) p ( s t u d y i n g ∣ s t u d e n t ) p ( s t u d y i n g ∣ i n ) p ( i n ∣ s t u d y i n g ) p ( i n ∣ N U S ) p ( N U S ∣ i n ) maximize:p(I|am)p(am|I)p(am|a)p(a|am)p(a|student)p(student|a)p(student|studying)p(studying|student)p(studying|in)p(in|studying)p(in|NUS)p(NUS|in) maximize:p(Iam)p(amI)p(ama)p(aam)p(astudent)p(studenta)p(studentstudying)p(studyingstudent)p(studyingin)p(instudying)p(inNUS)p(NUSin)
我们将目标函数写成一般形式,即:
m a x i m i z e : ∏ w ∈ t e x t ∏ c ∈ c o n t e x t ( w ) p ( c ∣ w ; θ ) maximize:\prod_{w\in{text}}\prod_{c\in{context(w)}}p(c|w;\theta) maximize:wtextccontext(w)p(cw;θ)
其中, θ \theta θ是我们的参数,也就是我们想要训练的词向量。看到概率连乘,自然想到取对数,即
θ ∗ = a r g m a x ( ∑ w ∈ t e x t ∑ c ∈ c o n t e x t ( w ) l o g p ( c ∣ w ; θ ) ) \theta^{*}=argmax(\sum_{w\in{text}}\sum_{c\in{context(w)}}logp(c|w;\theta)) θ=argmax(wtextccontext(w)logp(cw;θ))
其中, p ( c ∣ w ; θ ) p(c|w;\theta) p(cw;θ)应该满足以下几条性质:

  1. p ( c ∣ w ; θ ) ∈ ( 0 , 1 ) p(c|w;\theta)\in{(0,1)} p(cw;θ)(0,1)
  2. 若c与w相似度高,则 p ( c ∣ w ; θ ) p(c|w;\theta) p(cw;θ)
  3. 若c与w相似度低,则 p ( c ∣ w ; θ ) p(c|w;\theta) p(cw;θ)
  4. ∑ c , ∈ c o n t e x t ( w ) p ( c , ∣ w ; θ ) = 1 \sum_{c^{,}\in{context(w)}}{p(c^{,}|w;\theta)}=1 c,context(w)p(c,w;θ)=1

根据以上这几条性质,我们可以使用 s o f t m a x softmax softmax函数来计算 p ( c ∣ w ; θ ) p(c|w;\theta) p(cw;θ)​,即
p ( c ∣ w ; θ ) = e x p ( U c V w T ) ∑ c , e x p ( U c , V w T ) p(c|w;\theta)=\frac{exp(U_{c}V_{w}^{T})}{\sum_{c^{,}}exp({U_{c^{,}}}V_{w}^{T})} p(cw;θ)=c,exp(Uc,VwT)exp(UcVwT)
其中,U和V都是我们的词向量矩阵,定义两种矩阵的原因是每个词既可以作为中心词,也可以作为上下文词,所以在此加以区分。那么整个模型的参数 θ \theta θ​就可以表示为 θ = ( U , V ) \theta={(U, V)} θ=(U,V)

有了概率的表达式,我们可以将目标函数改写成以下的形式
θ ∗ = a r g m a x ( ∑ w ∈ t e x t ∑ c ∈ c o n t e x t ( w ) ( U c V w T − l o g ∑ c , e x p ( U c , V w T ) ) ) \theta^{*}=argmax(\sum_{w\in{text}}\sum_{c\in{context(w)}}(U_{c}V_{w}^{T}-log\sum_{c^{,}}exp(U_{c^{,}}V_{w}^{T}))) θ=argmax(wtextccontext(w)(UcVwTlogc,exp(Uc,VwT)))
要优化这个函数,我们可以采用梯度下降法来求解。但是不难发现一个问题,就是每次在更新梯度的时候,我们都要在每层求和符号里计算 l o g ∑ c , e x p ( U c , V w ) log\sum_{c^{,}}exp(U_{c^{,}}V_{w}) logc,exp(Uc,Vw)​,计算的成本是 O ( V ) O(V) O(V)​​​​,V是词库大小。那假如我们的词库非常庞大,那么这个模型的效率就会很低。为了解决这个问题,作者提出了两种技巧:negative sampling(负采样)和hierarchical s o f t m a x softmax softmax(层级 s o f t m a x softmax softmax​) 。

Negative Sampling

我们将 w t w_{t} wt​的上下文单词叫做正样本,其余的成为负样本。我们重新定义目标函数
θ ∗ = a r g m a x ( ∏ ( w , c ) ∈ D p ( D = 1 ∣ w , c ; θ ) ∏ ( w , c , ) ∈ D n o i s e p ( D = 0 ∣ w , c , ; θ ) ) \theta^{*}=argmax(\prod_{(w,c)\in{D}}p(D=1|w,c;\theta)\prod_{(w,c^{,})\in{D_{noise}}}{p(D=0|w,c^{,};\theta)}) θ=argmax((w,c)Dp(D=1∣w,c;θ)(w,c,)Dnoisep(D=0∣w,c,;θ))
同样分析概率 p ( D = 1 / 0 ∣ w , c ; θ ) p(D=1/0|w,c;\theta) p(D=1/0∣w,c;θ)的性质可以得出,我们应该用 s i g m o i d sigmoid sigmoid函数来计算此概率,即
p ( D = 1 ∣ w , c ; θ ) = 1 1 + e x p ( − U c V w ) p(D=1|w,c;\theta)=\frac{1}{1+exp(-U_{c}V_{w})} p(D=1∣w,c;θ)=1+exp(UcVw)1

p ( D = 0 ∣ w , c ; θ ) = e x p ( − U c V w ) 1 + e x p ( − U c V w ) p(D=0|w,c;\theta)=\frac{exp(-U_{c}V_{w})}{1+exp(-U_{c}V_{w})} p(D=0∣w,c;θ)=1+exp(UcVw)exp(UcVw)

那么,取对数后的目标函数可表示为
θ ∗ = a r g m a x ( ∑ ( w , c ) ∈ D l o g σ ( U c V w ) ) + ∑ ( w , c , ) ∈ D n o i s e l o g σ ( − U c , V w ) \theta^{*}=argmax(\sum_{(w,c)\in{D}}log\sigma(U_cV_w))+\sum_{(w,c^{,})\in{D_{noise}}}log\sigma(-U_{c^{,}}V_w) θ=argmax((w,c)Dlogσ(UcVw))+(w,c,)Dnoiselogσ(Uc,Vw)
而在实际训练的过程中,我们不会只选取一组负样本,而是会选取多组负样本,所以目标函数为
θ ∗ = a r g m a x ( ∑ ( w , c ) ∈ D l o g σ ( U c V w ) ) + k ∗ ∑ ( w , c , ) ∈ D n o i s e l o g σ ( − U c , V w ) \theta^{*}=argmax(\sum_{(w,c)\in{D}}log\sigma(U_cV_w))+k*\sum_{(w,c^{,})\in{D_{noise}}}log\sigma(-U_{c^{,}}V_w) θ=argmax((w,c)Dlogσ(UcVw))+k(w,c,)Dnoiselogσ(Uc,Vw)
接下来仍然采用梯度下降求解即可,梯度的求导过程如下:
∂ L ∂ U c = V w ( 1 − σ ( U c V w ) ) \frac{\partial{L}}{\partial{U_c}}=V_w(1-\sigma(U_cV_w)) UcL=Vw(1σ(UcVw))

∂ L ∂ V w = U c ( 1 − σ ( U c V w ) ) − k ∗ ∑ ( w , c , ) ∈ D n o i s e U c , ( 1 − σ ( U c V w ) ) \frac{\partial{L}}{\partial{V_w}}=U_c(1-\sigma(U_cV_w))-k*\sum_{(w,c^{,})\in{D_{noise}}}U_{c^{,}}(1-\sigma({U_cV_w})) VwL=Uc(1σ(UcVw))k(w,c,)DnoiseUc,(1σ(UcVw))

∂ L ∂ U c , = V w ( σ ( U c V w ) − 1 ) \frac{\partial{L}}{\partial{U_{c^{,}}}}=V_w(\sigma(U_cV_w)-1) Uc,L=Vw(σ(UcVw)1)

负样本的选取方式有以下三种:

  • Randomly,随计选取
  • By frequency, 根据频率
  • Heuristic, 介于上述两种方法之间,频率的 3 4 \frac{3}{4} 43​次方
Hierarchical Softmax

Hierarchical Softmax是指层级Softmax,利用了霍夫曼树,鉴于这只是训练的小trick且较为复杂,在这里不做过多介绍。

CBOW

CBOW和Skip-Gram的任务恰好相反,即根据上下文来预测中心词

在这里插入图片描述

具体细节与Skip-Gram类似,这里不再赘述

我们对两种Word2Vec模型做一个简单对比

Skip-GramCBOW
模型输入中心词上下文
模型输出上下文中心词
复杂度
训练时间
训练效果较好稍差
生僻词和专有词训练效果较好稍差

Glove

Glove词向量结合了Skip-Gram和矩阵分解两种模型,兼顾全局和局部特征,并使用了加权的最小二乘误差。
J = ∑ i , j = 1 V f ( X i , j ) ( w i T w ~ j + b i + b j ~ − l o g X i , j ) 2 J = \sum_{i,j=1}^{V}f(X_{i,j})(w_{i}^{T}\widetilde{w}_{j}+b_i+\widetilde{b_{j}}-logX_{i,j})^2 J=i,j=1Vf(Xi,j)(wiTw j+bi+bj logXi,j)2

Glove论文:Pennington, J., Socher, R., & Manning, C. D. (2014, October). Glove: Global vectors for word representation. In Proceedings of the 2014 conference on empirical methods in natural language processing (EMNLP) (pp. 1532-1543).

# 在notebook中下载glove向量文件
!wget http://nlp.stanford.edu/data/glove.6B.zip
!unzip glove.6B.zip

# 使用方法
with codecd.open('glove.6B.100d.txt', 'r', 'utf-8') as f:
    for line in f.readlines():
        line = line.strip().split()
        if len(line) > 3:
            word, wvec = line[0], list(map(float, line[1:]))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Fasttext

Fasttext是一种高级词向量,它对Word2Vec中CBOW模型的进行了改进,具体的改进如下:

  1. CBOW中预测的是中心词,Fasttext预测的是标签
  2. 灵活地使用Hierarchical Softmax
  3. 采用N-Gram特征

使用方法如下,详情参考gensim官方文档

from gensim.models import fasttext
# 创建fasttext模型
# tokenized_corpus是单词转换为对应数字后的文本
# min_count是单词出现的最小频率
# size是词向量维度
model = fasttext.FastText(tokenized_corpus, min_count, size)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

用Hierarchical Softmax
3. 采用N-Gram特征

使用方法如下,详情参考gensim官方文档

from gensim.models import fasttext
# 创建fasttext模型
# tokenized_corpus是单词转换为对应数字后的文本
# min_count是单词出现的最小频率
# size是词向量维度
model = fasttext.FastText(tokenized_corpus, min_count, size)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/498247
推荐阅读
相关标签
  

闽ICP备14008679号