Python deepFM推荐系统,推荐算法,deepFM源码实战,deepFM代码模板

1.DeepFM介绍:

        DeepFM(Deep Factorization Machine)是一种结合了深度学习和因子分解机的推荐模型。它在CTR(点击率)预测任务中表现出色,并能够有效地处理稀疏特征。

        DeepFM模型由两个部分组成:因子分解机(Factorization Machine)和深度神经网络(Deep Neural Network)。

        因子分解机(FM)部分利用了二阶多项式交互特征,可以有效地捕捉特征之间的交互关系。它将输入的特征向量分解为两个部分:一阶线性项和二阶交叉项。一阶线性项基于特征的原始值进行加权求和,而二阶交叉项通过内积计算不同特征之间的交叉权重。FM部分的输出表示了特征和交叉特征的组合信息。

        深度神经网络(DNN)部分通过多层神经网络学习高阶特征的表达。DNN可以自动学习到更加抽象和复杂的特征表示,从而提升模型的性能。这些隐藏层间的全连接层允许模型进行端到端的训练,通过非线性的激活函数和权重参数的更新,逐渐提取和组合特征。

        DeepFM模型通过将FM部分和DNN部分联合起来,充分利用了FM的低阶特征交叉和DNN的高阶特征学习能力。模型在训练过程中通过最小化预测值与真实值之间的差距来学习模型参数。在预测阶段,将输入的特征经过FM和DNN部分的计算得到最终的预测结果。

        相比于传统的模型,DeepFM模型能够同时利用低阶和高阶的特征交叉信息,提高了模型的表达能力和预测准确率。同时,它可以处理大规模稀疏特征和高维特征的问题,并且模型结构相对简洁,计算效率较高。因此,DeepFM在推荐系统和广告点击率预测等任务中具有很高的应用价值。

论文精要如下: 

 

 

其实最后就是把两部分特征相加,然后通过sigmoid函数输出最后的概率值。

2.DeepFM代码实战:

main.py文件

import numpy as np

import torch
import torch.optim as optim
from torch.utils.data import DataLoader
from torch.utils.data import sampler

from model.DeepFM import DeepFM
from data.dataset import CriteoDataset

# 900000 items for training, 10000 items for valid, of all 1000000 items
Num_train = 9000

# load data
train_data = CriteoDataset('./data', train=True)
loader_train = DataLoader(train_data, batch_size=16,
                          sampler=sampler.SubsetRandomSampler(range(Num_train)))
val_data = CriteoDataset('./data', train=True)
loader_val = DataLoader(val_data, batch_size=16,
                        sampler=sampler.SubsetRandomSampler(range(Num_train, 10000)))

feature_sizes = np.loadtxt('./data/feature_sizes.txt', delimiter=',')
feature_sizes = [int(x) for x in feature_sizes]
print(feature_sizes)

model = DeepFM(feature_sizes, use_cuda=False)
optimizer = optim.Adam(model.parameters(), lr=1e-4, weight_decay=0.0)
model.fit(loader_train, loader_val, optimizer, epochs=5, verbose=True)

数据处理文件 data/dataset.py

import torch
from torch.utils.data import Dataset
import pandas as pd
import numpy as np
import os

continous_features = 13

