推荐系统中的特征交叉

文章目录


DNN 时代已然到来, 号称拟合一切函数的 DNN 貌似带来了新的问题解决方式 — 数据, 模型, 学习. DNN 刚开始大行其道时, 其中一个显著的优点就是不用做过多的特征工程, 貌似要抢走工程师们挖掘特征的工作. 不过热潮过后, 特征工程再度进入人们视野, 特别是在某些领域 — 推荐搜索广告等.

为什么这几个领域如此重视特征工程呢? 愚见: 这些领域使用的通常是表格类型的, 大多是结构化或者半结构化的数据, 参与预测的实体 (如用户, 商品等) 都含有丰富的属性, 这些信息构建在 人与物之间的联系, 人的社会行为之上. 当然, 不可忽略搜推里的数据通常是稀疏且高维的. 总的来说, 其包含的规律信息是我们可预见的. 像 CV, NLP, Speech 等领域, 虽然大部分的信息也是以人类的行为为基础, 大多也是有迹可循的, 但是其中牵扯到很多的自然界中的信息, 如视觉, 语音这些本来就存在与自然界中的信息, 现在很多的工作可能更多地是去理解这些一直以来存在的信息的载体的本质.

那么现在的特征交叉的工作有哪些呢?

1. 人工构造

特征工程的重要性不言而喻, 早期工程师们根据自己对问题的理解, 人工挖掘特征, 找到对目标变量比较重要的特征组合, 将其与原始特征一齐输入到模型中. 这种方法在现在也还是蛮多见的, 例如 Wide&Deep, Youtube DNN 中都有人工构造特征的影子. 很显然, 这种方式依赖于对问题深刻的理解, 算是特征交叉里刀耕火种的阶段?

一些缺点: 1) 获得高质量的高阶特征的成本. 不同场景下高质量的特征是不一样的, 需要深厚的领域知识; 2) 特征过多, 难以手工构造; 3) 手工构造的特征泛化不足, 难以覆盖一些抽象的模式.

2. GBDT+LR

树模型对特征进行分裂的特性造就了其特征组合的能力, 来自 Facebook 的 GBDT+LR 则开启了这一潮流 (至少从公开发表上来看是这样的).

先看看树模型是怎么做特征组合的. 对于树中的每个结点, 树模型会选择最优的特征及分割点进行分裂, 迭代进行下去生成决策树 — 相当于对输入空间的一个划分. 从根节点道叶子节点的路径对应着一系列 if-else 组成的规则 — 即特征组合.

基于树模型做特征组合的方式也很简单: 每个样本输入到一棵树中可以得到一个 one-hot 向量, 这个向量既是该样本的一种特征组合方式, 可与原始特征一齐输入到预测模型中.

特点: 1) 可以在目标变量的指导下自动生成高阶的特征组合; 2) 显然, 生成组合特征需要监督信号; 3) 要调整树模型的参数.

3. FM

FM 算是自动做特征交叉的鼻祖? FM 能自动对任意两个特征做交叉:

∑ i = 1 n ∑ j = i + 1 n < v i , v j > x i x j \sum_{i=1}^n \sum_{j=i+1}^n <\boldsymbol{v}_i, \boldsymbol{v}_j> x_i x_j i=1nj=i+1n<vi,vj>xixj

FM 会为每个特征学习一个隐向量, 用隐向量的内积作为组合特征的重要性. 其特点: 1) 能够自动做二阶的特征交叉; 2) 隐向量也能一定程度降低数据稀疏性的影响; 3) 一般只支持两阶交叉, 做更高阶的特征交叉时间复杂度大大增加.

除了 FM, 还有一个 FFM, 算是 FM 的升级版吧, 在特征上再加了一层 Field (特征域) 的概念, 即每个特征都属于一个 field, 如 “科幻片”, “喜剧片” 都属于 “电影类型” 这个 field 中. FFM 也主要用来做二阶特征交叉, 也会为每个特征学习隐向量, 但是 FFM 为每个特征在每个域下学习一个隐向量. 如果有 f f f 个特征域, n n n 个特征, 那么隐向量的个数为 n ⋅ f n \cdot f nf. 其交叉的形式为:

