• 推荐模型复现(一):熟悉Torch-RecHub框架与使用


    1 Torch-RecHub框架

    一个轻量级的pytorch推荐模型框架

    1.1 框架概述

    • 核心定位:易使用易扩展、可复现业界实用的推荐模型、聚焦泛生态化的模型复现研究
    • 工程设计:基于PyTorch原生的类和函数,模型训练与模型定义解耦,无basemodel,在符合论文思想的基础上,使同学快速上手
    • 学习参考:参考DeepCTRFuxiCTR等优秀开源框架的特性

    1.2 主要特性

    • scikit-learn风格易用的API(fitpredict),开箱即用
    • 模型训练与模型定义解耦,易拓展,可针对不同类型的模型设置不同的训练机制
    • 支持pandasDataFrameDict等数据类型的输入,降低上手成本
    • 高度模块化,支持常见Layer,容易调用组装形成新的模型
      • LR、MLP、FM、FFM、CIN
      • target-attention、self-attention、transformer
    • 支持常见排序模型
      • WideDeep、DeepFM、DIN、DCN、xDeepFM等
    • 支持常见召回模型
      • DSSM、YoutubeDNN、YoutubeDSSM、FacebookEBR、MIND等
    • 丰富的多任务学习支持
      • SharedBottom、ESMM、MMOE、PLE、AITM等模型
      • GradNorm、UWL、MetaBanlance等动态loss加权机制
    • 聚焦更生态化的推荐场景
    • 支持丰富的训练机制

    1.3 Torch-RecHub架构设计

      Torch-RecHub主要由数据处理模块、模型层模块和训练器模块组成:

    1. 数据处理模块
    • 特征处理:DenseFeature(用于构建数值型特征)、SparseFeature(用于处理类别型特征)、SequenceFeature(用于处理序列特征)
    • 数据构造:DataGenerator(数据生成器,用于创建三大数据集)
    1. 模型层模块
    • 排序模型:WideDeep、DeepFM、DCN、xDeepFM、DIN、DIEN、SIM
    • 召回模型:DSSM、YoutubeDNN、YoutubeSBC、FaceBookDSSM、Gru4Rec、MIND、SASRec、ComiRec
    • 多任务模型:SharedBottom、ESMM、MMOE、PLE、AITM
    1. 训练器模块
    • CTRTrainer:用于精排模型训练与评估
    • MTLTrainer:用于多任务排序模型训练与评估
    • MatchTrainer:用于召回模型训练与评估

    2 Torch-RecHub的使用

      以下采用小样本的criteo数据集,仅有115条数据。该数据集是Criteo Labs发布的在线广告数据集。它包含数百万个展示广告的点击反馈记录,该数据可作为点击率(CTR)预测的基准。数据集具有40个特征,第1列是标签,其中值1表示已点击广告,而值0表示未点击广告。其他特征包含13个dense特征和26个sparse特征。

    1. import numpy as np
    2. import pandas as pd
    3. import torch
    4. from tqdm import tqdm
    5. from sklearn.preprocessing import MinMaxScaler, LabelEncoder
    6. from torch_rechub.basic.features import DenseFeature, SparseFeature
    7. from torch_rechub.utils.data import DataGenerator
    8. from torch_rechub.trainers import CTRTrainer
    9. from torch_rechub.models.ranking import WideDeep
    Copy to clipboardErrorCopied
    1. data_path = './data/criteo/criteo_sample.csv'
    2. # 导入数据集
    3. data = pd.read_csv(data_path)
    4. data.head()
    Copy to clipboardErrorCopied

    labelI1I2I3I4I5I6I7I8I9...C17C18C19C20C21C22C23C24C25C26
    000.00104.027.01990.0142.04.032.037.0...e5ba767225c88e4221ddcdc9b1252a9d0e8585d2NaN32c7478e0d4a6d1a001f360192c878de
    100.0-163.040.01470.061.04.037.046.0...e5ba7672d3303ea521ddcdc9b1252a9d7633c7c8NaN32c7478e17f458f7001f360171236095
    200.03704.01.01787.065.014.025.0489.0...3486227d642f261055dd3565b1252a9d5c8dc711NaN423fab6945ab94c82bf691b1c84c4aec
    3119.01030.010.01.03.033.047.0126.0...e5ba7672a78bd50821ddcdc95840adeac2a93b37NaN32c7478e1793a828e8b834072fede552
    400.0036.022.04684.0217.09.035.0135.0...e5ba76727ce63c71NaNNaNaf5dc647NaNdbb486d71793a828NaNNaN

    5 rows × 40 columns

    1. dense_features = [f for f in data.columns.tolist() if f[0] == "I"]
    2. sparse_features = [f for f in data.columns.tolist() if f[0] == "C"]
    3. # 数据NaN值填充,对sparse特征的NaN数据填充字符串为-996,对dense特征的NaN数据填充0
    4. data[sparse_features] = data[sparse_features].fillna('-996',)
    5. data[dense_features] = data[dense_features].fillna(0,)
    Copy to clipboardErrorCopied
    1. def convert_numeric_feature(val):
    2. v = int(val)
    3. if v > 2:
    4. return int(np.log(v)**2)
    5. else:
    6. return v - 2
    Copy to clipboardErrorCopied
    1. # 进行归一化
    2. for feat in dense_features:
    3. sparse_features.append(feat + "_cat")
    4. data[feat + "_cat"] = data[feat].apply(lambda x: convert_numeric_feature(x))
    5. sca = MinMaxScaler() #scaler dense feature
    6. data[dense_features] = sca.fit_transform(data[dense_features])
    Copy to clipboardErrorCopied
    1. # 处理sparse特征数据
    2. for feat in sparse_features:
    3. lbe = LabelEncoder()
    4. data[feat] = lbe.fit_transform(data[feat])
    Copy to clipboardErrorCopied
    1. # 得到最终的数据
    2. dense_feas = [DenseFeature(feature_name) for feature_name in dense_features]
    3. sparse_feas = [SparseFeature(feature_name, vocab_size=data[feature_name].nunique(), embed_dim=16) for feature_name in sparse_features]
    4. y = data["label"]
    5. del data["label"]
    6. x = data
    Copy to clipboardErrorCopied
    1. # 构造数据生成器
    2. data_generator = DataGenerator(x, y)
    Copy to clipboardErrorCopied
    1. batch_size = 2048
    2. # 将数据集分隔成训练集70%、验证集10%和测试集20%
    3. train_dataloader, val_dataloader, test_dataloader = data_generator.generate_dataloader(split_ratio=[0.7, 0.1], batch_size=batch_size)
    Copy to clipboardErrorCopied
    the samples of train : val : test are  80 : 11 : 24Copy to clipboardErrorCopied
    1. # 配置多层感知器模块的参数
    2. mlp_params={
    3. "dims": [256, 128],
    4. "dropout": 0.2,
    5. "activation": "relu"}
    6. # 构建WideDeep模型
    7. model = WideDeep(wide_features=dense_feas, deep_features=sparse_feas, mlp_params=mlp_params)
    Copy to clipboardErrorCopied
    1. learning_rate = 1e-3
    2. weight_decay = 1e-3
    3. device = 'cuda:0'
    4. save_dir = './models/'
    5. epoch = 2
    6. optimizer_params={
    7. "lr": learning_rate,
    8. "weight_decay": weight_decay}
    9. # 构建训练器
    10. ctr_trainer = CTRTrainer(model, optimizer_params=optimizer_params, n_epoch=epoch, earlystop_patience=10,
    11. device=device, model_path=save_dir)
    Copy to clipboardErrorCopied
    1. # 模型训练
    2. ctr_trainer.fit(train_dataloader, val_dataloader)
    Copy to clipboardErrorCopied
    1. epoch: 0
    2. train: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:12<00:00, 12.33s/it]
    3. validation: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:10<00:00, 10.66s/it]
    4. epoch: 0 validation: auc: 0.35
    5. epoch: 1
    6. train: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:10<00:00, 10.71s/it]
    7. validation: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:10<00:00, 10.69s/it]
    8. epoch: 1 validation: auc: 0.35
    Copy to clipboardErrorCopied
    1. # 模型评估
    2. auc = ctr_trainer.evaluate(ctr_trainer.model, test_dataloader)
    3. print(f'test auc: {auc}')
    Copy to clipboardErrorCopied
    1. validation: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:10<00:00, 10.60s/it]
    2. test auc: 0.6203703703703703
    Copy to clipboardErrorCopied

    3 总结

      本次任务,主要介绍了Torch-RecHub框架和基本的使用方法:

    1. Torch-RecHub框架主要基于PyTorch和sklearn,易使用易扩展、可复现业界实用的推荐模型,高度模块化,支持常见Layer,支持常见排序模型、召回模型、多任务学习;
    2. 使用方法:使用DataGenerator构建数据加载器,通过构建轻量级的模型,并基于统一的训练器进行模型训练,最后完成模型评估。

     

  • 相关阅读:
    Proteus仿真--1602LCD显示电话拨号键盘按键实验(仿真文件+程序)
    Vuex简介
    NetSuite海鲜书 - 知识会汇编 用户篇 2023
    (三十一)大数据实战——一键式DolphinScheduler高可用工作流任务调度系统部署安装
    瀑布流使用虚拟列表性能优化
    【FPGA】DDR3学习笔记(二)丨从SDRAM到DDR3的IP核设计
    CSDN 成为开放原子开源基金会黄金捐赠人,共建中国十万亿技术大生态
    如何解决Java 中的精度问题
    python的seek()和tell()
    Redis高可用系列——ZSet类型
  • 原文地址:https://blog.csdn.net/qq_36816848/article/details/125402958