CTR预估系列文章------NFFM

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a940902940902/article/details/89320879

NFFM文章解读与源码分析

NFFM结构与公式解析

在这里插入图片描述

NFFM结构如上图所示,主要分为category 经过one-hot之后的输入,对category特征进行Embedding编码得到真实的dense层输入 可以得到一个n(总共的filed数量) * n( 每 一个field 生成 field数量的vector用于交叉计算) * k(vector的长度)的特征

NFFM的数学表达如下:
X=[x1,x2,… xn] 对应上图Spares Feature层
Vi=[ vi,f1, vi,f2… vi,fn ] 对应上图中Dense Embedding 层的每一个filed,其实每一个filed都生成了一个多余的向量即 vi,fi 因为不会有自己和自己交叉的操作,但是为了方便还是生成了该向量
V=[V1,V2…Vn] 将Vi 连接起来对应整体的Dense Embedding层
ynffm = w0 + ∑ wi xi +DNN(fBI(Vx))
其中 前两项为FFM中的前两项 也就是一个线性回归,而深度部分可以继续分解 DNN(fBI(Vx))=DNN(FCS({vi,fj⊙vj,fi}))
其中FC表示全连接层,vi,fj⊙vj,fi表示vi,fj 与 vj,fi 的元素乘法,将所有的特征均进行交叉 最后可以得到n*(n-1)*k/2数量的特征

输入层

首先 将用户特征,媒体特征,上下文特征等全部转化为特征向量,如下所示:
X=[x1,x2,… xn]
其中xi表示第i个特征组(类似于FFM中field 的概念) 如果第i个特征是定长的category特征 则xi 代表该category特征进行one-hot之后的特征,如果该特征是数值特征,则xi 等于该数值特征的取值,对于xi为变长的category特征的情况会对各个取值Embedding之后做average的操作。

Dense Embeddings 层

对于Embedding层 可以公式化为如下表示:

ei =Vixi
其中Vi 代表第i个特征域 中的Embedding matrix (对于FM而言 第i个特征域中的Embedding Matrix是一个n(特征取值数)* k(隐向量长度)的矩阵 ,对于FFM 第i个特征域 Embedding matrix 是一个n(特征取值数) 乘(field数乘隐向量长度)的矩阵 )因为FFM中每一个field 都需要生成 filed个数的隐向量 所以在这里可以看出来 FFM比FM效果好本职就是因为特征数目的增加

同样对于数值特征也可以进行类似的操作:
em =vmxm
其中vm 表示第m个标量对应的Embedding 向量 (对于FM而言是一个1k的向量 对于FFM是一个1n*k向量)
这样就可以将category 和numerical数据都一起投影到一个低维空间 然后可以进行交叉操作

对于第i个 feature group

在实现的过程中使用 nn.Embedding 来实现Embedding层 这里首先对nn.Embedding 做一个简单的解释
首先对于一个category 进行one-hot Embedding之后n维的特征创建 nn.Embedding 模块
nn.Embedding(n,k) (则会生成一个n 行 k列的矩阵) 如果没有对该Embedding矩阵进行赋值操作则会生成一个 每一行都近似均值为0方差为1的正太分布的随机数
使用该Embedding 对特征进行编码
例如:

testEmbedding=nn.Embedding(5,4)
testEmbedding.weight
输出如下内容:
Parameter containing:
tensor([[ 0.9837,  0.8793, -1.4504, -1.1802],
        [ 1.3075, -1.1628,  0.1196, -0.1631],
        [ 0.6614,  1.1899,  0.8165, -0.9135],
        [-0.3538,  0.7639, -0.5890, -0.7636],
        [ 1.3352,  0.6043, -0.1034, -0.1512]], requires_grad=True)

testEmbedding(torch.autograd.Variable(torch.LongTensor([3])))
输出如下内容:
tensor([[-0.3538,  0.7639, -0.5890, -0.7636]], grad_fn=<EmbeddingBackward>)  
由此可见 对于输入的 category label encoding之后的值为3  进行 one-hot之后得到的 向量为  [0,0,0,1,0]  和weight进行点乘得到  [-0.3538,  0.7639, -0.5890, -0.7636] 

在随后的反向传播中可以不断的优化 Embedding 矩阵 进而得到最优隐向量表示
Bi-Iteration 层

ai,j =xi vi,fj ⊙xj vj,fi
fBI(Vx)= a1,2 ⊕a1,3+…+af-1,f
其中⊕为concat操作

NFFM pytorch 实现

输入变量

猜你喜欢

转载自blog.csdn.net/a940902940902/article/details/89320879