∑ i = 1 n ∑ j = i + 1 n < v i , f j , v j , f i > x i x j \sum_{i=1}^n \sum_{j=i+1}^n <\boldsymbol{v}_{i, f_j}, \boldsymbol{v}_{j, f_i}> x_i x_j i=1nj=i+1n<vi,fj,vj,fi>xixj

很显然, 在使用 FFM 时需要按域来对特征进行分组, 对于类别特征, 其取值作为特征都属于同一个域, 对于连续特征则可以单独作为一个域.

FFM 的特点: 1) 其参数要远大于 FM, 时间复杂度也更高, 不能像 FM 那样进行化简 (关于 FFM 空间/时间的优化可以参考微博的双线性 FFM, Bi-FFM); 2) 引入了特征域的概念, 特征进行两两交叉时, 能够体现域之间的相关性, 当然这也需要更多的参数来学习.

相关资料: 深入FFM原理与实践.

其实到这里已经可以看到很多后续工作的影子了 — 为特征学习 Embedding.

4. DCN

DCN 及其升级版 DCN-V2 由 google 提出来的, 二者都属于泛 Wide&Deep 类的模型. 泛 Wide&Deep 类的模型主要变化在于 Wide 部分. DCN 提出了 Cross Network 作为其 wide 部分:

The Deep & Cross Network.

DCN 左边即为 Cross Network. DCN 中的输入由离散特征的 embedding 和 连续特征拼接得到, 然后分别输入到 wide 和 deep 部分, 我们重点关注 wide — Cross Network 部分. Cross Network 是由 Cross Layer 组成的, 第 l + 1 l+1 l+1 层 Cross Layer 的计算方式:

x l + 1 = x 0 x l T w l + b l + x l = f ( x l , w l , b l ) + x l x_{l+1} = x_0 x_l^T w_l + b_l + x_l = f(x_l, w_l, b_l) + x_l xl+1=x0xlTwl+bl+xl=f(xl,wl,bl)+xl

Cross Network 的第 l l l 层可以获得 1 至 l + 1 l+1 l+1 阶的特征交叉. 从 DCN 的输入可以看到, 离散特征被替换成了 embedding, 在进行交叉的时候实际是 embedding 的每一位 (及连续特征) 间进行交叉, 并不是以特征为粒度进行交叉的.

一些缺点: 1) CrossNet 的输出与输入之间存在某种特定形式的关系; 2) CrossNet 的输入是稀疏特征的嵌入, 是 bit-wise 方式的特征交叉, 交叉的含义不明显.

DCN-V2 对 DCN 进行了升级. 相比 DCN, DCN-V2 变化主要在 Cross Network. DCN-V2 中 cross layer 的计算方式:

x l + 1 = x 0 ⊙ ( W l x l + b l ) + x l \mathrm{x}_{l+1}=\mathrm{x}_0 \odot\left(W_l \mathrm{x}_l+\mathrm{b}_l\right)+\mathrm{x}_l xl+1=x0(Wlxl+bl)+xl

其中 ⊙ \odot 表示逐元素的乘积. 除了 cross layer 的变化, DCN-V2 中 wide 和 deep 部分的结合方式可以是串行的也可以是并行的. 并且为了降低计算开销, 对 cross layer 进行了优化: 将 W ∈ R d × d W \in \mathbb{R}^{d \times d} WRd×d 变成低秩 (low-rank, 一般认为低秩的矩阵中含有更多信息) 的. DCN-V2 中用两个细长的矩阵来表示 W = U V T ,   U , V ∈ R d × r , r < d 2 W = U V^T,\ U, V \in \mathbb{R}^{d \times r}, r < \frac{d}{2} W=UVT, U,VRd×r,r<2d. 因此新的 corss layer 计算方式为:

x l + 1 = x 0 ⊙ ( U l ( V l T x l ) + b l ) + x l x_{l+1} = x_0 \odot (U_l (V_l^T x_l) + b_l) + x_l xl+1=x0(Ul(VlTxl)+bl)+xl

文中对这种做法给出的一个解释: 在子空间中学习交叉. 因此文中将其与 MMOE 进行结合:

