推荐系统学习笔记-PNN算法

由来

Product-based Neural Network)是在2016年提出的用于计算CTR问题的深度神经网络模型,PNN的网络结构对传统的FNN(Feedforward Neural Network)网络结构做了一些优化,使得其能够更适合处理CTR问题。在PNN网络模型中,主要的优化点为:

通过Embedding层处理离散特征。Embedding层现在已经成为DNN模型处理CTR问题的标配;
增加Product层,在Product Layer中,通过显式构造特征交叉,在不同的特征域之间进行特征组合,在实际的实施过程中,会有不同的product计算方法,分别为inner producr和outer product。

其与DeepCrossing类似,它将DeepCrossing的stack部分做了修改,做了特征向量相乘和交叉操作,使得更加充分的学习embedding向量的信息。最重要的就是Product层。

网络结构图

推荐系统学习笔记-PNN算法_第1张图片

用公式表达,就是

内积为

在这里插入图片描述

外积为
推荐系统学习笔记-PNN算法_第2张图片

平均池化降维公式:
推荐系统学习笔记-PNN算法_第3张图片

实验结果

推荐系统学习笔记-PNN算法_第4张图片

推荐系统学习笔记-PNN算法_第5张图片

结论

PNN网络结构在传统的DNN中增加了Product层,从而实现了特征的交叉,在具体的实现过程中,提出了两种Product的计算,分别为Inner Product和Outer Product。在具体的数据中,两种Product的表现并不一致,需要根据具体的数据选择合适的Product计算方法,相比较传统的DNN,从实验结果来看,效果上PNN得到了较大提升

模型实现(参考)

class PNN(nn.Module):
    def __init__(self, feature_info, hidden_units, mode='in', dnn_dropout=0., embed_dim=10, outdim=1):

        super(PNN, self).__init__()
        self.dense_feas, self.sparse_feas, self.sparse_feas_map = feature_info
        self.field_num = len(self.sparse_feas)
        self.dense_num = len(self.dense_feas)
        self.mode = mode
        self.embed_dim = embed_dim
        
        #embedding层
        self.embed_layers = nn.ModuleDict({
            'embed_'+str(key):nn.Embedding(num_embeddings=val, embedding_dim=self.embed_dim) for key, val in self.sparse_feas_map.items()
        })
        
        #Product层
        self.product = ProductLayer(mode, embed_dim, self.field_num, hidden_units)
        
        #dnn层
        hidden_units[0] += self.dense_num
        self.dnn_network = DNN(hidden_units, dnn_dropout)
        self.dense_final = nn.Linear(hidden_units[-1], 1)
    def forward(self, x):
        dense_inputs, sparse_inputs = x[:,:13], x[:,13:] 
        sparse_inputs = sparse_inputs.long() 
        sparse_embeds = [self.embed_layers['embed_'+key](sparse_inputs[:,i]) for key, i in zip(self.sparse_feas_map.keys(), range(sparse_inputs.shape[1]))]
        
        sparse_embeds = torch.stack(sparse_embeds)
        sparse_embeds = sparse_embeds.permute((1, 0, 2)) 
        z = sparse_embeds
        
 
        sparse_inputs = self.product(z, sparse_embeds)
        

        l1 = F.relu(torch.cat([sparse_inputs, dense_inputs], -1))
        #dnn_network
        dnn_x = self.dnn_network(l1)
        
        outputs = F.sigmoid(self.dense_final(dnn_x))
        return outputs




你可能感兴趣的:(kaggle,神经网络,推荐系统学习笔记,学习,算法,人工智能)