特征工程

特征工程使用方案

特征工程 深度学习

original icon
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.knowledgedict.com/tutorial/feature_engineering-autodis.html

深度学习中连续特征 Embedding 的 AutoDis 方法详解


深度学习中连续特征值的 Embedding 方式主要有 field embedding 和离散分桶后 embedding 两种,AutoDis 2020年底,华为研究人员发表的新的连续特征 embedding 方式,它是直接通过端对端的训练,内部构造的局部网络的 embedding 方式。

背景

在 CTR 预估模型中,大多数模型都遵守 Embedding & Feature Interaction(FI)的范式。以往的大多数研究都聚焦于网络结构的设计,以更好的捕获显式或隐式的特征交互,如 Wide&Deep 的 wide 部分,DeepFM 的 FM 部分,DIN 的注意力机制。然而却忽视了特征 Embedding 的重要性,尤其是忽视了连续型特征 Embedding。尽管很多文章中没有怎么研究,但 Embedding 模块是 CTR 预估模型的重要组成部分,有以下两个原因:

  1. Embedding 模块是后续 FI 模块的基石,影响 FI 模块的效果。
  2. CTR 模型的中大多数参数都在 Embedding 模块,所以很自然对模型效果有很大影响。

但是 Embedding 模块少有深入研究的工作,特别是连续型特征 Embedding 的方面。

目前常见的连续特征处理可以概括为三种:No EmbeddingField EmbeddingDescretization。接下来将为大家一一介绍。

如下图所示,FI 的架构图:

Feature Interaction 架构图

No Embedding

No Embedding 顾名思义是直接使用原始值或者转换后的值作为输入特征,即不对连续特征进行 embedding 操作。

如 Google 发表的 Wide & Deep 模型使用了原始特征,京东发表的 DMT 模型则使用了归一化后的特征。

此外 YouTube DNN 使用了多种方法(平方,开根号等)对归一化特征 \(\widetilde{x}_{j}\) 进行转换,如下示例:

\(e_{Youtube} = [ \widetilde{x}_{1}^{2},\widetilde{x}_{1}, \sqrt{\widetilde{x}_{1}},\widetilde{x}_{2}^{2},\widetilde{x}_{2}, \sqrt{\widetilde{x}_{2}},...,\widetilde{x}_{N}^{2},\widetilde{x}_{N}, \sqrt{\widetilde{x}_{N}}]\)

其中,\(e_{Youtube} \in R^{3N}\)

在 Facebook 发表的 DLRM 模型中,该模型使用了 MLP(Multilayer Perceptron)对所有连续型特征建模:

\(e_{DLRM} = [ DNN([x_1,x_2,...,x_N])]\)

其中 DNN 的结构为 512 - 256 - d,所以 \(e_{DLRM} \in R^{d}\)

这类对连续特征不进行 embedding 的方法,由于模型容量有限,通常难以有效捕获连续特征中的信息。

Field Embedding

Field Embedding 的处理方法为一个域中的所有特征中共享一个 field embedding,计算时将 field embedding 乘以相应的特征值即可:

\(e_{FE} = [ x_1 * e_1,x_2 * e_2,...,x_N * e_N]\)

其中 \(e_j \in R^d\) 是 field embedding 用于第j个连续特征域 。\(e_{FE} \in R^{N \times d}\)。由于同一field的特征共享同一个embedding,并基于不同的取值对embedding进行缩放,这类方法的表达能力也是有限的。

Discretization

离散化(Discretization)方法将连续特征转换成类别特征。对于第j个数据域,其特征 embedding 通过两阶段(two-stage)方法获取:discretization(离散化) 和 embedding look-up(查表):

\(e_j = E_j * d_j(x_j)\)

其中 \(E_j \in R^{H_j \times d}\) 是第j个域的 Embedding 矩阵,\(H_j\) 表示分桶的个数。\(d_j(x_j)\) 是手工设计的函数,将第j个域的各个数值特征映射到其中一个桶中。

离散化主要有如下四种方法:

  1. 等距离散(Equal Distance Discretization,EDD,也叫做等宽分箱)按照等距离划分桶,按照最大最小值的 gap 进行等分,假设第一个数值域的取值范围为 \([x_{j}^{min},x_{j}^{max}]\),其间距为 \(w_j = (x_j^{max}-x_j^{min})/H_j\)。因此离散化后的特征值 \(\widetilde x_j\) 为:

    \(\widetilde{x}_j = d_j^{EDD}(x_j) = floor((x_j-x_j^{min})/w_j)\)

  2. 等频离散(Equal Frequencey Discretization,EFD,也有的叫做等深分箱)将 \([x_j^{max}-x_j^{min}]\) 划分为几个桶,每个桶中特征值数量相等。

  3. 对数离散化(Logarithm Discretization,LD)。具体操作如下:

    \(\widetilde{x}_j = d_j^{LD}(x_j) = floor(log(x_j)^2)\)

  4. 基于树模型的离散化(Tree-based Discretization)。除深度学习模型外,树模型(例如 GBDT)被广泛应用于搜索推荐领域。其能高效的处理数值型特征。