x l + 1 = ∑ i = 1 K G i ( x l ) E i ( x l ) + x l E i ( x l ) = x 0 ⊙ ( U l i ( V l i ⊤ x l ) + b l ) \begin{aligned} \mathrm{x}_{l+1} &=\sum_{i=1}^K G_i\left(\mathrm{x}_l\right) E_i\left(\mathrm{x}_l\right)+\mathrm{x}_l \\ E_i\left(\mathrm{x}_l\right) &=\mathrm{x}_0 \odot\left(U_l^i\left(V_l^{i \top} \mathrm{x}_l\right)+\mathrm{b}_l\right) \end{aligned} xl+1Ei(xl)=i=1KGi(xl)Ei(xl)+xl=x0(Uli(Vlixl)+bl)

DCN-V2 的特点: 1) 延续 DCN 的功能, 能以叠加层数的方式获得各阶的特征交叉 (bit-wise); 2) 还是 bit-wise 粒度的交叉, 不是特征粒度的交叉, 交叉的含义不明确; 3) 增加参数 cross network 的表达能力进行了增强, DCN 中 wide 部分的参数要远小于 deep 部分的参数.

5. xDeepFM

初看 xDeepFM (eXtreme Deep Factorization Machine) 感觉写的啥玩意儿, 写的那么复杂, 参数量也要比其他模型高很多, 虽然内心抗拒但还是秉持着完整的心态来写一些吧. xDeepFM 也是泛 Wide&Deep 类的模型, 相比其他方法, xDeepFM 做的是 vector-wise 的特征交叉, 其 wide 部分是 Compressed Interaction Network (CIN). 与其他模型的 wide 部分不同, CIN 的输入是一个矩阵 X k ∈ R H k × D \boldsymbol{X}^k \in \mathbb{R}^{H_k \times D} XkRHk×D, 输出也是一个矩阵, 矩阵每一行表示一个特征的表征, X k \boldsymbol{X}^k Xk 每一行表示的是一个 k + 1 k+1 k+1 阶的特征.

Components and architecture of the Compressed Interaction Network (CIN).

CIN 的计算方式如上图 所示, 公式如下 ( ∘ \circ 表示逐元素乘积):

X h , ∗ k = ∑ i = 1 H k − 1 ∑ j = 1 m W i j k , h ( X i , ∗ k − 1 ∘ X j , ∗ 0 ) \mathbf{X}_{h, *}^k=\sum_{i=1}^{H_{k-1}} \sum_{j=1}^m \mathbf{W}_{i j}^{k, h}\left(\mathbf{X}_{i, *}^{k-1} \circ \mathbf{X}_{j, *}^0\right) Xh,k=i=1Hk1j=1mWijk,h(Xi,k1Xj,0)

结合公式来理解一下 cin. 先通过 x k x^k xk x 0 x^0 x0 得到 z k + 1 z^{k+1} zk+1, cin(a) 中的外积, 但其实可以看作是 x k x^k xk 的每一行分别与 x 0 x^0 x0 的每一行进行逐元素乘积得到张量 z k + 1 ∈ R H k × m × D z^{k+1} \in \mathbb{R}^{H_k \times m \times D} zk+1RHk×m×D. 所以 z i , j , ∗ k + 1 z^{k+1}_{i,j,*} zi,j,k+1 表示一个 vector-wise 的交叉, 及 k + 1 k+1 k+1 阶的特征交叉. 因此 z k + 1 z^{k+1} zk+1 相当于 H k × m H_k \times m Hk×m k + 1 k+1 k+1 阶的交叉特征, 那这个张量怎么变成一个矩阵呢? 看 cin(b). 结合公式, x k + 1 x^{k+1} xk+1 的每一行是通过一个矩阵与 z k + 1 z^{k+1} zk+1 计算得到的. 虽然公式看起来复杂, 其实 x k + 1 x^{k+1} xk+1 的一行可以看作是 z k + 1 z^{k+1} zk+1 中所有 k + 1 k+1 k+1 阶特征的一个线性组合. 由于 CIN 的每一层输出的是 k k k 阶的交叉特征, 而不是 1 ∼ k 1 \sim k 1k 阶的交叉特征, 因此需要对 CIN 每层的输出按行进行 pooling, 即如 cin© 所示, 所有 CIN 层的输出按行进行 sum pooling 后进行拼接得到交叉特征.