class CriteoDataset(Dataset):
    """
    Custom dataset class for Criteo dataset in order to use efficient 
    dataloader tool provided by PyTorch.
    """ 
    def __init__(self, root, train=True):
        """
        Initialize file path and train/test mode.

        Inputs:
        - root: Path where the processed data file stored.
        - train: Train or test. Required.
        """
        self.root = root
        self.train = train

        if not self._check_exists():
            raise RuntimeError('Dataset not found.')

        if self.train:
            data = pd.read_csv(os.path.join(root, 'train.txt'))
            self.train_data = data.iloc[:, :-1].values
            self.target = data.iloc[:, -1].values
        else:
            data = pd.read_csv(os.path.join(root, 'test.txt'))
            self.test_data = data.iloc[:, :-1].values
    
    def __getitem__(self, idx):
        if self.train:
            dataI, targetI = self.train_data[idx, :], self.target[idx]
            # index of continous features are zero
            Xi_coutinous = np.zeros_like(dataI[:continous_features])
            Xi_categorial = dataI[continous_features:]
            Xi = torch.from_numpy(np.concatenate((Xi_coutinous, Xi_categorial)).astype(np.int32)).unsqueeze(-1)
            
            # value of categorial features are one (one hot features)
            Xv_categorial = np.ones_like(dataI[continous_features:])
            Xv_coutinous = dataI[:continous_features]
            Xv = torch.from_numpy(np.concatenate((Xv_coutinous, Xv_categorial)).astype(np.int32))
            return Xi, Xv, targetI
        else:
            dataI = self.test_data.iloc[idx, :]
            # index of continous features are one
            Xi_coutinous = np.ones_like(dataI[:continous_features])
            Xi_categorial = dataI[continous_features:]
            Xi = torch.from_numpy(np.concatenate((Xi_coutinous, Xi_categorial)).astype(np.int32)).unsqueeze(-1)
            
            # value of categorial features are one (one hot features)
            Xv_categorial = np.ones_like(dataI[continous_features:])
            Xv_coutinous = dataI[:continous_features]
            Xv = torch.from_numpy(np.concatenate((Xv_coutinous, Xv_categorial)).astype(np.int32))
            return Xi, Xv

    def __len__(self):
        if self.train:
            return len(self.train_data)
        else:
            return len(self.test_data)

    def _check_exists(self):
        return os.path.exists(self.root)

 模型文件 model/DeepFM.py

# -*- coding: utf-8 -*-

"""
A pytorch implementation of DeepFM for rates prediction problem.
"""

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

from time import time


