ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

淘宝用户行为预测系统:Django+深度学习+ECharts大屏实战

淘宝用户行为预测系统:Django+深度学习+ECharts大屏实战 简介这份资源是面向高校计算机相关专业毕业设计的完整项目源码包围绕淘宝用户购物行为可视化与预测展开适合正在准备毕设或需要Django与深度学习实战案例的学生参考。项目以Python与Django搭建后端前端结合Vue、JavaScript与ECharts类可视化库呈现用户行为图表深度学习部分借助TensorFlow或PyTorch构建神经网络对历史购物数据进行训练与预测并配套MySQL等数据库完成数据存储与管理。压缩包共174个文件约34.71MB包含30个py后端脚本、21个vue与26个js前端文件、41张jpg与25张png界面截图、1个mp4演示视频以及sql建表脚本、bat启动脚本和依赖jar包等覆盖数据收集、清洗、模型训练、预测与可视化多个模块。已有56人学习下载可帮助读者快速理解系统整体架构、模块划分与前后端交互方式并对照演示视频验证预测效果与界面流程。1. 淘宝用户行为预测系统从原始日志到可视化大屏的完整落地路径淘宝用户行为数据是典型的电商时序日志一天几千万条点击、收藏、加购、购买记录字段稀疏、正负样本极度不平衡。很多同学做毕业设计时卡在同一个地方数据爬下来或拿到公开数据集后不知道该怎么把 Django 后端、深度学习模型和可视化大屏串成一条能跑通的链路。这个标题指向的正是这套组合方案——用 Django 做服务端和接口层用深度学习模型对用户购买行为做预测再把预测结果和统计指标通过 ECharts 可视化大屏呈现出来。它适合正在做电商方向毕业设计、需要一套可演示可复现系统的同学也适合想了解推荐/预测类系统前后端如何衔接的初中级工程师。核心难点不在模型多深而在数据管道、特征工程和服务集成的工程细节。2. Django 承接深度学习预测服务的架构选型与数据管道2.1 为什么用 Django 而不是 Flask/FastAPI 做这套系统电商行为预测系统不只是推理接口它还要管理用户表、商品表、行为日志表、预测结果表还要提供后台管理、权限控制和模板渲染。Django 自带 ORM、Admin、认证体系和迁移工具这些在毕业设计周期内能省掉大量重复代码。Flask 更轻但你要自己拼 SQLAlchemy、Flask-Login、Flask-Admin工作量反而更大。FastAPI 异步性能好适合纯推理服务但它的生态在后台管理和模板渲染上不如 Django 成熟。常见做法是 Django 负责业务逻辑和数据持久化深度学习推理部分单独封装成一个 Python 模块或独立进程通过函数调用或本地 HTTP 接口通信。不要一上来就把模型塞进 Django 的 view 里同步执行那样一个预测请求会阻塞整个 worker。我一般会先把模型加载到全局变量或单例对象中避免每次请求都重新加载权重。数据管道方面淘宝用户行为公开数据集通常包含 user_id、item_id、category_id、behavior_type、timestamp 五个核心字段。behavior_type 一般用 1 到 4 表示点击、收藏、加购、购买。原始数据需要先做时间戳解析、行为类型编码、用户和商品 ID 重映射再按时间窗口切分训练集和测试集。import pandas as pd import numpy as np # 读取原始行为日志假设为 CSV 格式 df pd.read_csv(user_behavior.csv, dtype{ user_id: np.int32, item_id: np.int32, category_id: np.int32, behavior_type: np.int8, timestamp: np.int64 }) # 时间戳转 datetime并提取小时、星期特征 df[datetime] pd.to_datetime(df[timestamp], units) df[hour] df[datetime].dt.hour df[weekday] df[datetime].dt.weekday # 行为类型映射点击0收藏1加购2购买3 behavior_map {1: 0, 2: 1, 3: 2, 4: 3} df[behavior_enc] df[behavior_type].map(behavior_map) # 按时间排序构造滑动窗口样本 df df.sort_values([user_id, datetime]).reset_index(dropTrue) # 标记每个用户是否在后续窗口内产生购买行为 df[is_buy] (df[behavior_enc] 3).astype(np.int8) # 保存预处理结果 df.to_parquet(behavior_processed.parquet, indexFalse) print(f处理后样本数: {len(df)}, 购买正样本比例: {df[is_buy].mean():.4f})这段代码做了四件事类型压缩减少内存占用、时间特征提取、行为编码统一、按用户和时间排序。参数上注意 dtype 指定user_id 和 item_id 用 int32 足够timestamp 必须用 int64否则 2038 年之后的时间戳会溢出。behavior_map 的映射关系要和后续模型输出层对应购买行为对应类别 3这是二分类还是多分类的分界点。如果只做购买预测可以把问题简化为二分类把收藏和加购作为辅助特征而不是独立类别。2.2 深度学习模型选型CNN、LSTM 还是 Transformer淘宝用户行为序列本质是变长时序数据每个用户的行为序列长度从几条到几千条不等。常见做法有三种把行为序列当作一维信号用 CNN 提取局部模式用 LSTM/GRU 建模长期依赖或者用 Transformer 的自注意力机制捕捉全局关系。毕业设计周期内我建议优先选 LSTM 或 GRU原因是实现简单、训练稳定、参数量可控在中等规模数据上效果足够。如果一定要用 CNN注意它更适合固定窗口的局部特征提取比如把最近 50 次行为作为一个样本用一维卷积核在时间维度上滑动。Transformer 虽然效果好但训练需要更多数据和算力调参成本高容易在毕业设计后期翻车。模型输入通常包括三类特征用户侧特征年龄、性别、历史购买频次、商品侧特征类别、价格区间、历史点击率、行为序列特征最近 N 次行为的 item_id 和 behavior_type 嵌入。输出层用 sigmoid 做二分类预测未来一段时间内是否购买。import torch import torch.nn as nn class BehaviorLSTM(nn.Module): def __init__(self, item_vocab_size, behavior_vocab_size, embed_dim64, hidden_dim128): super().__init__() # item 和 behavior 分别嵌入后拼接 self.item_embed nn.Embedding(item_vocab_size, embed_dim, padding_idx0) self.behavior_embed nn.Embedding(behavior_vocab_size, embed_dim, padding_idx0) self.lstm nn.LSTM( input_sizeembed_dim * 2, hidden_sizehidden_dim, num_layers2, batch_firstTrue, dropout0.3, bidirectionalFalse ) self.classifier nn.Sequential( nn.Linear(hidden_dim, 64), nn.ReLU(), nn.Dropout(0.3), nn.Linear(64, 1), nn.Sigmoid() ) def forward(self, item_seq, behavior_seq, lengths): item_emb self.item_embed(item_seq) # (B, L, D) beh_emb self.behavior_embed(behavior_seq) # (B, L, D) x torch.cat([item_emb, beh_emb], dim-1) # (B, L, 2D) packed nn.utils.rnn.pack_padded_sequence( x, lengths.cpu(), batch_firstTrue, enforce_sortedFalse ) out, (h, c) self.lstm(packed) # 取最后一个时间步的隐藏状态 last_hidden h[-1] # (B, hidden_dim) return self.classifier(last_hidden).squeeze(-1)模型结构说明item_embed 和 behavior_embed 的 vocab_size 要根据实际数据统计得出padding_idx0 表示填充位不参与梯度更新。LSTM 用两层、hidden_dim128 是中等规模数据的常用配置dropout0.3 防止过拟合。pack_padded_sequence 处理变长序列避免填充位影响最终隐藏状态。输出层 sigmoid 后得到 0 到 1 之间的购买概率。训练时用 BCELoss正负样本比例悬殊时加 pos_weight 或改用 Focal Loss。参数调整上embed_dim 从 32 到 128 都可以试hidden_dim 一般取 embed_dim 的 2 到 4 倍。序列长度截断到最近 50 或 100 次行为太长的序列对 LSTM 反而是一种负担。学习率用 1e-3 配合 Adam 优化器batch_size 根据显存调整一般 128 或 256。3. 从模型输出到 ECharts 可视化大屏的接口设计3.1 Django 中集成模型推理的三种方式与性能对比把 PyTorch 模型集成到 Django 里有三种常见方式。第一种是直接在 view 里 import 模型并调用简单但每次请求都要走一遍前向传播并发高时 CPU 打满。第二种是在 Django 启动时用 AppConfig.ready() 加载模型到全局变量请求时直接调用省去加载时间。第三种是把推理服务拆成独立进程Django 通过本地 socket 或 HTTP 调用适合模型大、需要 GPU 隔离的场景。毕业设计推荐第二种实现简单且性能可接受。注意 AppConfig.ready() 里不要做耗时太长的操作否则 Django 启动会变慢。模型加载放在 ready() 里用 torch.no_grad() 包裹推理过程避免计算图累积。# apps/prediction/apps.py from django.apps import AppConfig import torch import os class PredictionConfig(AppConfig): default_auto_field django.db.models.BigAutoField name apps.prediction model None def ready(self): if os.environ.get(RUN_MAIN) ! true: return from .model import BehaviorLSTM model_path os.path.join(os.path.dirname(__file__), weights, lstm_best.pt) self.model BehaviorLSTM(item_vocab_size50000, behavior_vocab_size4) self.model.load_state_dict(torch.load(model_path, map_locationcpu)) self.model.eval() print(预测模型加载完成)这里用 RUN_MAIN 环境变量判断避免 Django 开发服务器自动重载时重复加载模型。生产环境用 gunicorn 时不需要这个判断但加上也无害。model.eval() 切换 dropout 和 batch norm 到推理模式这一步漏掉会导致预测结果不稳定。3.2 预测结果落库与 ECharts 大屏数据接口预测结果需要持久化到数据库方便后续统计和展示。建一张 prediction_result 表字段包括 user_id、item_id、predict_score、predict_time、model_version。每次批量预测后写入前端通过 Django 的 JsonResponse 或 DRF 接口拉取聚合数据。ECharts 大屏通常需要四类数据购买概率分布直方图、不同品类购买率对比、用户行为漏斗图、时间趋势折线图。这些数据可以在 Django 里用 ORM 聚合查询得到也可以用 Pandas 在内存中计算后返回 JSON。# apps/prediction/views.py from django.http import JsonResponse from django.db.models import Avg, Count, Q from .models import PredictionResult import json def dashboard_data(request): # 购买概率分布按 0.1 区间分桶 buckets [] for i in range(10): low, high i / 10, (i 1) / 10 cnt PredictionResult.objects.filter( predict_score__gtelow, predict_score__lthigh ).count() buckets.append({range: f{low:.1f}-{high:.1f}, count: cnt}) # 品类购买率按 category_id 分组求平均预测分 category_stats ( PredictionResult.objects .values(category_id) .annotate(avg_scoreAvg(predict_score), totalCount(id)) .order_by(-avg_score)[:10] ) # 行为漏斗从原始行为表统计点击、收藏、加购、购买人数 from apps.behavior.models import UserBehavior funnel { click: UserBehavior.objects.filter(behavior_type1).values(user_id).distinct().count(), fav: UserBehavior.objects.filter(behavior_type2).values(user_id).distinct().count(), cart: UserBehavior.objects.filter(behavior_type3).values(user_id).distinct().count(), buy: UserBehavior.objects.filter(behavior_type4).values(user_id).distinct().count(), } return JsonResponse({ buckets: buckets, category_stats: list(category_stats), funnel: funnel }, json_dumps_params{ensure_ascii: False})接口逻辑说明分桶统计用 predict_score__gte 和 __lt 做范围过滤注意边界处理最后一个桶要包含 1.0。品类统计用 values annotate 做分组聚合取平均预测分最高的前 10 个品类。漏斗数据从原始行为表统计去重用户数四个阶段的人数递减关系能直观反映转化流失。json_dumps_params 设置 ensure_asciiFalse 保证中文正常返回。前端 ECharts 配置里直方图用 bar 类型品类对比用横向 bar 或 radar漏斗图用 funnel 类型趋势图用 line。数据通过 fetch 或 axios 从 Django 接口拉取注意跨域问题在开发阶段用 django-cors-headers 解决。4. 避坑与排查数据泄漏、显存溢出和接口超时的血泪经验4.1 训练集和测试集按时间切分不要随机切分现象模型在验证集上 AUC 达到 0.95上线后预测结果一塌糊涂。原因随机切分导致未来信息泄漏到训练集模型学到了“未来行为”这种不该有的特征。解决按时间戳排序前 80% 做训练后 20% 做测试。如果要做时间序列交叉验证用 expanding window 方式每次用历史数据预测下一段时间。4.2 变长序列 padding 后忘记传 lengths现象LSTM 训练 loss 震荡不收敛预测结果对所有用户几乎一样。原因pack_padded_sequence 需要真实长度如果全部传最大长度填充位会参与隐藏状态计算稀释有效信号。解决在 Dataset 的 collate_fn 里返回每个样本的真实长度训练和推理时都传入 lengths 参数。注意 enforce_sortedFalse 让 PyTorch 内部自动排序不需要手动按长度降序排列。4.3 Django 开发服务器自动重载导致模型重复加载现象启动 runserver 后控制台打印两次“模型加载完成”内存占用翻倍。原因Django 开发服务器默认开启自动重载主进程和子进程都会执行 AppConfig.ready()。解决用 os.environ.get(RUN_MAIN) 判断只在子进程加载模型。生产环境用 gunicorn 时没有这个问题但加上判断更保险。4.4 预测接口同步执行导致请求超时现象前端调用预测接口单个请求耗时超过 30 秒Nginx 返回 504。原因在 view 里对全量用户做批量预测数据量大时 CPU 推理时间过长。解决把批量预测拆成异步任务用 Celery 或 Django 的 background task 处理接口只返回任务 ID前端轮询结果。如果不想引入 Celery可以限制单次预测的用户数量比如每次最多 100 个用户分页调用。4.5 ECharts 数据量过大导致前端卡顿现象大屏加载后浏览器卡死控制台报内存不足。原因直方图返回了上万个数据点ECharts 渲染压力大。解决后端做数据聚合直方图最多返回 20 个桶趋势图按小时或天聚合不要返回原始秒级数据。ECharts 配置里开启 large 模式或 dataZoom 做懒加载数据量超过 1000 条时用 sampling 降采样。5. 模型效果验证与可视化大屏的联动调试技巧模型训练完之后不要只看 loss 曲线就收工。我一般会做三件事第一用测试集算 AUC、F1 和 KS这三个指标比准确率更能反映排序质量。第二把预测分数分桶后看实际购买率如果分数高的桶购买率反而低说明模型学反了。第三挑几个典型用户把他们的行为序列和预测分数打印出来人工检查是否符合直觉。可视化大屏的联动调试有个小技巧先在 Django shell 里手动构造几条预测结果确认接口返回的 JSON 结构正确再调前端。前端 ECharts 的 option 配置里series 的 data 字段直接绑定接口返回的数组不要在前端做复杂计算。如果大屏数据不更新检查 Django 的缓存设置和数据库事务隔离级别确保预测结果写入后能被读到。# 模型评估脚本示例 from sklearn.metrics import roc_auc_score, f1_score import numpy as np def evaluate_model(model, test_loader): model.eval() all_preds, all_labels [], [] with torch.no_grad(): for item_seq, beh_seq, lengths, labels in test_loader: preds model(item_seq, beh_seq, lengths) all_preds.extend(preds.cpu().numpy()) all_labels.extend(labels.cpu().numpy()) all_preds np.array(all_preds) all_labels np.array(all_labels) auc roc_auc_score(all_labels, all_preds) # 以 0.5 为阈值算 F1 f1 f1_score(all_labels, (all_preds 0.5).astype(int)) # 分桶校准检查 for low in np.arange(0, 1.0, 0.2): mask (all_preds low) (all_preds low 0.2) if mask.sum() 0: print(f分数 {low:.1f}-{low0.2:.1f}: 样本数{mask.sum()}, 实际购买率{all_labels[mask].mean():.4f}) print(fAUC{auc:.4f}, F1{f1:.4f}) return auc, f1这段评估代码的关键在于分桶校准检查。如果模型输出 0.8 到 1.0 的样本实际购买率只有 0.3说明模型过度自信需要做概率校准比如 Platt scaling 或 isotonic regression。AUC 高但 F1 低说明阈值选得不好可以用验证集搜索最佳阈值。这些细节在毕业设计答辩时是加分项能体现你对模型效果的深入理解。最后说一个我踩过的坑Django 的时区设置和数据库时间戳不一致导致按小时聚合的行为趋势图偏移 8 小时。解决办法是在 settings.py 里设置 USE_TZTrue数据库存 UTC 时间前端展示时用 JavaScript 转本地时区。这个坑排查了一下午希望帮到你。本文还有配套的精品资源点击获取
返回列表