需要注意: H k H_k Hk 是一个超参数, x k x^k xk 的每一行都是 k + 1 k+1 k+1 阶的交叉特征, 为什么不直接把 z k + 1 z^{k+1} zk+1 按前两个维度展开呢, 这样每个一行都是一个 k + 1 k+1 k+1 阶的交叉特征? 首先, 如果这样做, 那么 x k x^k xk 的维度就会一直是 m k + 1 × D m^{k+1} \times D mk+1×D, 这样就相当于一种完全的特征交叉. 显然, 随着层数的加深, 这参数是顶不住的. 因此 CIN 中使用 H k H_k Hk 个矩阵 W k , h W^{k, h} Wk,h 得到 H k H_k Hk k + 1 k+1 k+1 阶特征的组合, 起到 compress 的作用, 每个 W k , h W^{k, h} Wk,h 相当于一种不同的组合模型.

xDeepFM 的特点: 1) vector-wise 的特征交叉; 2) 参数量大大增加; 3) 每个特征的 embedding 的维度必须相同.

6. AutoInt

AutoInt (Automatic feature Interaction Learning) 也是一篇看起来很复杂的论文, AutoInt 不是泛 Wide&Deep 的结构. AutoInt 的目标是给定一个特征向量, 学习特征的低维表示, 其蕴含了高阶的交叉特征. AutoInt 的模型结构如图所示, 简言之: 通过 self-attention 学习每个特征的高阶表示. 所以重点就是 self-attention, 如果熟悉这个的话其实就已经知道 AutoInt 是怎么做的了.

Overview of AutoInt.

AutoInt 中为每个特征 (包括离散特征和连续特征) 学习一个表征. AutoInt 中使用的是多头自注意力 (Multi-head Self-Attention), 并且加了一个残差, head h h h 的计算方式:

α m , k ( h ) = exp ⁡ ( ψ ( h ) ( e m , e k ) ) ∑ l = 1 M exp ⁡ ( ψ ( h ) ( e m , e l ) ) ψ ( h ) ( e m , e k ) = ⟨ W Query  ( h ) e m , W Key  ( h ) e k ⟩ e ~ m ( h ) = ∑ k = 1 M α m , k ( h ) ( W Value  ( h ) e k ) \begin{gathered} \alpha_{\mathrm{m}, \mathbf{k}}^{(\mathrm{h})}=\frac{\exp (\psi^{(h)}\left(\mathbf{e}_{\mathrm{m}}, \mathbf{e}_{\mathbf{k}}\right))}{\sum_{l=1}^M \exp (\psi^{(h)}\left(\mathbf{e}_{\mathbf{m}}, \mathbf{e}_{\mathbf{l}}\right))} \\ \psi^{(h)}(\mathbf{e}_{\mathrm{m}}, \mathbf{e}_{\mathrm{k}})=\langle\mathbf{W}_{\text {Query }}^{(\mathbf{h})} \mathbf{e}_{\mathbf{m}}, \mathbf{W}_{\text {Key }}^{(\mathbf{h})} \mathbf{e}_{\mathbf{k}}\rangle \\ \widetilde{\mathbf{e}}_{\mathbf{m}}^{(\mathbf{h})}=\sum_{k=1}^M \alpha_{\mathrm{m}, \mathbf{k}}^{(\mathbf{h})}(\mathbf{W}_{\text {Value }}^{(\mathbf{h})} \mathbf{e}_{\mathbf{k}}) \end{gathered} αm,k(h)=l=1Mexp(ψ(h)(em,el))exp(ψ(h)(em,ek))ψ(h)(em,ek)=WQuery (h)em,WKey (h)eke m(h)=k=1Mαm,k(h)(WValue (h)ek)

e ~ m ( h ) \widetilde{\mathbf{e}}_{\mathbf{m}}^{(\mathbf{h})} e m(h) 就是特征 m m m 经过 head h h h 的输出, 将多个头的输出进行拼接即是特征 m m m 经过多头注意力的输出, 再加上残差即可 (残差是不可少的, 类似于 DCN 中的残差, 保证每一层的输出能够得到所有阶数的交叉特征). 注意到, 交叉的阶数随着层数指数增长, 因为自注意力层做特征交叉时是高阶特征与高阶特征交叉, 而不是高阶特征与原始特征交叉.

AutoInt 的特点: 1) 通过 self-attention 机制做特征交叉; 2) 交叉的阶数随层数指数增长; 3) 通过 attention 有更好的解释性(其他方法也可以通过类似的方式获得解释性?).

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值