class DeepFM(nn.Module):
    """
    A DeepFM network with RMSE loss for rates prediction problem.

    There are two parts in the architecture of this network: fm part for low
    order interactions of features and deep part for higher order. In this 
    network, we use bachnorm and dropout technology for all hidden layers,
    and "Adam" method for optimazation.

    You may find more details in this paper:
    DeepFM: A Factorization-Machine based Neural Network for CTR Prediction,
    Huifeng Guo, Ruiming Tang, Yunming Yey, Zhenguo Li, Xiuqiang He.
    """

    def __init__(self, feature_sizes, embedding_size=4,
                 hidden_dims=[32, 32], num_classes=1, dropout=[0.5, 0.5], 
                 use_cuda=True, verbose=False):
        """
        Initialize a new network

        Inputs: 
        - feature_size: A list of integer giving the size of features for each field.
        - embedding_size: An integer giving size of feature embedding.
        - hidden_dims: A list of integer giving the size of each hidden layer.
        - num_classes: An integer giving the number of classes to predict. For example,
                    someone may rate 1,2,3,4 or 5 stars to a film.
        - batch_size: An integer giving size of instances used in each interation.
        - use_cuda: Bool, Using cuda or not
        - verbose: Bool
        """
        super().__init__()
        self.field_size = len(feature_sizes)
        self.feature_sizes = feature_sizes
        self.embedding_size = embedding_size
        self.hidden_dims = hidden_dims
        self.num_classes = num_classes
        self.dtype = torch.long
        self.bias = torch.nn.Parameter(torch.randn(1))
        """
            check if use cuda
        """
        if use_cuda and torch.cuda.is_available():
            self.device = torch.device('cuda')
        else:
            self.device = torch.device('cpu')
        """
            init fm part
        """
        self.fm_first_order_embeddings = nn.ModuleList(
            [nn.Embedding(feature_size, 1) for feature_size in self.feature_sizes])
        self.fm_second_order_embeddings = nn.ModuleList(
            [nn.Embedding(feature_size, self.embedding_size) for feature_size in self.feature_sizes])
        """
            init deep part
        """
        all_dims = [self.field_size * self.embedding_size] + \
            self.hidden_dims + [self.num_classes]
        for i in range(1, len(hidden_dims) + 1):
            setattr(self, 'linear_'+str(i),
                    nn.Linear(all_dims[i-1], all_dims[i]))
            # nn.init.kaiming_normal_(self.fc1.weight)
            setattr(self, 'batchNorm_' + str(i),
                    nn.BatchNorm1d(all_dims[i]))
            setattr(self, 'dropout_'+str(i),
                    nn.Dropout(dropout[i-1]))

    def forward(self, Xi, Xv):
        """
        Forward process of network. 

        Inputs:
        - Xi: A tensor of input's index, shape of (N, field_size, 1)
        - Xv: A tensor of input's value, shape of (N, field_size, 1)
        """
        """
            fm part
        """

        fm_first_order_emb_arr = [(torch.sum(emb(Xi[:, i, :]), 1).t() * Xv[:, i]).t() for i, emb in enumerate(self.fm_first_order_embeddings)]
        fm_first_order = torch.cat(fm_first_order_emb_arr, 1)
        #print(fm_first_order.shape)
        fm_second_order_emb_arr = [(torch.sum(emb(Xi[:, i, :]), 1).t() * Xv[:, i]).t() for i, emb in enumerate(self.fm_second_order_embeddings)]
        fm_sum_second_order_emb = sum(fm_second_order_emb_arr)
        fm_sum_second_order_emb_square = fm_sum_second_order_emb * \
            fm_sum_second_order_emb  # (x+y)^2
        #print(fm_sum_second_order_emb_square.shape)
        fm_second_order_emb_square = [
            item*item for item in fm_second_order_emb_arr]
        fm_second_order_emb_square_sum = sum(
            fm_second_order_emb_square)  # x^2+y^2
        fm_second_order = (fm_sum_second_order_emb_square -
                           fm_second_order_emb_square_sum) * 0.5
        """
            deep part
        """
        deep_emb = torch.cat(fm_second_order_emb_arr, 1)
        deep_out = deep_emb
        for i in range(1, len(self.hidden_dims) + 1):
            deep_out = getattr(self, 'linear_' + str(i))(deep_out)
            deep_out = getattr(self, 'batchNorm_' + str(i))(deep_out)
            deep_out = getattr(self, 'dropout_' + str(i))(deep_out)
        """
            sum
        """
        total_sum = torch.sum(fm_first_order, 1) + \
                    torch.sum(fm_second_order, 1) + torch.sum(deep_out, 1) + self.bias
        return total_sum

    def fit(self, loader_train, loader_val, optimizer, epochs=100, verbose=False, print_every=100):
        """
        Training a model and valid accuracy.

        Inputs:
        - loader_train: I
        - loader_val: .
        - optimizer: Abstraction of optimizer used in training process, e.g., "torch.optim.Adam()""torch.optim.SGD()".
        - epochs: Integer, number of epochs.
        - verbose: Bool, if print.
        - print_every: Integer, print after every number of iterations. 
        """
        """
            load input data
        """
        model = self.train().to(device=self.device)
        criterion = F.binary_cross_entropy_with_logits

        for _ in range(epochs):
            for t, (xi, xv, y) in enumerate(loader_train):
                xi = xi.to(device=self.device, dtype=self.dtype)
                xv = xv.to(device=self.device, dtype=torch.float)
                y = y.to(device=self.device, dtype=torch.float)
                
                total = model(xi, xv)
                loss = criterion(total, y)
                optimizer.zero_grad()
                loss.backward()
                optimizer.step()

                if verbose and t % print_every == 0:
                    print('Iteration %d, loss = %.4f' % (t, loss.item()))
                    self.check_accuracy(loader_val, model)
                    print()
    
    def check_accuracy(self, loader, model):
        if loader.dataset.train:
            print('Checking accuracy on validation set')
        else:
            print('Checking accuracy on test set')   
        num_correct = 0
        num_samples = 0
        model.eval()  # set model to evaluation mode
        with torch.no_grad():
            for xi, xv, y in loader:
                xi = xi.to(device=self.device, dtype=self.dtype)  # move to device, e.g. GPU
                xv = xv.to(device=self.device, dtype=torch.float)
                y = y.to(device=self.device, dtype=torch.bool)
                total = model(xi, xv)
                preds = (F.sigmoid(total) > 0.5)
                num_correct += (preds == y).sum()
                num_samples += preds.size(0)
            acc = float(num_correct) / num_samples
            print('Got %d / %d correct (%.2f%%)' % (num_correct, num_samples, 100 * acc))

 3. 项目数据在下方连接