之前离散化的不足

尽管离散化在工业界广泛引用,但仍然有以下三方面的缺点:

  1. TPPTwo-Phase Problem):将特征分桶的过程一般使用启发式的规则(如 EDD、EFD)或者其他模型(如 GBDT),无法与 CTR 模型进行一起优化,即无法做到端到端训练。
  2. SBDSimilar value But Dis-similar embedding):对于边界值,两个相近的取值由于被分到了不同的桶中,导致其 embedding 可能相差很远。
  3. DBSDis-similar value But Same embedding):对于同一个桶中的边界值,两边的取值可能相差很远,但由于在同一桶中,其对应的 embedding 是相同的。

上述的三种局限可以通过下图进一步理解:

AutoDis 详解

为了解决现有方法的不足之处,提出了 AutoDis 框架,其能学习为每个特征值学习独一的表示以端到端的方式训练。下图展示了 AutoDis 可以作为一个可插拔的 Embedding 框架,用于数值型特征处理,并且兼容现有的 CTR 预估模型。

autodis 架构

AutoDis 架构

为了实现高模型容量、端到端训练,每个特征取值具有独立表示,AutoDis 设计了三个核心的模块,分别是 Meta-EmbeddingsAutomatic DiscretizationAggregation 模块。

\(e_j = f(d_j^{Auto}(x_j),ME_j)\)

  • 其中 \(ME_j\) 是第j个特征域的 meta-embedding 矩阵;
  • \(d_j^{Auto}(·)\) 是 automatic discretization 函数;
  • \(f(·)\) 是 aggregation 函数。

其结构如下图所示,最终将类比性特征和数值型特征的 embedding 进行连接输入到预估模型中去。

autodis 结构

Meta-Embeddings

一种朴素的方法是将连续特征中的每个特征值赋予一个独一的 embedding。但是这是不可行的,这将导致参数爆炸且对低频特征训练不足。

filed embedding 的做法为一个特征域的所有特征值共享一个 embedding,尽管它参数量较小,但由于其低模型容量影响了模型性能。

为了平衡模型容量和复杂度,对于第j个特征域,我们使用一组共享的 meta-embeddings 表达 \(ME_j \in R^{H_j×d}\)\(H_j\) 是 meta-embedding 的数量。每个 meta-embedding 可被视为隐空间的子空间可以提高表达能力。通过聚合这些 meta-embedding,最后得到的 embedding 相对于 field embedding 表达能力更强。\(H_j\) 是可调的。

Automatic Discretization

为了捕获连续特征值与 meta-embedding 的复杂关联,论文中设计了一个可微分的模块 automatic discretization \(d_j^{Auto}(·)\)\(d_j^{Auto}(·)\) 将第j个域中的特征值离散到 \(H_j\) 个桶中,每个桶对应一个 meta-embedding。

该模块主要使用了一个两层的神经网络,并使用了残差连接,将特征值 \(x_j\) 离散到 \(Hj\) 个桶中:

\(h_j = Leaky\_ReLU(w_jx_j)\)

\(\widetilde{x}_j =W_jh_j+αh_j\)

其中 \(w_j \in R^{1×H_j}\)\(w_j \in R^{H_j×H_j}\) 是可学习的参数,用于第j个数值域。α 用于控制残差连接。映射结果为 \(\widetilde{x}_j = [\widetilde{x}_j^1,\widetilde{x}_j^2,...,\widetilde{x}_j^{H_j}]\)。最后使用 SoftMax 进行归一化:

\(\widetilde{x}_j^h = \frac{e^{\frac{1}{τ}\widetilde{x}_j^h}}{\sum_{l=1}^{H_j}e^{\frac{1}{τ}\widetilde{x}_j^l}}\)

τ 为温度系数用于控制离散化后的分布。最后的结果为 \(\widehat{x}_j\)

\(\widehat{x}_j = d_j^{Auto}(x_j)=[\widetilde{x}_j^1,\widetilde{x}_j^2,...,\widetilde{x}_j^{H_j}]\)

其中 \(\widehat{x}_j^h\) 表示特征值 \(x_j\) 离散化到第h个桶中的概率,代表了特征值 \(x_j\) 与第h个 meta-embedding 的相关性。这种离散化方法可以被理解为 soft discretization。与 hard-discretization 相比,soft discretization 并不是将特征值离散到一个桶中,很好的解决了 SBD 和 DBS 问题。加之 AutoDis 是可微的,是模型可以进行端到端的训练,优化最终的目标。

对于温度系数 τ,当其区域无穷时,离散化概率分布区域均匀分布,当其解决0时,离散化概率分布区域 one-hot 分布。因此 τ 是一个很重要的系数。除此之外,不同域的特征分布不同。因此,论文中提出了温度系数自适应网络(temperature effcient adaptive network),将连续特征域的全局统计学特征和特征的具体取值进行综合考虑,同时将温度系数的计算过程与模型训练进行结合:

\(τ_{x_j} =Sigmoid(W_j^2Leaky\_ReLU(W_j^1[\overline{n}_j||x_j]))\)

