实体嵌入
英文是Entity Embedding。我们希望深度学习能够处理结构化数据。在处理类别特征时,常用办法包括独热编码、顺序编码等。在NLP任务处理中,词和文章的表示都得益于嵌入。我们同样可以将这个思想在结构化数据领域加以运用。
原理
假设
N
N
N表示分箱的数量,
M
M
M表示嵌入的维度,
B
B
B表示训练时候的批量尺寸。我们用
x
∈
R
B
∗
1
x \in R^{B*1}
x∈RB∗1代表输入数据,
E
∈
R
N
∗
M
E \in R^{N*M}
E∈RN∗M表示嵌入矩阵,
c
∈
R
N
∗
1
c \in R^{N*1}
c∈RN∗1表示分箱的向量中心。我们的权重。下标中
i
i
i表示数据的序号,
j
j
j表示分箱的序号。
W
i
j
=
s
o
f
t
m
a
x
(
1
∣
x
i
−
c
j
∣
+
ϵ
)
W_{ij} = softmax(\frac 1 {|x_i - c_j| + \epsilon})
Wij=softmax(∣xi−cj∣+ϵ1)
我们最后生成的嵌入矩阵可以表示为
V
∈
R
B
∗
N
V \in R^{B*N}
V∈RB∗N。
V
i
=
∑
j
=
1
N
W
i
j
E
j
V
=
W
E
V_i = \sum_{j=1}^N W_{ij} E_j \\\\ V = WE
Vi=j=1∑NWijEjV=WE
代码实现
我们借助pytorch构建实体嵌入层。
import torch
import torch.nn as nn
import torch.nn.functional as F
class EntityEmbeddingLayer(nn.Module):
def __init__(self, num_level, emdedding_dim, centroid):
super(EntityEmbeddingLayer, self).__init__()
self.embedding = nn.Embedding(num_level, embedding_dim)
self.centroid = torch.tensor(centroid).detach_().unsqueeze(1)
def forward(self, x):
"""
x: size of (batch_size, 1)
"""
eps = 1e-7
x = x.unsqueeze(1)
d = 1.0/((x-self.centroid).abs()+eps)
w = F.softmax(d.squeeze(2), 1)
v = torch.mm(w, self.embedding.weight)
return v
适用场景
深度学习处理结构化数据。
优点
- 嵌入向量稠密,非稀疏
- 容易计算类别距离
- 方便可视化
缺点
- 暂无
Reference
- NLP实战高手课,第三章,王然,极客时间