deepFM数据下载链接

https://download.csdn.net/download/L_goodboy/88950471

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/450986.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

截断表

oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 截断表 事务处理本身是保护数据完整性的一个手段,但是在使用事务处理的过程之中需要注意一点 在用户更新数据后还未进行事务提交时,如果发生了 DDL…

1688 API接口在数据分析与营销决策中的应用探索

在当今数字化快速发展的时代,数据分析与营销决策已成为企业运营中不可或缺的重要环节。而1688 API接口,作为阿里巴巴旗下的一个强大的数据交互平台,为企业在数据分析与营销决策方面提供了丰富的数据源和灵活的操作方式。本文将深入探讨1688 A…

https代理相对socks5代理有什么优势?

随着互联网的快速发展,代理服务已成为许多人在访问敏感或地理位置受限的网站时所依赖的工具。其中,HTTPS代理和SOCKS5代理是两种最常用的代理服务类型。本文将探讨HTTPS代理相对SOCKS5代理的优势。 1、安全性 HTTPS代理使用SSL/TLS协议对客户端和代理服…

RabbitMQ - 01 - 快速入门

目录 界面总览 创建队列 选择默认交换机 发布消息 查看消息 通过实现以下目标快速入门 界面总览 RabbitMQ Management 界面总览 通道: 传输消息的通道 路由: 接收和路由(分发)消息 队列: 存储消息 消息队列的流程: 生产者将消息发送给路由,路由分发消息到各个队列存储…

Android Kotlin知识汇总(四)Kotlin 协程实践

Kotlin的重要优势及特点之——结构化并发 Kotlin 协程是一种并发设计模式,可以在 Android 平台上让异步代码像阻塞代码一样易于使用。协程可大幅简化后台任务管理,例如网络调用、本地数据访问等任务的管理。 简单来说,协程就是一种轻量级的非…

Windows从0到1部署项目

文章目录 1.创建虚拟机2.文件的传输--共享文件夹共享文件夹的访问 3.安装jdk,Tomcat3.1jdk的安装与配置配置环境变量 3.2Tomcat的安装与配置 4.安装mysql数据库5.下载nginx6.虚拟域名 因为Windows项目部署有很多操作都是博主之前做过的了,所及就只放了博…

何恺明教授在MIT的第一课,双语字幕1080P看resnet作者亲自讲解resnet

这几天AI圈最火的话题莫过于何恺明大神在MIT的首场教学了 何恺明(Kaiming He)教授于3月7日走上讲台,完成了他在麻省理工学院的首场教学,这标志着他教学生涯中的一个重要时刻。作为麻省理工学院电气工程与计算机科学系&#xff08…

批处理自动找木马文件路径

背景:如果主机不多,应急有通报的木马病毒样本可能存在的路径,一个个翻就太累。 直接整成一个文档,如果存在那个可以着重主机了。当然木马查杀记录也不能忘记看下。 1. 双击打开 cmd.bat 2. 输入list.bat 3. 文件存在输出路径…

SQLiteC/C++接口详细介绍之sqlite3类(四)

上一篇:SQLiteC/C接口详细介绍之sqlite3类(三) 下一篇:SQLiteC/C接口详细介绍之sqlite3类(五)(暂未发表) 编写不易,有用的朋友点个赞或加粉一下万分感谢!300…

three.js 按键W前进、S退后、A左转、D右转运动

