挖掘高质量的交互特征需要非常专业的领域知识并且需要做大量尝试,耗费时间和精力。
在大型推荐系统中,原生特征非常庞大,手动挖掘交叉特征几乎不可能。
挖掘不出肉眼不可见的交叉特征。
FM模型:提取隐向量然后做内积的形式来提取交叉特征,扩展的FM模型更是可以提取随机的高维特征(DeepFM),缺点:会学习所有交叉特征,其中肯定会包含无用的交叉组合,这些组合会引入噪音降低模型的表现。(前期的特征选择很重要)
针对FM、FFM模型的缺点,随后又出现了几种针对改进的模型:
FFM 算法按照 field 对 latent vector 进行区分,从而提升模型的效果。但是 FFM 算法没有区分不同特征交叉的重要性,此模型针对不同特征交叉赋予不同的权重,从而达到更精细的计算交叉特征的目的。
y ( x ) : = w 0 + ∑ i = 1 n x i w i + ∑ i = 1 n ∑ j = i + 1 n < v i , v j > x i x j r F ( i ) , F ( j ) \mathrm{y}(\mathbf{x}):=w_{0}+\sum_{i=1}^{n} x_{i} w_{i}+\sum_{i=1}^{n} \sum_{j=i+1}^{n}<\mathbf{v}_{i}, \mathbf{v}_{j}>x_{i} x_{j} r_{\mathrm{F}(i), \mathrm{F}(j)} y(x):=w0+i=1∑nxiwi+i=1∑nj=i+1∑n<vi,vj>xixjrF(i),F(j)
其中, r F ( i ) , F ( j ) r_{F(i),F(j)} rF(i),F(j) 表示 field F ( i ) , F ( j ) F(i), F(j) F(i),F(j)交叉特征的重要性。
AFM 和 FwFM 类似,目标是希望对不同交叉特征采用不同的权重,从而减少引入噪声提升模型的性能。
如图所示,AFM在embedding后,先让 f 个field的特征做了bit-wise product后,得到 f × ( f − 1 ) / 2 f \times (f-1)/2 f×(f−1)/2 交叉项,然后AFM 引入了一个attention net,认为这些交叉特征项对每个结果贡献是不同的,例如 x i , x j x_i, x_j xi,xj 的权重重要度,用 a i j a_{ij} aij 来表示。从这个角度来看,其实 AFM 就是个加权累加的过程。
a i j ′ = h T ReL U ( w ( v i ⊙ v j ) x i x j + b ) a_{i j}^{\prime}=\mathbf{h}^{\mathrm{T}} \operatorname{ReL} \mathrm{U}\left(\mathbf{w}\left(\mathbf{v}_{i} \odot \mathbf{v}_{j}\right) x_{i} x_{j}+\mathbf{b}\right) aij′=hTReLU(w(vi⊙vj)xixj+b)
a i j = exp ( a i j ′ ) ∑ ( i , j ) ∈ ℜ x exp ( a i j ′ ) a_{i j}=\frac{\exp \left(a_{i j}^{\prime}\right)}{\sum_{(i, j) \in \Re x} \exp \left(a_{i j}^{\prime}\right)} aij=∑(i,j)∈ℜxexp(aij′)exp(aij′)
先计算伪权重,再进行归一化为真权重。
y ( x ) = w 0 + ∑ i = 1 n x i w i + p T ∑ i = 1 n ∑ j = i + 1 n a i j ( v i ⊙ v j ) x i x j y(x)=w_{0}+\sum_{i=1}^{n} x_{i} w_{i}+\mathbf{p}^{\mathrm{T}} \sum_{i=1}^{n} \sum_{j=i+1}^{n} a_{i j}\left(\mathbf{v}_{i} \odot \mathbf{v}_{j}\right) x_{i} x_{j} y(x)=w0+i=1∑nxiwi+pTi=1∑nj=i+1∑naij(vi⊙vj)xixj
其中,h,w,p,b为模型参数。
以上均为低阶特征交互模型,并不能实现高阶的特征交互!
FNN 层用 FM 初始化,即 FM 模型作为 pre-training,得到每个特征对应一个偏置项 w i w_i wi 和一个 k 维向量 v i v_i vi。然后参数向量随着训练不断学习调整。优势自然就是 FNN 训练开销低,可以更快达到收敛(初始化 embedding 为 FM 模型的 pre-training)
z i = W 0 i ⋅ x [ start i : end i ] = ( w i , v i 1 , v i 2 , … , v i K ) z_{i}=\mathbf{W}_{0}^{i} \cdot x\left[\text {start}_{i}: \text { end }_{i}\right]=\left(w_{i}, v_{i}^{1}, v_{i}^{2}, \ldots, v_{i}^{K}\right) zi=W0i⋅x[starti: end i]=(wi,vi1,vi2,…,viK)
I 1 = tanh ( W 1 z + b 1 ) \mathbf{I}_{1}=\tanh \left(\mathbf{W}_{1} \mathbf{z}+\mathbf{b}_{1}\right) I1=tanh(W1z+b1)
I 2 = tanh ( W 2 I 1 + b 2 ) \mathrm{I}_{2}=\tanh \left(\mathbf{W}_{2} \mathbf{I}_{1}+\mathbf{b}_{2}\right) I2=tanh(W2I1+b2)
y ^ = sigmoid ( W 3 I 2 + b 3 ) \hat{y}=\operatorname{sigmoid}\left(\mathbf{W}_{3} \mathbf{I}_{2}+\mathbf{b}_{3}\right) y^=sigmoid(W3I2+b3)
损失函数(最小交叉熵)为:
L ( y , y ^ ) = − y log y ^ − ( 1 − y ) log ( 1 − y ^ ) L(y, \hat{y})=-y \log \hat{y}-(1-y) \log (1-\hat{y}) L(y,y^)=−ylogy^−(1−y)log(1−y^)
FNN 实际上是对特征 embedding 之后进行 concatenate,再接 MLP,虽然使用激活函数(tanh)增加非线性,实际上是对特征进行了加权组合,PNN 与 FNN 区别在于 PNN 中间多了一层 Product Layer 层。其中 z 为embedding 层的线性部分,p 为 embedding 层的特征交叉部分,其他与 FNN 算法结构相同。
l z = ( l z 1 , l z 2 , … , l z n … , l z D 1 ) , l z n = W z n ⊙ z l p = ( l p 1 , l p 2 , … , l p n … , l p D 1 ) , l p n = W p n ⊙ p l 1 = r e l u ( l z + l p + b 1 ) ; l 2 = r e l u ( W 2 l 1 + b 2 ) y ~ = σ ( W 3 l 2 + b 3 ) \begin{aligned} l_{z} &=\left(l_{z}^{1}, l_{z}^{2}, \ldots, l_{z}^{n} \ldots, l_{z}^{D_{1}}\right), l_{z}^{n}=W_{z}^{n} \odot z \\ l_{p} &=\left(l_{p}^{1}, l_{p}^{2}, \ldots, l_{p}^{n} \ldots, l_{p}^{D_{1}}\right), l_{p}^{n}=W_{p}^{n} \odot p \\ l_{1} &=r e l u\left(l_{z}+l_{p}+b_{1}\right) ; l_{2}=r e l u\left(W_{2} l_{1}+b_{2}\right) \\ \tilde{y} &=\sigma\left(W_{3} l_{2}+b_{3}\right) \end{aligned} lzlpl1y~=(lz1,lz2,…,lzn…,lzD1),lzn=Wzn⊙z=(lp1,lp2,…,lpn…,lpD1),lpn=Wpn⊙p=relu(lz+lp+b1);l2=relu(W2l1+b2)=σ(W3l2+b3)
product layer 分为两部分,其中 z 代表线性信号向量,而 p 代表二次信号向量;
Inner Product-based Neural Network:
g ( f i , f j ) = < f i , f j > g\left(f_{i}, f_{j}\right)=
Outer Product-based Neural Network
g ( f i , f j ) = f i f j T g\left(f_{i}, f_{j}\right)=f_{i} f_{j}^{T} g(fi,fj)=fifjT,矩阵乘法表示特征交叉,类似于“和”的关系。
FNN 和 PNN 缺点都是忽略了低维交叉特征,Wide&Deep 和 DeepFM 模型通过混合架构解决了这个问题,但是同样存在缺点:
Bit-wise VS vector-wise
假设隐向量的维度为3维,如果两个特征(对应的向量分别为 (a1,b1,c1) 和 (a2,b2,c2) 的话)在进行交互时,交互的形式类似于 f(w1 * a1 * a2,w2 * b1 * b2 ,w3 * c1 * c2) 的话,此时我们认为特征交互是发生在元素级(bit-wise)上。如果特征交互形式类似于 f(w * (a1 * a2 ,b1 * b2,c1 * c2))的话,那么我们认为特征交互是发生在特征向量级(vector-wise)。
Explicitly VS implicitly
显式的特征交互和隐式的特征交互。以两个特征为例 x i x_i xi和 x j x_j xj,在经过一系列变换后,我们可以表示成 w i j ∗ ( x i ∗ x j ) w_{ij} * (x_i * x_j) wij∗(xi∗xj) 的形式,就可以认为是显式特征交互,否则的话,是隐式的特征交互。
在推荐系统中,输入的原始特征稀疏,维数大,没有明显的时空相关性,在原始特征输入上应用embedding层,将其压缩为低维、密集的实值向量。
输入的每个 feature 长度可能不同,但是经过 embedding layer,维数均保持为k。
FNN、Deep Crossing 以及 Wide&Deep 的深层部分利用 field embedding e 上的前馈神经网络来学习高阶特征交互,
x 1 = σ ( W ( 1 ) e + b 1 ) \mathbf{x}^{1}=\sigma\left(\mathbf{W}^{(1)} \mathbf{e}+\mathbf{b}^{1}\right) x1=σ(W(1)e+b1)
x k = σ ( W ( k ) x ( k − 1 ) + b k ) \mathbf{x}^{k}=\sigma\left(\mathbf{W}^{(k)} \mathbf{x}^{(k-1)}+\mathbf{b}^{k}\right) xk=σ(W(k)x(k−1)+bk)
PNN 和 DeepFM 除了在嵌入向量 e 应用 DNN 外,还引入了双向交互层(FM),PNN 和 DeepFM 之间的主要区别在于:PNN 将 product layer 的输出连接到 DNN,而 DeepFM 将 FM 层直接连接到输出单元。(一个是串联一个是并联)之所以称为隐式的高阶交互,是因为这两个模型得到 DNN 部分并不能推断出具体学到了多少阶的交叉特征。
Cross-Network 的目标在于明确地模拟高阶特征交互。与传统的全连接网络不同,隐藏层通过以下交叉操作计算:
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\left(x_{l}, w_{l}, b_{l}\right)+x_{l} xl+1=x0xlTwl+bl+xl=f(xl,wl,bl)+xl
deep layer: h l + 1 = f ( w l h l + b l ) h_{l+1}=f\left(w_{l} h_{l}+b_{l}\right) hl+1=f(wlhl+bl), f ( ⋅ ) f(\cdot) f(⋅) 为 relu 激活函数。
combination output layer: p = σ ( [ x L T , h L 2 T ] W l o g i t s ) p=\sigma\left(\left[x_{L}^{T}, h_{L_{2}}^{T}\right] W_{l o g i t s}\right) p=σ([xLT,hL2T]Wlogits),将经过 cross layer 的输出 x 和经过 deep layer 的输出 h 进行 concat 得到最终的特征向量。 σ \sigma σ 为 sigmoid 函数。
缺点:(1)Cross-Network的输出以特殊形式限制,每个隐藏层是 x 0 x_0 x0 标量的倍数;(2)特征交互以 bit-wise 方式进行。
对于 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\left(x_{l}, w_{l}, b_{l}\right)+x_{l} xl+1=x0xlTwl+bl+xl=f(xl,wl,bl)+xl ,去掉偏置项 b l b_l bl 以后有:
x i + 1 = x 0 x i T w i + 1 + x i = x 0 ( ( α i x 0 ) T w i + 1 ) + α i x 0 = α i + 1 x 0 x_{i+1}=x_{0} x_{i}^{T} w_{i+1}+x_{i}=x_{0}\left(\left(\alpha^{i} x_{0}\right)^{T} w_{i+1}\right)+\alpha^{i} x_{0}=\alpha^{i+1} x_{0} xi+1=x0xiTwi+1+xi=x0((αix0)Twi+1)+αix0=αi+1x0
α \alpha α 是一个标量,多层之后 x i + 1 x_{i+1} xi+1 仍是 x 0 x_0 x0 与表里的乘积,特征交叉只是 bit-wise 级。
相互作用在 vector-wise 层面,而不是在 bit-wise 上;
显式度量高阶特征相互作用;
网络的复杂性不会随着交互程度指数级增长;
xDeepFM设计动机:DCN 的Cross层接在Embedding层之后,虽然可以显示自动构造高阶特征,但它是以bit-wise的方式。例如,Age Field对应嵌入向量
,Occupation Field对应嵌入向量 ,在Cross层,a1,b1,c1,a2,b2,c2会拼接后直接作为输入,即它意识不到Field vector的概念。Cross 以嵌入向量中的单个bit为最细粒度,而FM是以向量为最细粒度学习相关性,即vector-wise。xDeepFM的动机,正是将FM的vector-wise的思想引入Cross部分。
xDeepFM的vector wise级别特征交叉主要体现在 (b)–© 的转化过程,首先将隐层矢量取出 x k x^k xk 与 初始矢量 x 0 x^0 x0 外积得到矩阵,对应图(a)操作,其中 D 是 embedding 矢量长度,这样得到的三维矩阵,以 D 维度做切片的话,各面表示中间结果 x k x^k xk 和 x 0 x^0 x0 组成的矩阵;到 (b) 中,利用 CNN 做卷积操作(卷积核同 D 维度切片一样),得到长度为 D 的向量,结合CNN具体操作,即卷积核系数与切面乘积和,各切面的加权和对应D维向量上的一个值,到 © 之后沿着embedding 维度 D 进行 sum pooling,对应得到一个vector wise级别的特征交叉,对 © 中图像,进行 sum pooling 时,各切面维度 H k H_k Hk 应该是不定的,对应 CNN 卷积核数目。综上,沿着 D 维度进行 sum pooling,得到的是中间结果 x k x^k xk 和 x 0 x^0 x0 的一次vector wise 级别特征交叉。
如 (a) 所示,根据原始特征矩阵 x 0 ( H k × D ) x_{0}\left(H_{k} \times D\right) x0(Hk×D) 和前一层的输出 x k ( m × D ) x^{k}(m \times D) xk(m×D),得到中间结果 z k + 1 ( H k × m × D ) z^{k+1}\left(H_{k} \times m \times D\right) zk+1(Hk×m×D);
图 (b) 为 feature map 过程,生成的中间结果 z k + 1 z^{k+1} zk+1 ,利用 H k + 1 H_{k+1} Hk+1 个尺寸大小为 m × H k m \times H_k m×Hk 的卷积核得到下一层的隐层状态。具体的卷积计算细节与 CNN 不同,CIN 中一个神经元相关的接受域是垂直于特征维度 D 的整个平面,而 CNN 中的接受域是当前神经元周围的局部小范围,因此 CIN 经过卷积操作得到的特征图是一个向量,而不是一个矩阵。
X h , ∗ k = ∑ i = 1 H k − 1 ∑ j = 1 m W i j k , h ( X i , ∗ k − 1 ⋅ X j , ∗ 0 ) X_{h, *}^{k}=\sum_{i=1}^{H_{k-1}} \sum_{j=1}^{m} W_{i j}^{k, h}\left(X_{i, *}^{k-1} \cdot X_{j, *}^{0}\right) Xh,∗k=i=1∑Hk−1j=1∑mWijk,h(Xi,∗k−1⋅Xj,∗0)
w w w 类似于 CNN 中的 filter, X h , ∗ k X_{h, *}^{k} Xh,∗k 就是一个 feature map。
p i k = ∑ j − 1 D X i , j k p_{i}^{k}=\sum_{j-1}^{D} X_{i, j}^{k} pik=∑j−1DXi,jk ,其中, i ∈ [ 1 , H k ] i \in\left[1, H_{k}\right] i∈[1,Hk],这样得到一个pooling vector: p k = [ p 1 k , p 2 k , … , p H k k ] p^{k}=\left[p_{1}^{k}, p_{2}^{k}, \ldots, p_{H_{k}}^{k}\right] pk=[p1k,p2k,…,pHkk] , p + = [ p 1 , p 2 , … , p T ] p^{+}=\left[p^{1}, p^{2}, \ldots, p^{T}\right] p+=[p1,p2,…,pT],T 表示网络的深度。
y ~ = σ ( w linear T a + w d n n T x d n n K + w c i n T p + + b ) \tilde{y}=\sigma\left(w_{\text {linear}}^{T} a+w_{d n n}^{T} x_{d n n}^{K}+w_{c i n}^{T} p^{+}+b\right) y~=σ(wlinearTa+wdnnTxdnnK+wcinTp++b)
x d n n k , p + x_{d n n}^{k}, p^{+} xdnnk,p+ 分别是 DNN 和 CIN 的输出。
对于图(c),每一层的隐状态 x k + 1 x^{k+1} xk+1 ,将每个(第 k 层有 H k H_k Hk 个)特征向量求和,(sum pooling),最后将每一层结果拼接起来,作为最后的输出。
CIN 实现了输出单元可以得到不用阶数的特征交互模式,此外 CIN 的计算过程与机构和 RNN 类似,对于每一层的隐状态都是根据前一层的隐状态和额外的输入数据计算得到。
将 CIN 和 DNN 结合起来,得到 xDeepFM
一方面包括低阶和高阶特征交互;另一方面,既包括隐式的功能交互,也包括显式的功能交互;分别是DNN和CIN的输出。
损失函数(log loss):
Γ = − 1 N ∑ i = 1 N ( y i log y i ~ + ( 1 − y i ) log ( 1 − y i ~ ) ) + λ Θ \Gamma=-\frac{1}{N} \sum_{i=1}^{N}\left(y_{i} \log \tilde{y_{i}}+\left(1-y_{i}\right) \log (1-\tilde{y_{i}})\right)+\lambda \Theta Γ=−N1i=1∑N(yilogyi~+(1−yi)log(1−yi~))+λΘ
θ \theta θ 为 l1 和 l2 正则化。
暂记于此,后续继续补充。
[1] 博客:https://blog.csdn.net/yfreedomliTHU/article/details/91386734blog.csdn.net
[2] 综述:机器学习在CTR中的应用
[3] xDeepFM