1. 简介
之前搞对话系统时接触了StarSpace (抛开事实不谈,首先这个名字就比Glove、Elmo、Transformer……来的有诗意),用于计算 Intent 和 Action 的关系,效果还不错,一查发现,原来师出名门,来自Facebook AI Research2017年底发表的经典论文《StarSpace: Embed All The Things!》,一种通用的神经嵌入模型,要 Embedding 一切,霸气十足。
当然面对不同的场景,没有万能算法,推荐StaSpace也是希望各位在遇到Embeding问题时,除了Word2Vec、Node2Vec、Bert等算法外,能够多一种选择。
2. 要解决的问题
论文开篇也是毫不掩饰,直入主题。既然要 Embedding 万物,那凡是需要 Embedding 的任务,以下任务StarSpace都可以胜任:
- 文本分类或其他标签任务,例如:情绪分类
- 实体排序,例如:给出查询的web排名
- 基于协同过滤的推荐,例如:推荐文本,音乐或视频
- 基于内容的推荐,内容由离散特征定义,例如:文档中的词语
- 嵌入图表,例如:Freebase(可以理解成三元组构成的知识图谱数据库)这样的多关系图
- 学习词、句或文档的嵌入
在每种情况下,模型都是通过嵌入由离散特征组成的实体并相互比较,根据任务类型来学习它们之间的相似性。StarSpace可以被视为一种直接且高效的 strong baseline,和Word2Vec、Glove、fasttext等相比毫不逊色,甚至优于它们,当然最大的特点还是通用,把各种各样的数据投射到向量空间中,包括但不限于:文本、文章、主题、标签、知识图谱等。
口说无凭,作者在①文本分类②知识库关系预测③文档推荐④文章检索⑤句子匹配⑥学习句子向量6个不同任务上做了对比实验,评估算法的质量。
3. 模型原理
论文的目标是获得实体(entities)的embedding,而实体是一个很泛泛的概念,一个词、一句话、一个节点、一个用户……都可以成为一个实体,可以用稀疏向量(one-hot)来表示:
- 实体是一个词时,稀疏向量只有一个元素为1,其它都为0,向量的长度为词表的大小
- 实体是一个句子时,稀疏向量就是词袋向量,句子出现过的token所在的元素为1,其它为0,向量的长度同样为词表的大小
- 实体是一个用userID表示的用户时,稀疏向量是one-hot向量,如第一个用户,这个向量的第一个元素为1,其它都为0,向量的长度为用户数
- 实体是一个 {用用户喜欢的电影} 来表示的用户,如某个用户喜欢电影1、电影3,则向量的第一个元素和第三个元素为1,其它元素为0,此时向量的长度为电影数
以上稀疏向量转化为dense embedding就很简单了,把稀疏向量乘以一个 词典大小 embedding维度 的矩阵即可。
StarSpace可以很自由的去比较不同类型的实体。
F
为
包
含
D
个
特
征
的
字
典
,
表
示
为
D
×
d
的
矩
阵
,
则
F
i
为
第
i
个
特
征
生
成
的
d
维
e
m
b
e
d
d
i
n
g
,
那
么
实
体
a
的
e
m
b
e
d
d
i
n
g
为
∑
i
∈
D
F
i
,
即
每
个
f
e
a
t
u
r
e
都
有
一
个
嵌
入
,
由
于
一
个
实
体
a
具
有
不
同
的
f
e
a
t
u
r
e
,
所
以
构
成
实
体
a
的
嵌
入
就
是
这
些
特
征
的
加
和
(
或
加
权
和
)
(
和
w
o
r
d
2
v
e
c
之
后
进
行
s
e
n
t
e
n
c
e
e
m
b
e
d
d
i
n
g
是
一
样
的
)
。
也
就
是
说
,
与
其
他
嵌
入
模
型
一
样
,
首
先
要
给
打
算
e
m
b
e
d
d
i
n
g
的
集
合
中
(
论
文
称
为
字
典
,
包
含
诸
如
单
词
等
特
征
)
每
个
离
散
特
征
分
配
一
个
d
维
向
量
。
实
体
由
字
典
中
的
特
征
包
表
示
,
它
们
的
嵌
入
是
隐
式
学
习
的
,
一
个
实
体
也
可
以
由
单
个
(
唯
一
)
属
性
构
成
,
例
如
单
个
单
词
、
名
称
、
用
户
或
项
目
I
D
。
为
了
训
练
模
型
,
需
要
比
较
实
体
的
距
离
,
也
就
是
最
小
化
一
下
损
失
函
数
:
\small F为包含D个特征的字典,表示为D \times d的矩阵,则F_i为第i个特征生成的d维\\ embedding, 那么实体a的embedding为\sum_{i\in D}F_i ,即每个feature都有一个嵌入,\\由于一个实体a具有不同的feature,所以构成实体a的嵌入就是这些特征的加和\\(或加权和)(和word2vec之后进行 \,sentence\,embedding\,是一样的)。也就是说,\\与其他嵌入模型一样,首先要给打算embedding的集合中(论文称为字典,包含\\诸如单词等特征) 每个离散特征分配一个d维向量。实体由字典中的特征包表示,\\它们的嵌入是隐式学习的,一个实体也可以由 单个(唯一)属性构成,例如单个\\单词、名称、用户或项目ID。为了训练模型,需要比较实体的距离,也就是最小化\\一下损失函数:
F为包含D个特征的字典,表示为D×d的矩阵,则Fi为第i个特征生成的d维embedding,那么实体a的embedding为∑i∈DFi,即每个feature都有一个嵌入,由于一个实体a具有不同的feature,所以构成实体a的嵌入就是这些特征的加和(或加权和)(和word2vec之后进行sentenceembedding是一样的)。也就是说,与其他嵌入模型一样,首先要给打算embedding的集合中(论文称为字典,包含诸如单词等特征)每个离散特征分配一个d维向量。实体由字典中的特征包表示,它们的嵌入是隐式学习的,一个实体也可以由单个(唯一)属性构成,例如单个单词、名称、用户或项目ID。为了训练模型,需要比较实体的距离,也就是最小化一下损失函数:
∑
(
a
,
b
)
∈
E
+
,
b
−
∈
E
−
L
b
a
t
c
h
(
s
i
m
(
a
,
b
)
,
s
i
m
(
a
,
b
1
−
)
,
.
.
.
,
s
i
m
(
a
,
b
k
−
)
)
\small \sum_{(a,b)\in E^+,b^-\in E^-}L^{batch}(sim(a,b),sim(a,b^-_1),...,sim(a,b^-_k))
(a,b)∈E+,b−∈E−∑Lbatch(sim(a,b),sim(a,b1−),...,sim(a,bk−))
∙
正
实
体
对
(
a
,
b
)
来
自
E
+
∙
负
实
体
b
i
−
来
自
E
−
,
通
过
负
采
样
每
次
从
b
a
t
c
h
中
选
k
个
负
实
体
对
∙
相
似
度
函
数
s
i
m
(
,
)
可
以
选
择
余
弦
或
内
积
∙
损
失
函
数
也
提
供
了
两
种
方
式
:
m
a
r
g
i
n
r
a
n
k
i
n
g
l
o
s
s
和
n
e
g
t
i
v
e
l
o
g
l
o
s
s
o
f
s
o
f
t
m
a
x
,
通
常
前
者
表
现
更
好
\scriptsize \bullet正实体对(a,b)来自E^+ \\ \bullet 负实体b^-_i来自E^-,通过负采样每次从batch中选k个负实体对\\ \bullet 相似度函数sim(,)可以选择余弦或内积 \\ \bullet损失函数也提供了两种方式:margin\,ranking\,loss和negtive\,log\,loss\,of\,softmax,通常前者表现更好
∙正实体对(a,b)来自E+∙负实体bi−来自E−,通过负采样每次从batch中选k个负实体对∙相似度函数sim(,)可以选择余弦或内积∙损失函数也提供了两种方式:marginrankingloss和negtiveloglossofsoftmax,通常前者表现更好
4. 模型结构
从上一节可以看出,starspace的前向传播还是很简单的,就是两个embedding层。下面来看一看StarSpace具体是怎么做的。
举个🌰:
老板让我们把商品评论向量化,实现可以给用户评论打标签的功能。我们找了一些数据,并自己打了标签,di表示评论,li表示标签:
①用共现矩阵来展示的话:
②将其他评论和标签的关系也加入其中:可以看出,d2和d5都有l1、l3,d1也有l1,但是没有l3,所以我们希望模型学习的过程中,d2和d5的向量离l3越来越近,而d1距离l3越来越远。这样就形成了一个个簇,像星座群一样(是不是有StarSpace那味了)。
③用 bag-of-words 把d1表示成[0,0,1,0,1,0] ,用 one-hot 来表示标签,把l1表示为[0,0,0,0,0,1] ,则通过下面的结构,把这两者给关联起来:④上图中希望d1评论的向量能够和l1标签比较的接近,为了能够向量能够进行计算,需要维度统一,由于sparse不同,所以要在输入和 dense layer 中间增加一个 feed forward 层来让维度统一。LABEL 就是共现矩阵中的关系。
⑤上面只是 positive example,negative example 则要进行 k-negative sampling。共现矩阵中未打✅的就是负样本。
以上就是StarSpace的整体结构:
- 两个embedding层,一个embedding层用于embedding a,一个embedding层用于embedding b;
- 两个embedding层的输出(对于多特征的实体,每个embedding层后还有sum)在共同进入一个相似度计算模块,similarity(a,b)的计算结果 c;
- c 进入损失函数进行计算反向传播,以负采样来说,就是通过负采样构造了1个真实伪正类和k个假的伪负类,然后使用损失函数。
5. 应用
StarSpace 的实战应用支持多种模式,无监督、有监督、单标签、多标签的都有。虽然Meta官方版本是用C++实现的,但是好在项目中提供了 python wrapper,可以方便我们在 python 的项目中使用。
我们可以通过调整 trainMode 和 trainFile 的格式来让 StarSpace 完成不同类型的任务。
下面看一下在文本分类任务的表现: