CTR 模型 NFFM

    xiaoxiao2023-10-11  163

    1 理论介绍

    详看 zhihu nzc 介绍 NFFM; FM和FFM区别 FM对于每一个特征只会生成一个连续值特征向量,与其他特征做交叉时,都会使用这一个特征向量。而FFM中,每一个特征会生成多个特征向量,与不同的特征做组合时,会用不同的特征向量做组合。

    FFM和NFFM的区别

    FFM: NFFM: y n f f m = w 0 + ∑ i = 1 f w i x i + D N N ( X ) D N N ( X ) = F C S ( { v i , f j ⊙ v j , f i } ) y_{n f f m} = w_{0}+\sum_{i=1}^{f} w_{i} x_{i}+D N N(X) \\ D N N(X)=F C S\left(\left\{v_{i, f_{j}} \odot v_{j, f_{i}}\right\}\right) ynffm=w0+i=1fwixi+DNN(X)DNN(X)=FCS({vi,fjvj,fi}) 这里, FCS 代表全连接网络。 ,代表的是两个特征向量之间做元素间乘法后拼接的结果。

    Q: 这里用向量的内积,会有区别吗?

    A: 因为普通的FFM直接输出到LR 模型中,用内积就行了(得到一个数);NFFM模型需要输出到DNN网络中,这里用元素积(也叫哈达玛积),向量相乘后仍是向量,不能再用内积运算了。

    在NFFM中,可以看到,embedding 层 Matrix Embedding 的表示是field number(特征的个数)个矩阵组成。

    也就是说, 一个 one hot 特征转换为一个矩阵, 这里矩阵的维度其实是, field_num * embedding_size; 这里选择 field_num 个而不是一个的原因是,它认为 每两个特征交叉是不一样的,不能共享参数(每一个特征在Embedding层只有一个向量表示)。 后面是接了 全连接网络,进一步提取交叉特征; 以及把一开始的 稀疏表示特征(one hot特征)也进行拼接进入到最终的 Softmax层,获得点击转换概率 CTR。

    2. numpy 简单实现FFM过程

    FFM 层向前生成的向量应该有 ∑ i = 1 f i l e d _ n u m − 1 i \sum\limits_{i = 1}^{filed\_num -1} i i=1filed_num1i 个。

    Bi-Iteration层 a i , j = x i v i , f j ⊙ x j v j , f i f B l ( V x ) = a 1 , 2 ⊕ a 1 , 3 + … + a f − 1 , f \begin{aligned} &a_{i, j}=x_{i} v_{i, f_j} \odot x_{j} v_{j, f_{i}}\\ &f_{\mathrm{Bl}}\left({V}_{\mathrm{x}}\right)=\mathrm{a}_{1,2} \oplus \mathrm{a}_{1,3}+\ldots+\mathrm{a}_{\mathrm{f}-1, \mathrm{f}} \end{aligned} ai,j=xivi,fjxjvj,fifBl(Vx)=a1,2a1,3++af1,f ⊕ \oplus 为 concat 操作。

    import numpy as np from itertools import combinations # input_size * field_num * filed_size # field 1 : filed_size = 3 # field_2 : filed_size = 4 input = np.array([[[0, 0, 1], [1, 0, 0, 0]], [[0, 1, 0], [0, 0, 0, 1]]]) embedding_size = 10 field_num = len(input[1]) # 只取输入数据的 第一个样本来演算 sample = input[0] embedding_matrix = [] for i in range(field_num): field = sample[i] # 每一个输入特征转化成 field_num 个 embedding_size 大小的Vector,用于后面交叉 w = np.random.random(size = (len(field), embedding_size*field_num)) # Embedding layer 的表示 field_embedding = np.matmul(field, w) embedding_matrix.append(field_embedding) # 获得的Embedding layer matrix: (field_num , field_num , embedding_size) embedding_matrix = np.array(embedding_matrix).reshape(field_num, field_num , embedding_size) # FFM 元素两两交叉 print(embedding_matrix) # 根据 v_{i, f_j} * v_{j, f_i} 点乘计算, 输出向量:( field_num * (field_num -1)/2 * embedding_size) output = [] for (c1, c2) in combinations(np.arange(field_num), 2): element_wise = (embedding_matrix[c1][c2] * embedding_matrix[c2][c1]) output.append(element_wise) print('output', np.array(output))

    1csdn NFFM介绍; 2 zhihu 渣大介绍NFFM; 3 渣大 TensorFlow版本开源NFFM;

    最新回复(0)