资讯动态

基于Django与LSTM的空灵鼓销售分析与销量预测系统实战

发布时间:2026/10/13 7:33:36 来源:尧图企业网站定制
1. 为什么我选了“空灵鼓销售分析”这个题目以及它值不值得抄作业先亮个观点如果你正在找毕业设计题目或者想做一个能同时塞进 Django、大数据、深度学习三块技术栈的实战项目千万不要选那种大而全的通用电商销售分析系统恰恰是空灵鼓这种垂直细分品类反而更容易做出彩。为什么这么说我在帮某小型乐器品牌做经营数据分析时对着一堆脱敏后的订单数据想过这个问题。空灵鼓这个品类有几个非常有意思的特点SKU 少但属性维度深。一般品牌只有十几个型号但每个型号有音调D调、E调、F调等、尺寸13寸、15寸、17寸、颜色、是否带收纳包、是否含教学课程这些维度。这种结构非常适合做多维度交叉分析。用户决策周期有规律。空灵鼓客单价在中高区间用户从浏览到下单往往会经过多次比价、犹豫不像快消品那样即看即买。这意味着订单数据和用户行为数据之间存在可挖掘的转化规律。销售有季节性周期。比如节假日送礼需求、暑期音乐培训需求、年末电商大促这些周期性波动正好适合用深度学习模型做销量预测。对毕业设计来说这三个特点意味着什么意味着你有充足的理由把 Django、大数据 ETL、深度学习三块东西串起来而且每个环节都有话可说不会被答辩老师质疑为了用而用。整个系统的定位我建议提炼成一句话围绕空灵鼓业务的真实订单数据搭建一套从前端数据采集、后台仓储管理、销售多维分析到深度学习销量预测的闭环系统。底线是它必须是一个能跑起来、能演示、能解释清楚每个模块为什么存在的完整项目而不是三个技术点的生硬拼接。2. 系统整体架构Django 当枢纽但它不该扛下所有2.1 分层思路不要让 Django 既做 Web 又跑预测我见过很多学生项目把深度学习模型直接塞进 Django 的 views.py 里每次请求都现场调model.predict()结果就是接口响应时间飙到秒级页面加载卡到怀疑人生。正确的做法是分层。我当时设计的是这样一套结构层级技术选型职责数据采集层Python 爬虫脚本 后端手动录入接口抓取电商平台公开评论、商品信息录入线下渠道订单数据存储层MySQL主库 Redis缓存MySQL 存订单、商品、用户、区域维表Redis 缓存高频聚合结果业务服务层Django Django REST Framework提供管理后台、分析报表接口、权限控制分析计算层Pandas ETL 定时任务定期把原始订单表清洗成宽表、聚合表深度学习层TensorFlow / KerasLSTM 模型 FastAPI独立推理服务接收特征返回销量预测结果展示层Vue ECharts或简单用 Django 模板 AJAX销售大屏、趋势图、分布图这里 Djang 的核心价值在于它是所有数据流转的调度中枢但计算密集型的预测任务必须拆分出去。否则一旦预测请求和普通查询请求混跑Django 的线程池会被阻塞系统会变得又慢又不稳定。2.2 为什么预测服务单独用 FastAPI 而不是 Django 再开一个实例这是个很实际的问题。直接复用 Django 写一个/api/predict/接口不行吗行但有几个麻烦Django 的请求生命周期比较重中间件、认证、ORM 都要过一遍而预测接口其实只需要接收一个特征向量、返回一个数值。FastAPI 的异步能力刚好匹配这个场景。模型加载本身就吃内存如果和 Django 主服务放在同一个进程里模型对象会常驻内存。到时候 Django 一重启模型还得重新加载模型占几个 G 内存时Web 服务的内存上限也被挤占了。分开部署之后深度学习服务可以独立做 GPU 加速如果只用 CPU 推理至少也能独立扩缩容Django 这边完全无感知。所以我当时的接口设计是前端/定时任务 - Django API - FastAPI 预测服务 - 返回预测值Django 层加了一层缓存同一个商品同一个日期的预测结果在 Redis 里缓存 12 小时只有缓存未命中时才真正打到 FastAPI。这样预测接口的开销被压缩到了可接受的范围。2.3 完整目录结构直接给个可落地的参考这不是什么惊天动地的架构但胜在清晰、能跑airong_sales/ ├── manage.py ├── requirements.txt ├── config/ │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── celery.py # 定时任务配置可选 ├── apps/ │ ├── products/ # 商品管理 │ ├── orders/ # 订单管理 │ ├── analysis/ # 销售分析、报表接口 │ ├── users/ # 用户/权限管理 │ └── forecast/ # 预测任务调度 ├── scripts/ │ ├── data_collect.py # 外部数据采集 │ ├── etl_daily.py # 日级ETL清洗 │ └── train_model.py # 模型训练脚本 ├── ml_service/ # 独立深度学习推理服务 │ ├── main.py # FastAPI 入口 │ ├── model.py # LSTM模型定义 │ ├── saved_model/ # 导出后的模型文件 │ └── features.py # 特征构造 └── templates/ ├── dashboard.html ├── product_list.html └── ...核心原则是apps 之间不要互相 import通过 Django 的信号机制或消息队列通信模型训练脚本放在 scripts 目录不要塞进 app 里。这样的话哪怕答辩老师突然问如果数据量涨 10 倍你怎么改你也能把迁移到 ClickHouse 或 Spark 的方向说清楚。3. 数据链路从订单流水到分析宽表Django ORM 只是最后一公里3.1 原始数据从哪来爬虫 接口 模拟数据三路并行真实项目里不可能有现成的数据集。我当时处理了三路数据来源爬虫脚本采集抓取某主流电商平台公开的空灵鼓商品标题、价格、评论数、销量区间等公开展示信息用于分析竞争对手定价和热度趋势。注意只采集合法公开的数据不能涉及用户隐私、不能突破平台访问限制。品牌方脱敏订单数据某乐器品牌提供的脱敏订单记录订单号已替换、用户昵称已匿名化字段包括下单时间、SKU、数量、金额、省份城市、渠道来源。系统自填模拟数据对于明显缺失的时间段比如非促销日用合理范围内的随机函数插值补齐保证时间序列的连续性。这一点在做深度学习预测时特别关键——模型最怕中间断档。这里要提醒一下如果你是完全自己模拟数据也要注意合理性。比如周一到周五的销量普遍低于周末618、双11 附近要有明显的尖峰价格高的型号销量低但销售额贡献不一定低。模型的预测表现很大程度上取决于训练数据的规律是否真实。3.2 核心表结构订单表该怎么设计用 Django 的models.py定义订单模型时很多新手会犯一个错误把所有维度都塞进一张大表。但在数据分析场景下我们反而需要把订单表设计成偏日志结构的宽表便于后期直接用 SQL 聚合。我实际用的核心模型结构大致是这样from django.db import models from django.utils import timezone class SaleOrder(models.Model): 销售订单主表 order_no models.CharField(max_length64, uniqueTrue, verbose_name订单号) product models.ForeignKey(products.Product, on_deletemodels.PROTECT, verbose_name商品) province models.CharField(max_length32, db_indexTrue, verbose_name省份) city models.CharField(max_length32, verbose_name城市) channel models.CharField(max_length16, choices( (tmall, 天猫), (jd, 京东), (douyin, 抖音), (offline, 线下门店), (manual, 手动录入),), verbose_name渠道) quantity models.PositiveIntegerField(default1, verbose_name数量) amount models.DecimalField(max_digits10, decimal_places2, verbose_name实付金额) cost models.DecimalField(max_digits10, decimal_places2, verbose_name成本) order_time models.DateTimeField(db_indexTrue, verbose_name下单时间) is_refunded models.BooleanField(defaultFalse, verbose_name是否退款) created_at models.DateTimeField(defaulttimezone.now, verbose_name记录创建时间) class Meta: db_table sale_order indexes [ models.Index(fields[order_time, province]), models.Index(fields[product, order_time]), ]几个细节值得展开说说金额字段必须用 DecimalField不能直接用 FloatField。Float 在 Python 和 MySQL 中出现精度漂移做金额汇总时会差几分钱答辩时被问数据处理精度问题会很难看。订单时间加db_indexTrue并且组合索引(product, order_time)。这个组合索引是专门为销量预测取数准备的因为模型训练需要某个商品按天汇总的销量序列如果没有这个索引千万级订单表的查询会慢到不可用。渠道字段先留好枚举分析报表里按渠道分组是基本操作不要等表数据都录完了再加字段。商品表相对简单但要包含category、tuning音调、size、price、cost这样的属性字段因为后面做价格带分析和属性交叉分析时都要用到。3.3 ETL 清洗建立日级销售聚合宽表原始订单表不适合直接喂给模型也不适合频繁聚合查询。我设计了一个每日定时 ETL 任务用 Celery beat 或系统的 crontab 都行把sale_order清洗成daily_sales_summary宽表import pandas as pd from django.db import connection def daily_etl(execute_date): 按日汇总订单数据写入 daily_sales_summary 宽表 query SELECT product_id, DATE(order_time) AS dt, COUNT(*) AS order_cnt, SUM(quantity) AS sales_cnt, SUM(amount) AS sales_amount, SUM(cost) AS total_cost, COUNT(DISTINCT province) AS province_cnt FROM sale_order WHERE DATE(order_time) %s AND is_refunded 0 GROUP BY product_id, DATE(order_time) with connection.cursor() as cursor: cursor.execute(query, [execute_date]) rows cursor.fetchall() df pd.DataFrame(rows, columns[ product_id, dt, order_cnt, sales_cnt, sales_amount, total_cost, province_cnt ]) # 增量写入宽表使用 INSERT ... ON DUPLICATE KEY UPDATE from apps.analysis.models import DailySalesSummary for _, r in df.iterrows(): DailySalesSummary.objects.update_or_create( product_idr[product_id], dtr[dt], defaults{ order_cnt: r[order_cnt], sales_cnt: r[sales_cnt], sales_amount: r[sales_amount], total_cost: r[total_cost], province_cnt: r[province_cnt], } ) print(f[ETL] {execute_date} 完成共处理 {len(df)} 条记录)这个 ETL 有很多可以丰富的地方比如增加退款率字段用于衡量渠道质量增加前一日销量、前7日平均销量这样的滞后特征方便深度模型直接使用对省市区字段做归一化清洗处理广东省和广东这种同义异写增加节假日标记是否周末、是否双11、是否双12这是预测模型非常关键的外部特征。3.4 Redis 缓存策略让聚合页面从 3 秒压到 200 毫秒销售分析大屏通常要展示近30天总销售额、各省份销售额排行、各渠道占比等聚合指标。如果每次都从订单明细表去 GROUP BY数据量一大Django 的 ORM 查询会非常吃力。我的做法是在 Django 的 service 层加一层 Redis 缓存装饰器。import json from django.core.cache import cache def get_sales_overview(days30): 获取销售总览数据优先走缓存 cache_key fanalysis:sales_overview:{days} cached cache.get(cache_key) if cached: return json.loads(cached) # Redis 未命中走 MySQL 聚合查询 result DailySalesSummary.objects.filter( dt__gtetimezone.now().date() - timezone.timedelta(daysdays) ).aggregate( total_salesmodels.Sum(sales_amount), total_order_cntmodels.Sum(order_cnt), total_refund_cntmodels.Sum(refund_cnt), ) cache.set(cache_key, json.dumps(result, defaultstr), timeout3600) return result注意几点缓存 key 要带上查询参数缓存 value 统一用 JSON 序列化缓存时间根据数据更新频率来定——订单实时进来但日级汇总每天只更新一次所以timeout36001小时是安全选择。不要在 Django 里直接操作 Redis 的 String 类型要用cache抽象层这样以后从本地 Redis 换成云 Redis 或内存缓存代码不用改。4. 深度学习销量预测为什么选了 LSTM以及怎么把模型变成可用的服务4.1 选型逻辑LSTM 不是最时髦的但是最合适的说实话用 Transformer 做时间序列预测在 2025 年已经是常规操作了但我在这个项目里最终选了 LSTM有几个考量数据量不支持复杂模型。空灵鼓这个品类单个 SKU 每天一条销量记录一年也就 365 条样本。LSTM 在这种小样本时间序列上的表现比 Transformer 稳定得多。可解释性。答辩时老师大概率会问你为什么选这个模型LSTM 的门控机制很好讲——遗忘门决定记住多少历史信息、输入门决定写入多少新信息几句话就能讲明白。Transformer 要让老师理解注意力机制在时间序列里怎么用解释成本高很多。部署成本低。LSTM 的参数量通常在几万级别CPU 推理延迟在毫秒级而一个小型 Transformer 参数量动辄百万级推理耗时明显更高对毕业设计的演示环境不友好。当然我也在论文里做了 ARIMA 和 LSTM 的对比实验。ARIMA 对线性趋势、季节性有优势但对促销尖峰、节假日效应这类非线性变化非常迟钝。LSTM 虽然训练时间长一点但在 MAPE平均绝对百分比误差上通常比 ARIMA 低 3 到 5 个百分点。4.2 特征构造滑窗 外部特征这是预测效果的分水岭模型选得再好特征构造乱七八糟也白搭。我设计的特征分三类第一类历史销量序列特征前 1 天、前 3 天、前 7 天、前 14 天的销量前 7 天的移动平均值和标准差前 28 天的周同比。第二类日历特征星期几独热编码是否节假日是否大促日618、双11 前后 3 天标记为 1月份捕捉季节性。第三类商品属性特征价格带档位低价、中价、高价是否新品上架天数小于 30 视为 1音调类型编码。训练数据的构造方式是滑窗用前 28 天的数据预测后 1 天。我用 pandas 实现了一个简单的窗口切片函数import numpy as np import pandas as pd def build_sequences(df, window28): 把日销量 df 转换成 (X, y) 序列样本 X, y [], [] for i in range(window, len(df)): X.append(df.iloc[i-window:i].values) y.append(df.iloc[i][sales_cnt]) return np.array(X, dtypenp.float32), np.array(y, dtypenp.float32)注意归一化必须用训练集的均值和标准差来归一化验证集和测试集不能整体归一化。这是新手最容易犯的错——整体归一化相当于把未来的信息泄露到了训练过程里测试指标会虚高。4.3 模型结构极简 LSTM不加花活from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout def build_lstm_model(input_shape): model Sequential([ LSTM(64, return_sequencesTrue, input_shapeinput_shape, activationtanh), Dropout(0.2), LSTM(32, return_sequencesFalse, activationtanh), Dropout(0.2), Dense(16, activationrelu), Dense(1, activationlinear), # 回归任务输出预测销量 ]) model.compile(optimizeradam, lossmse, metrics[mae]) return model这个结构一共就五层训练很快。return_sequencesTrue是为了让第一层 LSTM 输出的完整序列进入第二层最后一层用linear激活函数不做任何压缩因为销量预测是回归任务而不是分类任务不能用 sigmoid。训练时我加了 EarlyStopping 回调from tensorflow.keras.callbacks import EarlyStopping early_stop EarlyStopping( monitorval_loss, patience10, restore_best_weightsTrue ) model.fit( X_train, y_train, validation_data(X_val, y_val), epochs100, batch_size16, callbacks[early_stop], verbose1 )4.4 模型部署导出 SavedModel用 FastAPI 包一层训练完成后把模型导出成 SavedModel 格式model.save(ml_service/saved_model/airong_lstm_v1)然后在ml_service/main.py里写一个轻量级推理接口from fastapi import FastAPI from pydantic import BaseModel import numpy as np import tensorflow as tf app FastAPI() model tf.keras.models.load_model(saved_model/airong_lstm_v1) class PredictRequest(BaseModel): features: list[float] # 长度必须等于模型 input_shape[1] app.post(/predict) def predict(req: PredictRequest): x np.array([req.features], dtypenp.float32) pred model.predict(x, verbose0)[0][0] return {predicted_sales: round(float(pred), 2)}Django 这边的调用方式也很简单import requests def call_predict_service(features: list[float]): resp requests.post(http://127.0.0.1:8001/predict, json{features: features}, timeout10) return resp.json()[predicted_sales]这里有几个生产级的细节模型在 FastAPI 启动时就加载不要放在请求函数里加载否则每个请求都会加载一次模型慢到崩溃。给 requests 调用加超时。FastAPI 推理服务如果挂了Django 的请求不能无限等待必须快速失败并降级到历史平均值。预测接口要做简单的输入校验。pydantic的BaseModel其实已经做了类型约束但业务上还要检查特征长度是否正确否则模型会报维度错误。4.5 模型评估不要只看 LossLoss 是训练指标答辩时老师更关心预测效果。我做了两个辅助指标MAPE平均绝对百分比误差mean(abs((y_true - y_pred) / y_true)) * 100用来描述平均预测偏差百分之多少。误差可视化把测试集里预测值和真实值画成折线对比图一张图胜过千言万语。实际跑下来单 SKU 的销量预测 MAPE 大概在 12% 到 18% 之间对毕业设计来说完全够用。答辩时如果老师问为什么误差 15% 这么大你可以解释销量本身存在随机波动尤其是大促日的极端值很难预测而且 15% 是百分误差如果日销量是 20 台15% 的误差只有 3 台绝对值并不大。5. 可视化与分析报表Django 只提供数据接口图表交给 ECharts5.1 销售大屏四块核心图表可视化是毕业设计最容易出彩的部分。我的销售分析大屏包含四块核心图表全部用 ECharts 渲染图表类型数据来源近30天销售趋势折线图单轴折线daily_sales_summary按日期汇总各省份销售额热力地图地图订单表按省 group by各渠道销售占比饼图饼图订单表按渠道 group by价格带销量分布柱状图柱状图商品表按价格区间分桶Django 这边的接口只需要按维度返回 JSONfrom django.db.models import Sum from django.http import JsonResponse from apps.analysis.models import DailySalesSummary def trend_data(request, days30): data ( DailySalesSummary.objects .filter(dt__gtetimezone.now().date() - timezone.timedelta(daysdays)) .values(dt) .annotate(totalSum(sales_amount)) .order_by(dt) ) return JsonResponse({dates: [d[dt].strftime(%m-%d) for d in data], totals: [float(d[total]) for d in data]})ECharts 前端代码不做展开核心就一句话接口返回什么结构前端就渲染什么结构。把接口先按前端需要的格式设计好比前端迁就后端省事一百倍。5.2 分析报表用 Django 后台 自定义视图组合销售分析系统除了可视化大屏还要有可供管理层查看的详细报表。我实现了三个核心页面商品销售排行页展示每个 SKU 的销量、销售额、毛利率、周环比增长率。毛利率字段是(amount - cost) / amount在 ORM 里用F表达式计算避免把数据拉到内存再算。from django.db.models import F, ExpressionWrapper, FloatField qs Product.objects.annotate( gross_marginExpressionWrapper( (F(recent_amount) - F(recent_cost)) / F(recent_amount), output_fieldFloatField() ) )区域销售明细页点击省份可以下钻到城市点击城市可以再下钻到门店或渠道。这个下钻逻辑在接口上加一个level参数就行前端用 drilldown 事件监听。促销效果对比页把大促前后各 7 天的销量做成对比柱状图计算促销提升率 大促期日均销量 - 平时日均销量/ 平时日均销量。这个指标在论文里很有价值因为它把深度学习预测和业务分析串起来了——你可以用预测模型模拟如果没有促销销量会是多少从而客观评估促销的真实拉动效果。5.3 数据导出的隐藏加分项很多同学做到可视化就停了。但我想建议你补一个Excel 报表导出功能用openpyxl或pandas生成带格式的 xlsx 文件。理由有两个答辩演示的时候从系统内导出本月销售报表更像一个真实可用的系统论文里可以写一句系统支持按渠道、按区域、按商品导出多维报表满足业务人员的离线分析需求技术完整性直接上一个档次。6. 论文版块怎么编排从目录到答辩问题都替你梳理了一遍6.1 一个能站得住的论文目录论文不是把系统介绍一遍就完了要有技术逻辑线。我建议按下面这个目录走第1章 绪论 1.1 研究背景与意义 1.2 国内外研究现状 1.3 主要研究内容 第2章 相关技术基础 2.1 Django 框架 2.2 MySQL 与 Redis 2.3 深度学习时间序列预测方法 2.4 大数据分析处理流程 第3章 系统需求分析与总体设计 3.1 可行性分析 3.2 功能需求分析 3.3 系统总体架构设计 3.4 数据库设计 第4章 系统详细设计与实现 4.1 数据采集与 ETL 实现 4.2 销售分析模块实现 4.3 销量预测模块实现 4.4 可视化大屏实现 第5章 系统测试与结果分析 5.1 功能测试 5.2 性能测试 5.3 预测模型对比实验 第6章 总结与展望注意我标注的细节对比实验放第 5 章不要放第 4 章。第 4 章讲我做了什么第 5 章讲做出来的东西效果如何、好在哪里。答辩老师听到你在第 5 章给出 ARIMA vs LSTM 的实验数据一般都会点头认可。6.2 答辩时最可能被问到的技术问题我复盘了一下真实答辩场景高频问题集中在下面几类为什么用 LSTM 不用 Transformer→ 答数据量小、可解释性强、部署成本低。这是加分问题不是扣分问题因为你自己已经在论文里做了对比实验。订单数据从哪来是你的真实数据吗→ 如实回答脱敏数据 爬虫公开数据 模拟数据。如果完全没接触过真实数据就说基于某小型乐器品牌脱敏订单数据搭建并对缺失部分做了合理模拟。Django 性能瓶颈在哪里怎么优化→ 答ORM 懒加载导致的 N1 查询、聚合查询慢。优化用select_related/prefetch_related解决 N1用 Redis 缓存聚合结果必要时用RawSQL。如果数据量达到亿级这套架构还适用吗→ 答当前架构定位是千万级以内亿级需要引入分布式数仓如 ClickHouse 或 StarRocks做预聚合Django 只负责读数仓结果。这是个开放性问题考察的是你有没有想过扩容路径。预测模型的输入特征具体是什么→ 把滑窗长度、外部特征列出来讲清楚每个特征的含义。能把这个讲清楚深度学习这块基本稳了。6.3 答辩演示的节奏建议演示别一上来就打开大屏。建议按这个顺序来先登录系统展示后台订单管理页给老师看数据是真的在流动展示 ETL 日志或定时任务记录说明数据从原始表到宽表的处理过程打开销售大屏讲解各图表含义打开预测页面输入一个商品展示预测销量并与近期真实销量折线对比打开促销分析页用预测模型解释没促销会怎样。整个过程控制在 10 到 15 分钟。每一步的技术点都提前准备好话术别等老师问了才临时翻代码。7. 踩坑记录这五个坑我替你踩过了照着避开就行7.1 Python 环境不一致导致模型加载失败本地明明能跑部署到服务器上就报OpKernel错误。查了半天发现是 TensorFlow 版本不一致本地 2.10服务器 2.4。建议把requirements.txt严格锁版本Django4.2.7 djangorestframework3.14.0 tensorflow-cpu2.13.0 fastapi0.104.1 uvicorn0.24.0 pandas2.0.3 numpy1.24.3 mysqlclient2.2.0 redis5.0.1 openpyxl3.1.2尤其是tensorflow-cpu服务器没有 GPU 时务必装 CPU 版官方完整版会尝试调 CUDA 然后报错。7.2 时区问题MySQL 和 Django 的时间差了 8 小时Django 默认USE_TZ True存数据库的是 UTC 时间而业务上一看下单时间全偏了。解决数据库连接配置里加时区或者统一改用本地时间。我的做法是USE_TZ FalseTIME_ZONE Asia/Shanghai因为这是一个纯国内业务系统没有跨时区需求关掉 UTC 转换反而省心。如果你的系统要出海再按原样用 UTC 并在展示层转换。7.3 Redis 缓存雪崩所有 key 同一时间过期我在缓存设计时把所有聚合查询的timeout都设成了 600 秒结果每天整点一批 key 集中过期所有请求瞬间打到 MySQL数据库负载飙升。解决过期时间加一个随机抖动比如timeout3600 random.randint(0, 300)。这也是业界通用做法。7.4 订单数据里的脏数据退款订单和测试订单混入统计有些订单已经标记退款但金额依然被计入销售总览还有测试阶段手动创建的金额为 0.01 元的垃圾订单。解决在 ETL 层统一过滤is_refundedFalse且amount 0。在 Django 的 QuerySet 里也加默认过滤条件class SaleOrderManager(models.Manager): def get_queryset(self): return super().get_queryset().filter(is_refundedFalse, amount__gt0)这个 Manager 一加所有调用方自动排除无效订单不用每个查询都写一遍过滤条件。7.5 深度学习模型的季节性特征表达不足刚开始做预测时只用了历史销量和星期特征节假日尖峰完全预测不到。后来才意识到对空灵鼓这个品类国庆、双11、年末送礼季的销量可能是平日的 3 到 5 倍这种尖峰光靠滑窗历史数据是学不出来的。解决在特征里加is_holiday、is_promotion、days_to_promotion距离大促还有几天这些手工构造的外部特征。加了之后 MAPE 从 22% 降到了 16% 左右效果立竿见影。8. 这套系统还能怎么延伸给有想法的人留的四个后续方向用户画像与复购分析。利用订单里的用户维度信息脱敏后做 RFM 模型分析识别高价值客户、流失风险客户。这是电商分析系统的天然延伸能用到聚类算法又是一章论文素材。实时数据接入。把爬虫模块改成消息队列生产者订单数据入队后由消费者实时写入Django 侧用 WebSocket 推送大屏实时更新。这一套改完就是完整的实时数仓 Demo。更细粒度的预测。当前预测是日级、SKU 级可以下钻到渠道级、城市级。特征加入渠道渗透率、城市 GDP 等外部数据后模型精度还有提升空间。成本分析模块。订单表里已经有成本和利润字段加入 ABC 分类法输出哪些商品贡献了 80% 的利润对业务更有参考价值。我的个人建议是如果时间充裕优先做第 1 个方向用户画像因为它独立性强、和现有数据不冲突、答辩时能展示的内容最丰富。如果时间紧张保住当前系统的完整演示链路就够了别在答辩前两周临时加功能。最后说说我几个月折腾下来的真实体会吧。这个项目最困难的地方不在于 Django 怎么写、模型怎么调而在于把三个技术栈组装成一个看起来本来就该长这样的系统。数据要从采到存、从清洗到聚合、从分析到预测每一层之间都要有清晰的接口。当你把这条链路跑通的那一刻你收获的不仅仅是一个毕业设计而是一套拿到真实业务数据也知道该从哪里下手的分析方法论。这才是这个项目真正值钱的地方。

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

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

免费获取报价 →
↑