效果&#xff1a;W 键 前进&#xff1b;S 键后退&#xff1b;A 键左转&#xff1b;D 键右转&#xff1b;使用了 tween.js 动画库&#xff1b; 代码&#xff1a; <template><div><el-container><el-main><div class"box-card-left">&…

ctfshow-XXE(web373-web378)

目录 XXE&#xff08;外部实体注入攻击&#xff09; web373 web374 web375 web376 web377 web378 知识点 XXE&#xff08;外部实体注入攻击&#xff09; XXE这几关有个前提flag在根目录下文件名为flag web373 <?php error_reporting(0); libxml_disable_entity_…

商铺办理房产证需缴纳的交易费用有哪些材料?

一、商铺办理房产证收费标准 一般来说&#xff0c;商铺办理房产证时需要缴纳的交易费用包括&#xff1a;交易费、登记费、验资费、营业税、个人所得税、契税等。 每个城市的缴费标准会有所不同。 具体缴纳费用需要咨询当地房管局。 1、契税&#xff1a;房屋交易额的5%。 &…

BUUCTF-----[SWPU2019]Web1

打开页面&#xff0c;原本以为是二次注入,结果不是&#xff0c;先注册一个账户 在申请发布广告中&#xff0c;发现反射性xss(然而没有什么用) 在广告申请名字中发现注入点 开始注入 通过一系列的测试&#xff0c;发现系统过滤了#&#xff0c;or&#xff0c;空格 orde…

C语言 - 各种自定义数据类型

1.结构体 把不同类型的数据组合成一个整体 所占内存长度是各成员所占内存的总和 typedef struct XXX { int a; char b; }txxx; txxx data; typedef struct XXX { int a:1; int b:1; …

如果电脑缺少dll文件怎么解决?如何快速解决dll丢失问题

最近有小伙伴问电脑老是缺少dll文件&#xff0c;这种问题到底要怎么去解决呢&#xff1f;其实这种现象是正常的&#xff0c;为啥说正常呢&#xff0c;下面我们会给大家详细的讲解dll为啥会缺少&#xff0c;然后还会讲解电脑缺少dll文件怎么解决的方法&#xff0c;好了&#xff…

Linux: 预备

计算机结构基础 由于速度原因, CPU不直接与外设打交道, 而是通过内存进行交互.(CPU速度 >> 外设) 操作系统: 内核 (管理软硬件) shell(给用户使用操作系统的方式) 操作系统封装了用户操作接口 相比于系统接口,使用更简单跨平台性: 不同的操作系统,其系统调用接口是不同…

代码随想录 贪心算法-难度题目-其他题目

目录 53.最大子数组和 134.加油站 968.监控二叉树 53.最大子数组和 53. 最大子数组和 中等 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组 是数组中的一个…

(SUB)app性能测试

APP性能测试(启动速度、内存、CPU、FPS、GPU、耗电量)_性能测试中fps分析-CSDN博客 app性能测试_app性能测试方案-CSDN博客 测试方案 服务端 平均响应时间 错误率 吞吐量 CPU/内存占用率 网络/硬盘的读写速度 客户端 启动速度 手机APP的启动时长是一个很容易被用户感…

【数据库】Oracle内存结构与参数调优

Oracle内存结构与参数调优 Oracle 内存结构概览oracle参数配置概览重要参数&#xff08;系统运行前配置&#xff09;:次要参数&#xff08;可在系统运行后再优化调整&#xff09;: Oracle数据库服务器参数如何调整OLTP内存分配操作系统核心参数配置Disabling ASMM&#xff08;禁…

JSON基础知识

目录 一、定义二、作用三、特点四、语法JSON具有以下这些形式&#xff1a;4.1 对象(JSONObject)&#xff1a;4.2 数组(JSONArray)&#xff1a;4.3 值4.4 字符串4.5 数值 五、常用的JSON解析方式5.1 org.json解析5.1.1 常用api5.1.2 get方法与opt方法对比5.1.3 使用示例5.1.3 参…