深入理解embedding

深入理解embedding

背景: 在广告系统中,ctr、cvr预估模型训练时通常将样本转换成embedding输入网络进行训练,得到最终的预估值。embedding被称为sparse model、大模型等,是模型训练和预估中极其重要的一环。但关于embedding的含义和使用对于非科班人士比较晦涩,在这里对embedding的引入、含义、应用作系统性的介绍。

分类数据 及表示方法

分类数据:从有限候选集中选择一个或多个离散项作为输入特征,如电影集、单词集

在分类数据的表示上,最直接的方法使用id唯一表示候选集中的项,但在训练的时候会带来维度的不统一,以电影集为例,对于不同用户观看过的电影数量不同,导致特征维度不同。一个有效的方法是稀疏向量表示,类似one hot 编码。(另一种说法是将每个稀疏向量表示为数字向量,以便语义上相似的项(电影或单词)在向量空间中具有相似的距离)

ont hot编码:将离散的分类变量转换为稀疏的二进制向量表示,以便更好地在机器学习模型中使用。One-Hot编码将每个分类变量的取值映射为一个只有一个元素为1,其余元素为0的向量。向量的长度等于分类变量的取值个数。对于给定的样本,如果它属于某个分类变量的某个取值,那么该取值对应的位置为1,其他位置为0。

但one hot编码及衍生的离散变量表示仍存在显著的缺点:one hot vector维度太大,以及不同向量之间的距离刻画问题。大型稀疏向量直接导致网络层的节点数巨大,这意味着训练需要的有效数据量也要非常大才行,另一方面训练时的运算量也会成倍增加。 而向量中相邻的两个值并不见得有相近的语义关系,无法表示特征之间的相似性。

Embedding引入

embedding可以很好解决上述分类数据表示的问题。embedding将大型离散向量转换到具有语义相似性的低维向量空间中,即将高维、稠密的向量映射到低维、连续的向量空间中。如大小为999的词汇集,映射到8维的embedding,维度直接少了两个数量级。在embedding中,语义不同的向量表示通常距离很远,这样同时解决了维度、语义两个问题。

embedding是一个矩阵,每列表示item的向量表示,要获取单个item的稠密向量,就检索对应的列。参照tensorflow中的tf.nn.embedding_lookup函数。

在推荐算法中,embedding的获取当做网络训练的一部分,这种方法可以为特定系统定制良好的embedding。

应用

以tensorflow中api的使用来说明分类数据到模型输入embedding的过程

tf.feature_column.categorical_column_with_vocabulary_list:用于创建分类特征列的方法。它用于将离散的分类特征转换为可以输入到 TensorFlow 模型中的特征列对象。

tf.feature_column.embedding_column:用于将分类特征转换为嵌入(embedding)向量

具体过程如下(来自于chatgpt):

  1. 索引化特征列(IndexedCategoricalColumn):首先,将分类特征列转换为索引化特征列。索引化特征列将原始的离散取值映射为整数索引,以便后续处理。这样可以将离散的分类特征转化为数值型的索引表示。
  2. 嵌入表查找(Embedding Table Lookup):在训练过程中,tf.feature_column.embedding_column 方法会创建一个嵌入表(embedding table),该表将每个离散取值映射为一个嵌入向量。嵌入表是一个可训练的参数,其维度由指定的嵌入维度决定。
  3. 嵌入向量提取(Embedding Vector Extraction):通过索引化特征列的取值在嵌入表中进行查找,得到相应的嵌入向量。每个索引对应于嵌入表中的一行,该行表示该索引对应的嵌入向量。
  4. 嵌入向量合并(Embedding Vector Aggregation):如果数据集中包含多个分类特征列,那么在最后的嵌入层中,这些嵌入向量将被合并为一个更大的嵌入向量或嵌入矩阵。这样可以将不同特征的嵌入向量进行组合,形成更丰富的特征表示。
import tensorflow as tf

# 定义数据集
data = {
    'gender': ['male', 'female', 'male', 'female', 'male'],
    'occupation': ['engineer', 'doctor', 'teacher', 'doctor', 'engineer']
}

# 创建分类特征列
gender_column = tf.feature_column.categorical_column_with_vocabulary_list(
    key='gender',
    vocabulary_list=['male', 'female']
)
occupation_column = tf.feature_column.categorical_column_with_vocabulary_list(
    key='occupation',
    vocabulary_list=['engineer', 'doctor', 'teacher']
)

# 创建嵌入特征列
embedded_gender_column = tf.feature_column.embedding_column(
    categorical_column=gender_column,
    dimension=3  # 指定嵌入维度
)
embedded_occupation_column = tf.feature_column.embedding_column(
    categorical_column=occupation_column,
    dimension=5  # 指定嵌入维度
)

# 将特征列转换为输入层
input_layer = tf.keras.layers.DenseFeatures([
    embedded_gender_column,
    embedded_occupation_column
])

# 构建模型,此处仅为示例
model = tf.keras.Sequential([
    input_layer,
    # 添加其他层...
])

# 编译和训练模型...

tf.feature_column.embedding_column 方法将离散特征 occupation 转换为嵌入特征。

嵌入表查找的过程可以简述如下:

  1. 首先,我们定义了一个嵌入矩阵,其中每一行对应一个离散特征的嵌入向量。在这个例子中,假设我们的嵌入矩阵是一个维度为 (4, 3) 的矩阵,表示有 4 个不同的职业('engineer''teacher''doctor''artist')和每个职业对应的 3 维嵌入向量。
  2. 当模型输入包含离散特征 occupation 时,我们可以使用 tf.nn.embedding_lookup 函数来进行嵌入表的查找。该函数接受两个参数:嵌入矩阵和要查找的索引。
  3. 对于每个样本中的 occupation 特征,我们将其整数索引作为输入传递给 tf.nn.embedding_lookup 函数。函数将会在嵌入矩阵中查找对应索引的嵌入向量。
  4. 最后,tf.nn.embedding_lookup 函数返回的是查找到的嵌入向量。这些嵌入向量可以作为模型的输入,用于表示离散特征的信息。
import tensorflow as tf

# 嵌入矩阵,维度为 (4, 3)
embedding_matrix = tf.Variable([[0.1, 0.2, 0.3],
                                [0.4, 0.5, 0.6],
                                [0.7, 0.8, 0.9],
                                [1.0, 1.1, 1.2]])

# 索引化特征列
occupation_column = tf.feature_column.categorical_column_with_vocabulary_list('occupation', vocabulary_list=['engineer', 'teacher', 'doctor', 'artist'])
indexed_occupation_column = tf.feature_column.indicator_column(occupation_column)

# 输入数据
inputs = {'occupation': [2, 0, 1]}  # 假设有 3 个样本

# 查找嵌入向量
embedded_occupation = tf.nn.embedding_lookup(embedding_matrix, indexed_occupation_column)
embedded_occupation = tf.keras.layers.Flatten()(embedded_occupation)  # 将嵌入向量展平

# 将嵌入向量作为模型的输入进行后续处理
# ...

# 在训练过程中,模型会根据损失函数对嵌入矩阵进行更新
# ...

refs:
深度学习中的embedding

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值