其中 \(n_j\) 是第j个特征域的全局统计学特征向量。包括均值和累积概率分布的统计值(我理解的是累积概率为某个值如 0.1 或 0.2 时对应的连续特征取值),为了指导模型训练将 \(τ_{x_j}\) 的范围从 (0, 1) 调整为 (τ-ϵ)(τ+ϵ),τ 是全局超参数。

Aggregation Function

根据前两个模块,已经得到了每个分桶的 embedding,以及某个特征取值对应分桶的概率分布,接下来则是如何选择合适的 Aggregation Function 对二者进行聚合。论文提出了如下三种方案:

  1. Max-Pooling

    选择相关性最大的 meta-embedding,即概率最大的那个:

    \(e_j=ME_j^k,where\space k = arg\space max_{h\in{1,2,...,H_j}}\widehat{x}_j^h\)

    k 表示概率最大的那个 meta-embedding 索引,\(ME_j^k\) 是第k个 meta-embedding。然而这种 hard 选择策略会导致 AutoDis 退化成一个 hard discretization 方法,从而导致 SBD 和 DBS 问题。

  2. Top-K-Sum

    将概率最高的前K个 meta-embedding 加和:

    \(e_j = \sum_{l=1}^KME_j^{kl},where\space k_l=arg_l^{top}{h\in{1,2,...,H_j}}\widehat{x}_j^h\)

    这种方法有两个不足之处:(1)不能从根本上解决 DBS 问题(2)同时得到的最终 embedding 也没有考虑到具体的概率取值。

  3. Weighted-Average

    根据每个分桶的概率对分桶 embedding 进行加权求和,公式如下:

    \(e_j = \sum_{h=1}^{Hj}\widehat{x}_j^h·ME_j^h\)

    这种方式确保了每个不同的特征取值都能有其对应的 embedding 表示。同时,相近的特征取值往往得到的分桶概率分布也是相近的,那么其得到的 embedding 也是相近的,可以有效解决 SBD 和 DBS 的问题。

AutoDis 代码实现

tensorflow keras 代码实现

如下基于 tensorflow 2.x 的 keras api 实现的 autodis,可以直接拿过来直接使用,笔者线上实践版,开箱即用,具体代码如下:

import tensorflow as tf


class AutoDis(tf.keras.layers.Layer):
    """
        单个特征 AutoDis 处理网络层

    Args:
        h: 指定分桶数
        dim: embedding 维度
        a: 残差连接
        reg: 正则项系数
    """

    def __init__(self, h, dim, a=0.5, reg=1e-6):
        super(AutoDis, self).__init__()
        self.h = h
        self.dim = dim
        self.a = a
        self.meta_emb = self.add_weight(name='meta_emb', shape=(self.dim, self.h),
                                        initializer=tf.keras.initializers.RandomNormal(),
                                        regularizer=tf.keras.regularizers.L2(l2=reg), trainable=True)
        self.wj = self.add_weight(name='wj', shape=(1, self.h), initializer=tf.keras.initializers.RandomNormal(),
                                  regularizer=tf.keras.regularizers.L2(l2=reg), trainable=True)
        self.Wj = self.add_weight(name='Wj', shape=(self.h, self.h), initializer=tf.keras.initializers.RandomNormal(),
                                  regularizer=tf.keras.regularizers.L2(l2=reg), trainable=True)

    def _call_automatic_discretization(self, x):
        print(x.shape)
        #   x ==> (None, 1)
        hj = tf.nn.leaky_relu(tf.matmul(x, self.wj))  # (None, h)
        xj = tf.matmul(hj, self.Wj) + self.a * hj  # (None, h)
        return tf.nn.softmax(xj)  # (None, h)

    def _call_meta_embeddings(self, x):
        #   x ==> (None, 1)
        x = tf.tile(tf.reshape(x, [-1, 1, 1]), [1, self.dim, self.h])  # (None, dim, h)
        return self.meta_emb * x  # (None, dim, h)

    def call(self, inputs):
        #   inputs ==> (None, 1)
        xh = tf.expand_dims(self._call_automatic_discretization(inputs), axis=1)  # (None, 1, h)
        ME = self._call_meta_embeddings(inputs)  # (None, dim, h)
        return tf.reduce_sum(ME * xh, axis=-1)  # (None, dim)
Embedding的概念来自于wordembeddings,具体是2013年Google开源的一款用于词向量计算的工具——word2vec。 ...
深度学习(deep learning)是机器学习的分支,它是一种以人工神经网络为架构,对数据进行表征学习的算法。现在已有数种深度学习框架,如 ...
基础定义卷积层由一个或多个卷积核组成,每个卷积核实质上就是一个小的滤波器,其尺寸一般较小,如3x3或5x5。关键参数卷积层的一些关键参数:卷 ...
深度学习(deep learning)是机器学习的分支,是一种以人工神经网络为架构,对数据进行特征学习(表征学习)的算法。 ...
es ltr 里有特征仓库的概念,一个特征仓库其实就是一个 es 的索引,可以存储特征和模型的元数据。 ...