赞
踩
对文本进行完预处理后,接下来的重要任务就是将文本用向量化的形式进行表达。在本章节中,我们将尽量全面地覆盖文本向量化表示方法,重点关注Word2Vec以及目前各种常用的词向量。
首先,我们来看基于统计方法的向量化表示,包括One-Hot Encoding,,BOW,TF-IDF,矩阵分解
独热编码是比较容易想到的一种编码方式,但独热编码显然无法表示语义信息和词语之间的关系,而且独热编码矩阵是一个庞大并且稀疏的矩阵。
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
词袋模型是将句子中每一个词用其在句子中出现的次数来表示(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)
词频-逆文本频率是一种同统计方法,用于统计每个词对一份文件的重要程度。换言之,一个词在整个语料库中出现的次数越多,它的重要性越低(例如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)
TF−IDF(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)
首先介绍矩阵分解SVD。若矩阵 A m ∗ n A_{m*n} Am∗n满足 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=A−1)
对任意的矩阵
A
m
∗
n
A_{m*n}
Am∗n,都能被奇异值分解为:
A
=
U
(
∑
r
0
0
0
)
V
T
A=U(
其中 U U U是 m ∗ m m*m m∗m的正交矩阵, V V V是 n ∗ n n*n n∗n的正交矩阵, ∑ r \sum_{r} ∑r是由矩阵 A A A特征值从大到小排列成的方阵。
利用矩阵分解获得词向量:
我们定义一个 V ∗ V V*V V∗V的方阵 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组成的稀疏向量。因此,我们希望能够训练出一种分布式的、可以指定维度的稠密的词向量,并且希望这种词向量能够有效表示出单词之间的关系。
you shall know a word by the company it keeps(Harris, 1954; Firth, 1957)
分布式假设是说我们可以通过周围的词来预测当前词,基于这个假设,我们来研究Word2Vec两种著名的算法Skip-Gram和CBOW
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}] [wt−window_size,wt−window_size+1...wt−1]和 [ 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模型的细节如下:
下面,我们来详细地学习一下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(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)
我们将目标函数写成一般形式,即:
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:w∈text∏c∈context(w)∏p(c∣w;θ)
其中,
θ
\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(w∈text∑c∈context(w)∑logp(c∣w;θ))
其中,
p
(
c
∣
w
;
θ
)
p(c|w;\theta)
p(c∣w;θ)应该满足以下几条性质:
根据以上这几条性质,我们可以使用
s
o
f
t
m
a
x
softmax
softmax函数来计算
p
(
c
∣
w
;
θ
)
p(c|w;\theta)
p(c∣w;θ),即
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(c∣w;θ)=∑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(w∈text∑c∈context(w)∑(UcVwT−logc,∑exp(Uc,VwT)))
要优化这个函数,我们可以采用梯度下降法来求解。但是不难发现一个问题,就是每次在更新梯度的时候,我们都要在每层求和符号里计算
l
o
g
∑
c
,
e
x
p
(
U
c
,
V
w
)
log\sum_{c^{,}}exp(U_{c^{,}}V_{w})
log∑c,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) 。
我们将
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)∈D∏p(D=1∣w,c;θ)(w,c,)∈Dnoise∏p(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)∈D∑logσ(UcVw))+(w,c,)∈Dnoise∑logσ(−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)∈D∑logσ(UcVw))+k∗(w,c,)∈Dnoise∑logσ(−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))
∂Uc∂L=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})) ∂Vw∂L=Uc(1−σ(UcVw))−k∗(w,c,)∈Dnoise∑Uc,(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)
负样本的选取方式有以下三种:
Hierarchical Softmax是指层级Softmax,利用了霍夫曼树,鉴于这只是训练的小trick且较为复杂,在这里不做过多介绍。
CBOW和Skip-Gram的任务恰好相反,即根据上下文来预测中心词
具体细节与Skip-Gram类似,这里不再赘述
我们对两种Word2Vec模型做一个简单对比
Skip-Gram | CBOW | |
---|---|---|
模型输入 | 中心词 | 上下文 |
模型输出 | 上下文 | 中心词 |
复杂度 | 高 | 低 |
训练时间 | 长 | 短 |
训练效果 | 较好 | 稍差 |
生僻词和专有词训练效果 | 较好 | 稍差 |
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=1∑Vf(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:]))
Fasttext是一种高级词向量,它对Word2Vec中CBOW模型的进行了改进,具体的改进如下:
使用方法如下,详情参考gensim官方文档
from gensim.models import fasttext
# 创建fasttext模型
# tokenized_corpus是单词转换为对应数字后的文本
# min_count是单词出现的最小频率
# size是词向量维度
model = fasttext.FastText(tokenized_corpus, min_count, size)
用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)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。