资讯动态

04-进阶方向:结构化数据与推荐系统——推荐排序:Wide Deep

发布时间:2026/10/16 10:49:14 来源:尧图企业网站定制
推荐排序Wide Deep记忆与泛化、特征组合一、Wide Deep概述1.1 为什么需要Wide Deepimportnumpyasnpimportmatplotlib.pyplotaspltfrommatplotlib.patchesimportRectangle,FancyBboxPatchimportwarnings warnings.filterwarnings(ignore)print(*60)print(Wide Deep记忆与泛化的结合)print(*60)# Wide Deep架构图fig,axesplt.subplots(1,2,figsize(14,6))# Wide部分记忆ax1axes[0]ax1.axis(off)ax1.set_title(Wide部分记忆Memorization,fontsize10)wide_features[用户ID123,物品ID456,历史点击物品A]fori,featinenumerate(wide_features):circleplt.Circle((0.2,0.7-i*0.15),0.08,colorlightblue,ecblack)ax1.add_patch(circle)ax1.text(0.2,0.7-i*0.15,feat,hacenter,vacenter,fontsize7)wide_outputplt.Rectangle((0.65,0.55),0.2,0.2,facecolorlightcoral,ecblack)ax1.add_patch(wide_output)ax1.text(0.75,0.65,线性模型\n(特征交叉),hacenter,vacenter,fontsize7)foriinrange(3):ax1.annotate(,xy(0.65,0.65),xytext(0.28,0.7-i*0.15),arrowpropsdict(arrowstyle-,lw1))ax1.text(0.5,0.2,记忆: 学习高频共现模式,hacenter,fontsize8,bboxdict(boxstyleround,facecolorlightyellow))# Deep部分泛化ax2axes[1]ax2.axis(off)ax2.set_title(Deep部分泛化Generalization,fontsize10)# 嵌入层embeddingplt.Rectangle((0.2,0.7),0.6,0.1,facecolorlightgreen,ecblack)ax2.add_patch(embedding)ax2.text(0.5,0.75,嵌入层 (Dense Embedding),hacenter,vacenter,fontsize7)# 隐藏层hidden1plt.Rectangle((0.25,0.55),0.5,0.1,facecolorlightyellow,ecblack)ax2.add_patch(hidden1)ax2.text(0.5,0.6,隐藏层1,hacenter,vacenter,fontsize7)ax2.annotate(,xy(0.5,0.65),xytext(0.5,0.7),arrowpropsdict(arrowstyle-,lw1))hidden2plt.Rectangle((0.25,0.4),0.5,0.1,facecolorlightyellow,ecblack)ax2.add_patch(hidden2)ax2.text(0.5,0.45,隐藏层2,hacenter,vacenter,fontsize7)ax2.annotate(,xy(0.5,0.5),xytext(0.5,0.55),arrowpropsdict(arrowstyle-,lw1))deep_outputplt.Rectangle((0.65,0.25),0.2,0.1,facecolorlightcoral,ecblack)ax2.add_patch(deep_output)ax2.text(0.75,0.3,DNN输出,hacenter,vacenter,fontsize7)ax2.annotate(,xy(0.75,0.35),xytext(0.75,0.4),arrowpropsdict(arrowstyle-,lw1))ax2.text(0.5,0.15,泛化: 学习稀疏特征组合,hacenter,fontsize8,bboxdict(boxstyleround,facecolorlightyellow))plt.suptitle(Wide Deep架构,fontsize14)plt.tight_layout()plt.show()print(\n Wide Deep核心思想:)print( Wide部分: 记忆高频特征组合LR 特征交叉)print( Deep部分: 泛化到稀疏特征组合DNN)print( 结合: 同时获得记忆和泛化能力)二、Wide部分2.1 特征交叉defwide_part():Wide部分详解print(\n*60)print(Wide部分特征交叉)print(*60)fig,axesplt.subplots(1,2,figsize(14,5))# 特征交叉示例ax1axes[0]ax1.axis(off)ax1.set_title(特征交叉示例,fontsize11)# 用户特征ax1.text(0.2,0.8,用户特征:,fontsize9,fontweightbold)user_features[user_id123,gendermale,age25-34]fori,featinenumerate(user_features):ax1.text(0.25,0.72-i*0.08,feat,fontsize8)# 物品特征ax1.text(0.6,0.8,物品特征:,fontsize9,fontweightbold)item_features[item_id456,categoryelectronics,pricehigh]fori,featinenumerate(item_features):ax1.text(0.65,0.72-i*0.08,feat,fontsize8)# 交叉特征ax1.text(0.2,0.45,交叉特征:,fontsize9,fontweightbold,colorred)cross_features[user_id123 AND item_id456,gendermale AND categoryelectronics,age25-34 AND pricehigh]fori,featinenumerate(cross_features):ax1.text(0.25,0.37-i*0.08,feat,fontsize8,colorred)# 公式ax2axes[1]ax2.axis(off)ax2.set_title(Wide部分公式,fontsize11)formula Wide部分逻辑回归 特征交叉: y_wide σ(w_wide^T · x_wide b) 其中: • x_wide: 原始特征 交叉特征 • 交叉特征: φ(x) Π x_i^{c_i} 特征交叉示例: • AND(user_id123, item_id456) • AND(gendermale, categoryelectronics) 作用: • 记忆高频共现模式 • 简单、可解释 • 适合处理稀疏特征 ax2.text(0.05,0.95,formula,transformax2.transAxes,fontsize9,verticalalignmenttop,fontfamilymonospace)plt.suptitle(Wide部分特征交叉,fontsize12)plt.tight_layout()plt.show()wide_part()三、Deep部分3.1 嵌入层与DNNdefdeep_part():Deep部分详解print(\n*60)print(Deep部分深度神经网络)print(*60)fig,axesplt.subplots(1,2,figsize(14,5))# Deep部分结构ax1axes[0]ax1.axis(off)ax1.set_title(Deep部分结构,fontsize11)# 输入特征features[用户ID,物品ID,类别,价格,时间]x_posnp.linspace(0.1,0.9,len(features))fori,(feat,x)inenumerate(zip(features,x_pos)):circleplt.Circle((x,0.85),0.06,colorlightblue,ecblack)ax1.add_patch(circle)ax1.text(x,0.85,feat,hacenter,vacenter,fontsize7)# 嵌入层embed_layerplt.Rectangle((0.1,0.68),0.8,0.1,facecolorlightgreen,ecblack)ax1.add_patch(embed_layer)ax1.text(0.5,0.73,嵌入层 (Embedding Layer),hacenter,vacenter,fontsize8)forxinx_pos:ax1.annotate(,xy(x,0.78),xytext(x,0.85),arrowpropsdict(arrowstyle-,lw0.5))# 拼接concatplt.Rectangle((0.2,0.55),0.6,0.08,facecolorlightyellow,ecblack)ax1.add_patch(concat)ax1.text(0.5,0.59,拼接 (Concat),hacenter,vacenter,fontsize8)ax1.annotate(,xy(0.5,0.68),xytext(0.5,0.63),arrowpropsdict(arrowstyle-,lw1))# 隐藏层hidden1plt.Rectangle((0.25,0.42),0.5,0.08,facecolorlightcoral,ecblack)ax1.add_patch(hidden1)ax1.text(0.5,0.46,隐藏层 (ReLU),hacenter,vacenter,fontsize8)ax1.annotate(,xy(0.5,0.55),xytext(0.5,0.5),arrowpropsdict(arrowstyle-,lw1))hidden2plt.Rectangle((0.25,0.28),0.5,0.08,facecolorlightcoral,ecblack)ax1.add_patch(hidden2)ax1.text(0.5,0.32,隐藏层 (ReLU),hacenter,vacenter,fontsize8)ax1.annotate(,xy(0.5,0.42),xytext(0.5,0.36),arrowpropsdict(arrowstyle-,lw1))# 输出outputplt.Rectangle((0.35,0.15),0.3,0.08,facecolorlightpink,ecblack)ax1.add_patch(output)ax1.text(0.5,0.19,Deep输出,hacenter,vacenter,fontsize8)ax1.annotate(,xy(0.5,0.28),xytext(0.5,0.23),arrowpropsdict(arrowstyle-,lw1))# 公式ax2axes[1]ax2.axis(off)ax2.set_title(Deep部分公式,fontsize11)formula Deep部分DNN: a^{(1)} σ(W^{(1)} · e b^{(1)}) a^{(2)} σ(W^{(2)} · a^{(1)} b^{(2)}) ... y_deep W^{(L)} · a^{(L-1)} b^{(L)} 其中: • e: 拼接的嵌入向量 • σ: ReLU激活函数 • L: 隐藏层数 作用: • 学习高阶特征交互 • 泛化到稀疏组合 • 自动特征学习 ax2.text(0.05,0.95,formula,transformax2.transAxes,fontsize9,verticalalignmenttop,fontfamilymonospace)plt.suptitle(Deep部分深度神经网络,fontsize12)plt.tight_layout()plt.show()deep_part()四、Wide Deep实现4.1 完整实现defwide_deep_implementation():Wide Deep完整实现print(\n*60)print(Wide Deep实现)print(*60)code import torch import torch.nn as nn import torch.nn.functional as F class WideDeep(nn.Module): def __init__(self, wide_feature_dim, deep_feature_dim, embed_dims, hidden_dims(256, 128, 64), dropout0.2): super(WideDeep, self).__init__() # Wide部分线性模型 self.wide nn.Linear(wide_feature_dim, 1) # Deep部分的嵌入层 self.embeddings nn.ModuleList([ nn.Embedding(dim[0], dim[1]) for dim in embed_dims ]) # Deep部分的输入维度 deep_input_dim sum([dim[1] for dim in embed_dims]) # Deep部分的隐藏层 deep_layers [] for dim in hidden_dims: deep_layers.append(nn.Linear(deep_input_dim, dim)) deep_layers.append(nn.BatchNorm1d(dim)) deep_layers.append(nn.ReLU()) deep_layers.append(nn.Dropout(dropout)) deep_input_dim dim deep_layers.append(nn.Linear(deep_input_dim, 1)) self.deep nn.Sequential(*deep_layers) # 输出层 self.sigmoid nn.Sigmoid() def forward(self, wide_input, deep_input): # Wide部分 wide_out self.wide(wide_input) # Deep部分嵌入 embed_list [] for i, emb in enumerate(self.embeddings): embed_list.append(emb(deep_input[:, i])) deep_embed torch.cat(embed_list, dim1) # Deep部分DNN deep_out self.deep(deep_embed) # 组合输出 output wide_out deep_out return self.sigmoid(output) class WideDeepRecommender: def __init__(self, wide_feature_dim, deep_feature_dim, embed_dims, hidden_dims(256, 128, 64), lr0.001): self.device torch.device(cuda if torch.cuda.is_available() else cpu) self.model WideDeep(wide_feature_dim, deep_feature_dim, embed_dims, hidden_dims).to(self.device) self.optimizer torch.optim.Adam(self.model.parameters(), lrlr) self.criterion nn.BCELoss() def train_step(self, wide_input, deep_input, labels): self.model.train() self.optimizer.zero_grad() wide_input torch.FloatTensor(wide_input).to(self.device) deep_input torch.LongTensor(deep_input).to(self.device) labels torch.FloatTensor(labels).to(self.device) outputs self.model(wide_input, deep_input).squeeze() loss self.criterion(outputs, labels) loss.backward() self.optimizer.step() return loss.item() def predict(self, wide_input, deep_input): self.model.eval() with torch.no_grad(): wide_input torch.FloatTensor(wide_input).to(self.device) deep_input torch.LongTensor(deep_input).to(self.device) outputs self.model(wide_input, deep_input).squeeze() return outputs.cpu().numpy() def save(self, path): torch.save(self.model.state_dict(), path) def load(self, path): self.model.load_state_dict(torch.load(path)) # 使用示例 np.random.seed(42) # 参数设置 n_users, n_items 1000, 5000 n_samples 10000 # Wide特征原始特征 交叉特征 wide_feature_dim 100 # Deep特征类别特征 deep_feature_dim 4 embed_dims [ (n_users, 32), # user_id嵌入 (n_items, 32), # item_id嵌入 (10, 8), # category嵌入 (24, 8) # hour嵌入 ] # 创建模型 model WideDeepRecommender(wide_feature_dim, deep_feature_dim, embed_dims) print(Wide Deep模型创建成功) print(f模型参数量: {sum(p.numel() for p in model.model.parameters()):,}) print(code)wide_deep_implementation()五、Wide Deep vs 其他模型5.1 模型对比defmodel_comparison():Wide Deep与其他模型对比print(\n*60)print(Wide Deep vs 其他模型)print(*60)fig,axplt.subplots(figsize(12,8))ax.axis(off)comparison ╔════════════════════════════════════════════════════════════════════════════════╗ ║ Wide Deep vs 其他推荐模型对比 ║ ╠════════════════════════════════════════════════════════════════════════════════╣ ║ ║ ║ 模型 Wide部分 Deep部分 特点 ║ ║ ─────────────────────────────────────────────────────────────────────────────║ ║ LR ✓ ✗ 简单基线 ║ ║ FM ✓(二阶) ✗ 特征交叉 ║ ║ DeepFM ✓(一阶二阶) ✓ 端到端学习 ║ ║ Wide Deep ✓(特征交叉) ✓ 记忆泛化 ║ ║ Deep Cross ✓(Cross网络) ✓ 显式高阶交叉 ║ ║ DIN ✗ ✓(注意力) 用户兴趣建模 ║ ║ ║ ║ Wide Deep优势: ║ ║ • 同时学习记忆和泛化 ║ ║ • 可解释性强Wide部分 ║ ║ • 端到端训练 ║ ║ • Google Play推荐系统核心模型 ║ ║ ║ ║ 适用场景: ║ ║ • 推荐系统排序阶段 ║ ║ • CTR预估任务 ║ ║ • 同时需要记忆和泛化的场景 ║ ║ ║ ╚════════════════════════════════════════════════════════════════════════════════╝ ax.text(0.05,0.95,comparison,transformax.transAxes,fontsize10,verticalalignmenttop,fontfamilymonospace)plt.tight_layout()plt.show()model_comparison()六、总结组件作用输入输出Wide记忆高频模式原始交叉特征线性预测Deep泛化稀疏组合嵌入向量DNN预测组合综合预测WideDeep输出CTR概率核心公式P(y1|x) σ(w_wide^T·x_wide w_deep^T·a^{(L)} b)Wide Deep优势记忆高频特征组合Wide泛化到稀疏特征组合Deep端到端联合训练可解释性强

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