Python电商数据分析:爬虫、Django与Transformer销量预测实战
2026/9/5 8:31:34 网站建设 项目流程

很多做数据分析或后端开发的同学,其实已经知道 Python 爬虫、Django、深度学习这些技术各自是什么,也看过不少模型教程。但一旦真正接到“电商销量预测”这类任务,很快就会发现:单独懂一个环节根本不够。数据从哪来、怎么落库、怎么清洗、特征怎么做、模型用什么结构、结果给谁看,每一段都是断的。

这里有一个很容易被忽略的判断:这类项目真正决定上限的,往往不是 Transformer 模型调得有多好,而是从爬虫采集到数据后端、再到模型预测和可视化展示的整个链路能不能稳定跑通。Django 在这个链路里不只是用来做一个后台管理系统,它更像是数据整体流转的“中转站”和“治理层”。Transformer 则承担的是销量序列预测里的关键一步,但前提是前序数据已经足够干净、特征已经足够合理。

这篇文章我会以“Python 电商数据分析与销量预测”为切入点,把爬虫采集、Django 后端框架、数据分析、深度学习预测、可视化这几块放到一条完整的项目链路里讲。读完你会清楚每个环节解决什么问题、哪些坑最常出现,以及怎样把几套技术组合成一个可运行、可迭代的电商销量预测系统。本文会用偏实战的示例和代码展开,适合刚接触数据分析项目,也想往全栈型数据方向走的开发者收藏。

1. 电商销量预测为什么难在“链路”而不是“模型”

如果你只看各类算法文章,可能会以为电商销量预测的核心工作是研究模型结构,比如把 Transformer 改一改、把注意力机制调一调,预测精度就能上去。但从实际项目视角看,真正消耗精力的往往不是模型训练,而是数据链路。

一个真实的电商销量预测任务,至少要处理这样的数据流:

  1. 商品基础信息,例如 SKU、品类、价格、上下架时间。
  2. 每日销售数据,例如销量、销售额、访客数、转化率。
  3. 营销与活动数据,例如是否参加大促、折扣力度、优惠券发放时间。
  4. 外部环境数据,例如节假日、天气、竞品价格变化。

这些数据分散在多个地方。有些能通过接口或者内部报表拿到,有些需要定期采集,有些则要靠运营团队手工维护。你首先要解决的,是如何把这些零散数据变成一张干净、连续、可以喂给模型的宽表。

这里要注意一个常见误区:不要以为把销量数据直接丢给深度学习模型,模型就会自己“学到”促销、节假日等因素的影响。实际上,很多业务特征需要你显式整理出来。如果连“昨天是否参加了秒杀活动”这种字段都没有,模型就只能从历史销量的数字变化里间接猜测,预测效果自然不稳定。

所以我的判断很明确:

电商销量预测项目,百分之七八十的工作量在数据采集、数据整理和特征构造上;Transformer 之类的模型只是项目里的“最后一公里”。

理解这一点之后,你再去看爬虫、Django、pandas、Transformer 这些技术,就会有一个更清楚的定位:它们不是彼此独立的炫技工具,而是同一条流水线上的不同工序。

2. 电商销量预测的技术栈选择与整体架构

先明确这套技术组合中每一项的核心作用。

技术组件核心职责典型使用场景选择理由
Python 爬虫采集外部数据从公开渠道或自家内部系统获取商品价格、竞品数据、活动信息Python 生态完善,快速原型能力强
Django 后端框架数据建模、存储、API 服务统一管理商品、店铺、销量日表,为前端和模型提供数据接口ORM 成熟,自带 Admin,适合业务系统开发
pandas / NumPy数据清洗与特征构造缺失值处理、时间序列对齐、窗口特征计算数据分析环境的标准工具
scikit-learn基线模型与评估线性回归、随机森林、模型指标计算对比深度模型是否有真实增益
PyTorch + Transformer序列预测基于历史窗口预测未来销量能建模长距离序列依赖,适合有一定数据量的销量预测
ECharts / Matplotlib可视化展示历史销量趋势和预测结果结果可交互,适合业务沟通

从这套架构来看,项目的大致数据流是:

爬虫或接口采集数据 → pandas 清洗和特征构造 → Django ORM 入库或提供 API → PyTorch 读取历史序列训练 Transformer → 输出预测结果 → 可视化展示。

这里值得强调的是 Django 的角色。很多人学习 Django 时,只学会了写增删改查接口,但在这个项目里,Django 承担的其实是“数据治理中枢”。商品主数据、每日销量明细、预测结果、模型版本,都应该在 Django 中有对应的数据模型。这样无论是人工核查数据,还是监控模型表现,都有据可查。

再补充一个建议:项目初期不要直接上复杂架构,先做一个“最小可用链路”。先用几百行代码把一份销量 CSV 从爬虫端跑到 Django 入库,再做特征工程和简单模型预测。链路通了,再逐步替换为更完整的模块化实现,这样排错成本最低。

3. Python 爬虫在电商数据分析项目中的边界与实现

很多人看到“电商爬虫”就会想到去全网抓取商品数据,但在实际项目里,第一原则其实是合法合规。无论是爬取公开店铺数据还是内部销售数据,都应先确认你是否有权使用这些数据。优先使用官方开放接口,是最稳妥的做法。如果确实需要编写爬虫,建议只采集授权范围内的公开数据,并遵守目标网站的 robots 协议和服务条款,设置合理请求频率,不构造高频访问,不绕过访问控制。

为了方便演示,这里假设有一个由自己 Django 应用提供的统计接口,返回某店铺每日销量数据。这个接口本身可以由你控制,爬虫只是把接口数据拉下来。

# fetch_sales.py import requests import pandas as pd API_URL = "http://127.0.0.1:8000/api/sale/statistics?limit=1000" def fetch_sales(): resp = requests.get(API_URL, timeout=10) resp.raise_for_status() payload = resp.json() # 接口统一返回 {"code": 0, "data": [...]} 结构 data = payload.get("data", []) df = pd.DataFrame(data) df["date"] = pd.to_datetime(df["date"]) return df if __name__ == "__main__": sales_df = fetch_sales() print(sales_df.head()) sales_df.to_csv("sales_raw.csv", index=False, encoding="utf-8-sig")

注意这段代码里使用了raise_for_status(),只要接口返回非 2xx 状态码,程序就会直接抛出异常,避免把错误页面当成正常数据继续处理。

如果面对的是真正的外部网站,爬虫部分的复杂度会高出很多,主要问题包括请求频率控制、返回内容校验、异常重试、增量采集等。但从工程角度看,管理复杂度远高于写请求本身。通常会用一个简单的指数退避重试:第一次失败等 1 秒,第二次等 2 秒,第三次等 4 秒,直到超过最大重试次数。

还有一个很常见的问题:爬虫进程运行时没有任何报错,但也没有输出。很多初学者会看到 “Process finished with exit code 0” 就以为程序正常完成了。其实这只能说明程序没有抛出异常,并不代表数据抓取成功。很可能是目标列表本身为空,或者代码进入了一个没有打印日志的分支。排查时应该先检查 DataFrame 的行数、返回值的字段是否为空,并在关键步骤加上日志输出。

4. Django 后端设计:从数据表到 API

在电商销量预测项目中,Django 的模型设计要有“面向分析”的意识,不能只按业务系统的习惯去设计。除了记录商品基础资料,更重要的是把时间、产品、价格、促销、销量这些维度一起保存下来,方便后续做特征工程。

下面是一个精简的 Django 模型示例。假设项目名称是shop_analysis,应用名称是sales

# shop_analysis/sales/models.py from django.db import models class Product(models.Model): sku = models.CharField("SKU", max_length=64, unique=True) title = models.CharField("商品标题", max_length=255) category = models.CharField("品类", max_length=64, blank=True) price = models.DecimalField("当前价格", max_digits=12, decimal_places=2, default=0) class Meta: db_table = "sales_product" verbose_name = "商品" verbose_name_plural = "商品" def __str__(self): return self.title class DailySales(models.Model): product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name="商品") date = models.DateField("日期") sales_num = models.IntegerField("销量", default=0) price = models.DecimalField("当日价格", max_digits=12, decimal_places=2, default=0) promotion_flag = models.BooleanField("是否参与促销", default=False) page_view = models.IntegerField("访客数", default=0) order_num = models.IntegerField("下单数", default=0) class Meta: db_table = "sales_daily" verbose_name = "每日销量" verbose_name_plural = "每日销量" constraints = [ models.UniqueConstraint( fields=["product", "date"], name="uniq_product_date", ) ] def __str__(self): return f"{self.product.sku} {self.date} {self.sales_num}"

这个模型最关键的设计是UniqueConstraint(fields=["product", "date"])。它保证同一商品同一天的销量记录不会重复。后续爬虫脚本或 Excel 导入如果重复执行,不至于产生脏数据。

为了让前面爬下来的 CSV 数据进入 Django 数据库,可以使用 Django 的自定义管理命令。创建sales/management/commands/import_sales.py文件:

# shop_analysis/sales/management/commands/import_sales.py import csv from datetime import datetime from django.core.management.base import BaseCommand from sales.models import Product, DailySales class Command(BaseCommand): help = "导入每日销量 CSV 文件" def add_arguments(self, parser): parser.add_argument("csv_file", type=str) def handle(self, *args, **options): file_path = options["csv_file"] with open(file_path, newline="", encoding="utf-8-sig") as f: reader = csv.DictReader(f) for row in reader: sku = row["sku"] date = datetime.strptime(row["date"], "%Y-%m-%d").date() product, _ = Product.objects.get_or_create( sku=sku, defaults={ "title": row.get("title", sku), "category": row.get("category", ""), "price": row.get("price", 0), }, ) DailySales.objects.update_or_create( product=product, date=date, defaults={ "sales_num": int(row["sales_num"]), "price": row.get("price", 0), "promotion_flag": row.get("promotion_flag") == "1", "page_view": int(row.get("page_view", 0)), "order_num": int(row.get("order_num", 0)), }, ) self.stdout.write(self.style.SUCCESS("sales data imported"))

定义好模型和导入命令后,需要在项目根目录执行:

python manage.py makemigrations sales python manage.py migrate python manage.py import_sales sales_raw.csv

这里的update_or_create是 Django ORM 一个很实用的方法。如果记录了不存在的商品或日期,就创建;如果已经存在,则按最新数据更新,天然支持幂等导入。

接下来如果要给前端或模型训练提供数据,可以写一个简单的 Django 视图接口,返回某个商品最近 N 天的销量序列:

# shop_analysis/sales/views.py import json from django.http import JsonResponse from django.views import View from sales.models import DailySales class SaleSeriesView(View): def get(self, request): sku = request.GET.get("sku") days = int(request.GET.get("days", 60)) qs = ( DailySales.objects.filter(product__sku=sku) .order_by("date")[:days] ) data = [ { "date": item.date.strftime("%Y-%m-%d"), "sales": item.sales_num, "price": float(item.price), "promotion": item.promotion_flag, "pv": item.page_view, } for item in qs ] result = { "code": 0, "data": data, } return JsonResponse(result)

路由配置这里略过,重要的是理解这条链路:Django 把业务数据和原始爬虫数据统一管理,之后数据分析、模型训练、前端展示都可以通过这一层获取数据,避免各写各的临时脚本。

5. 数据清洗与特征工程:决定销量预测效果的上限

销量数据入库之后,并不代表可以直接训练模型。原始表里面仍有大量问题需要处理,比如促销期间的销量暴涨、缺货导致的销量为零、刷单带来的异常值,还有时间序列不连续的情况。

数据分析环节最重要的任务是构造“可学习的特征”。对于销量预测来说,不能只看“过去几天销量是多少”这一个维度的信息,还要考虑星期、节假日、促销状态、价格变化等外部信号。

这里有一个高价值的原则:构建特征时绝不能使用未来信息。典型错误是直接用当天的其他指标去预测当天的销量,比如将“当天访客数”作为训练特征。训练时模型确实可以学得很好,但真正预测未来一天时,当天的访客数根本还没有发生,这就造成了数据泄漏。

下面是一段特征构造示例,重点关注滞后特征和滚动特征的正确写法:

# make_features.py import pandas as pd def prepare_features(df: pd.DataFrame) -> pd.DataFrame: df = df.copy() df["date"] = pd.to_datetime(df["date"]) df = df.sort_values(["date"]).reset_index(drop=True) # 基础日期特征 df["dayofweek"] = df["date"].dt.dayofweek df["month"] = df["date"].dt.month df["is_weekend"] = df["dayofweek"].isin([5, 6]).astype(int) # 价格变化 df["price_lag1"] = df["price"].shift(1) # 促销会直接影响销量,但当天促销信息对未来预测不可知 # 所以这里只保留促销滞后特征,而不是直接使用当天促销字段 df["promotion_lag1"] = df["promotion_flag"].shift(1).fillna(0).astype(int) # 销量滞后与滚动统计:先 shift 再 rolling,避免使用当天数据 df["sales_lag1"] = df["sales"].shift(1) df["sales_lag7"] = df["sales"].shift(7) df["sales_ma7"] = df["sales"].shift(1).rolling(window=7).mean() df["sales_ma30"] = df["sales"].shift(1).rolling(window=30).mean() # 去掉开头没有完整历史窗口的行 df = df.dropna().reset_index(drop=True) return df

看到没有,promotion_flag没有直接作为当天的特征,而是用shift(1)转成了“前一天是否促销”。这样做的原因很简单:如果要预测未来第 1 天的销量,你通常不知道未来是否会有临时促销,至少不能假设自己一定知道。如果强行把未来促销字段填进特征,模型上线时就会面临特征缺失的尴尬。

在工程实践中,我建议把清洗和特征构造写成独立脚本,并且输出一份可核查的中间表。这样模型效果不好时,可以一层一层检查:是原始数据有问题、特征有问题,还是模型结构有问题。

6. 基于 Transformer 的销量预测实现

6.1 为什么用 Transformer 做销量预测

Transformer 最早来自自然语言处理领域,它的核心机制是自注意力。自注意力可以让序列中任意两个位置直接建立关联。对销量预测来说,这意味着模型有可能学到“半个月前的大促活动影响了当前销量”这种长距离关系,而不像普通 RNN 或 LSTM 那样依赖信息逐步传递。

但这不代表只要上 Transformer 就一定能赢。销量数据通常样本量不大,可能只有一个商品几百天的记录。在这种情况下,Transformer 容易过拟合,未必比线性回归或随机森林好。正确做法是先跑简单模型做基线,再尝试 Transformer,并比较它们在验证集上的表现。

实际项目里更常见的是把 Transformer 当作“序列编码器”,输入最近 30 天或 60 天的多变量序列,输出未来一天或未来几天的预测值。它解决的问题本质上是一个有监督回归问题。

6.2 准备序列数据集

在构造序列数据之前,我会把整个数据集按时间排序,并确保每一个商品单独构造窗口,避免把不同商品的数据混在一起。下面的代码会生成长度为window的样本,每个样本的标签是窗口之后那一天的销量。

# prepare_dataset.py import numpy as np import pandas as pd from make_features import prepare_features feature_cols = [ "sales_lag1", "sales_lag7", "sales_ma7", "sales_ma30", "dayofweek", "month", "is_weekend", "price_lag1", "promotion_lag1", ] def create_sequences(df: pd.DataFrame, window: int = 30): X, y = [], [] values = df[feature_cols].to_numpy(dtype="float32") targets = df["sales"].to_numpy(dtype="float32") for i in range(window, len(df)): X.append(values[i - window:i]) y.append(targets[i]) return np.array(X), np.array(y)

假设数据从 2023-01-01 开始,窗口为 30,则第一个样本使用 2023-01-01 到 2023-01-30 的特征,预测 2023-01-31 的销量。

训练集和测试集的划分也必须注意:不能随机打乱,而要按时间切分。比如用最后 30 天作为测试集,前面所有数据作为训练集。这样才更接近线上“预测未来”的场景。

6.3 搭建基于 PyTorch 的简单 Transformer

下面是一个基于 PyTorch 内置 TransformerEncoder 的销量预测模型。由于销量序列一般不会特别长,输入特征维度由前面的feature_cols决定,d_model可以设置为 64 或 128。

# sales_transformer.py import torch import torch.nn as nn class SalesTransformer(nn.Module): def __init__( self, feature_dim: int, d_model: int = 64, nhead: int = 4, num_layers: int = 2, dropout: float = 0.1, ): super().__init__() self.input_proj = nn.Linear(feature_dim, d_model) self.pos_embed = nn.Parameter(torch.zeros(1, 1000, d_model)) encoder_layer = nn.TransformerEncoderLayer( d_model=d_model, nhead=nhead, dropout=dropout, batch_first=True, ) self.encoder = nn.TransformerEncoder(encoder_layer, num_layers=num_layers) self.output_proj = nn.Linear(d_model, 1) self.dropout = nn.Dropout(dropout) def forward(self, x): # x shape: (batch, seq_len, feature_dim) x = self.input_proj(x) x = x + self.pos_embed[:, : x.size(1), :] x = self.dropout(x) x = self.encoder(x) # 取序列最后一个时间步的输出做预测 out = self.output_proj(x[:, -1, :]) return out.squeeze(-1)

模型结构分三段理解:

  1. input_proj把每个时间步的多维特征映射到d_model维空间。
  2. pos_embed是简单的位置编码参数,用于让模型感知时间先后顺序。
  3. TransformerEncoder负责在整个时间窗口内做自注意力编码。
  4. 预测时只取最后一个时间步的输出。

这里我使用了batch_first=True,这样输入张量形状是(batch, seq_len, feature_dim),比较容易理解。如果你的 PyTorch 版本较早,需要确认TransformerEncoderLayer是否支持batch_first参数,否则可以通过x.transpose(0, 1)调整维度。

6.4 训练与验证

训练部分建议做两件事:一是用验证集做早停,二是记录每次训练的平均绝对误差。销量数据通常有明显的数量级差异,不同商品的日销量可能从个位数到上万。如果直接使用绝对误差,大销量商品会主导损失;更稳妥的做法是根据业务需要选择误差指标。

这里以平均绝对百分比误差作为参考指标:

def mean_absolute_percentage_error(y_true, y_pred): y_true = np.asarray(y_true, dtype="float32") y_pred = np.asarray(y_pred, dtype="float32") mask = y_true != 0 return np.mean(np.abs((y_true[mask] - y_pred[mask]) / y_true[mask]))

在训练代码里,每个 epoch 完成后都要计算验证集 MAPE。如果连续多个 epoch 没有下降,则停止训练并保存最佳模型参数。这个逻辑用纯 PyTorch 写并不复杂,如果不希望自己实现,也可以直接使用 PyTorch Lightning 或 Hugging Face 的 Trainer 来管理训练循环,但理解背后的验证逻辑更重要。

Transformer 有一个比较玄学的地方:学习率稍微大一点,训练loss 就可能震荡;学习率太小又收敛太慢。实践中建议从1e-4开始,配合 AdamW 优化器,并对输入数据做标准化。

6.5 预测未来的实现策略

训练完成后,要预测未来第 1 天,只需要取最近 30 天的特征窗口,喂给模型。但如果要预测未来第 7 天,就涉及多步预测问题。一种简单的做法是滚动预测:把预测出的第 1 天销量拼接到历史窗口末尾,再重新构造特征,预测第 2 天,如此迭代。

这种方式会有误差累积,预测步数越长,可靠性越低。在项目初期,我更建议先做“未来第 1 天”的预测,等模型稳定后,再尝试多步滚动预测,并且给业务方明确说明:多步预测结果只能参考趋势,不能当作精确值。

7. 数据分析与可视化:从数字到业务判断

销量预测项目做到最后,总要回答一个问题:预测结果怎么让业务人员看懂、怎么辅助决策。这也是可视化环节存在的意义。

可视化的第一目标不是做漂亮的动态大屏,而是帮助判断模型是否合理。例如把历史真实销量和预测值画在同一张图上,如果发现模型在每次大促日都预测偏低,说明促销特征处理不到位;如果模型在断货期后出现明显偏差,说明缺失值处理逻辑需要调整。

# visualize_result.py import matplotlib.pyplot as plt import pandas as pd # 假设 test_result.csv 有三列:date, y_true, y_pred df = pd.read_csv("test_result.csv", parse_dates=["date"]) plt.figure(figsize=(12, 5)) plt.plot(df["date"], df["y_true"], label="真实销量", marker="o", markersize=3) plt.plot(df["date"], df["y_pred"], label="预测销量", marker="x", markersize=3) plt.xlabel("日期") plt.ylabel("销量") plt.title("电商销量预测结果对比") plt.legend() plt.grid(True, alpha=0.3) plt.tight_layout() plt.show()

如果后续要嵌入 Django 页面,更推荐把预测结果输出为 JSON 接口,然后在前端使用 ECharts 来绘制交互图表。这样业务人员可以缩放时间范围,也能筛选商品查看单独趋势。Django 后端只需要把datey_truey_pred组成列表返回即可,不涉及复杂的模板渲染。

可视化的另外一层价值在于异常发现。如果预测曲线和历史真实曲线长期存在系统性偏移,说明模型可能出现了数据泄漏之外的稳定性问题。电商销量会受到季节、竞争、平台流量变化等因素影响,任何模型都不可能永远准确。可视化能帮助你更快识别“什么时候该重新训练模型”,而不是等到业务反馈后才后知后觉。

8. 常见问题与排查方法

这套技术链路包含爬虫、Django、pandas、PyTorch、可视化,每一层都可能出问题。这里把实际项目中出现频率较高的问题整理成一张排查表。

问题现象可能原因排查方式解决方案
爬虫进程退出但没有输出目标接口返回空数据,程序没有日志检查返回数据的行数和字段,确认请求状态码在关键步骤添加完整日志,检查返回结构是否变化
Django 模型字段修改后迁移失败已存在数据库中数据与字段约束冲突查看python manage.py makemigrations错误信息先备份数据,调整迁移脚本,再执行 migrate
导入销量 CSV 时重复执行造成重复记录没有设置商品+日期的唯一约束检查DailySales表记录数使用UniqueConstraintupdate_or_create
预测结果严重偏低促销特征没有正确构造,或使用了未来信息检查训练和测试特征分布将促销做成滞后特征,或单独建立活动预测模型
Transformer 输入维度报错窗口长度或特征维度与模型初始化不一致打印X.shape和模型第一层维度确认输入形状为(batch, seq_len, feature_dim)
验证集 loss 低但业务效果差指标和业务目标不一致查看 MAPE、分区间误差按商品销量区间分别统计误差,调整优化目标
Django 接口返回时间字段序列化失败返回了date对象而不是字符串查看视图层对象类型使用strftime转为字符串后再放入 JSON
模型在训练集很好、测试集很差时间序列划分不当或数据泄漏检查是否随机打乱了数据必须按时间顺序切分训练集和测试集
训练 Batch 过大导致内存溢出序列窗口大且数据量大打印内存占用减小 batch size,或使用 DataLoader 分批加载

看到这里可能你已经发现,很多问题不是孤立的技术 bug,而是“数据意识”不足导致的。比如数据泄漏在生产系统中是最隐蔽的问题之一,因为它不会让程序报错,只会让模型的线下评估非常好看,上线后却一塌糊涂。排查数据泄漏时,要把训练、验证、测试三个阶段的所有特征都拿出来对比,重点检查是否存在只有未来才出现的字段。

9. 工程化部署与最佳实践

如果项目要从笔记本原型走向生产环境,有几个工程化问题必须提前考虑。

第一,数据更新要有固定节奏。可以每天凌晨用定时任务从接口拉取前一天销量,写入 Django 数据库。这个过程中要保证幂等,最好记录每次采集的任务日志,这样即便某天接口超时,也能快速定位并补采。

第二,模型训练要自动化,但不能每天盲目全量重训。电商销量数据通常是动态变化的,节假日、活动期和平日的数据分布差异很大。更合适的做法是设置每周或每两周重训练一次,并且每次重训练前先评估新旧模型在同一段验证集上的表现。只有新模型在指标上没有明显退化,才允许替换线上模型。

第三,预测结果要落库。不要只在 Jupyter Notebook 里看到结果就结束。把每次预测结果保存到 Django 数据库,同时保存模型版本号和预测日期,这样后续可以做模型效果追踪。如果三个月后业务人员反馈预测不准,你还能翻出历史记录,定位是哪一版模型、哪一段特征出了问题。

第四,依赖管理和部署环境要固定。Django 项目建议使用requirements.txtpyproject.toml固定依赖;深度学习相关依赖尤其要注意 PyTorch 和 CUDA 版本匹配。如果目标服务器没有 GPU,就先把模型参数调小一些,使用 CPU 也能完成预测任务。

第五,合规与数据安全。这一套链路涉及商品数据、价格和销量数据。如果数据来自公司内部,要注意访问权限管理和数据脱敏;如果是外部采集数据,更要严格遵守来源网站条款和法律法规。不要输出涉及个人隐私信息的数据,不要将未授权数据用于公开演示或商业用途。

从工程规范来看,建议文件结构如下:

shop_analysis/ ├── manage.py ├── shop_analysis/ │ ├── settings.py │ └── urls.py ├── sales/ │ ├── models.py │ ├── views.py │ ├── management/ │ │ └── commands/ │ │ └── import_sales.py │ └── migrations/ ├── crawler/ │ └── fetch_sales.py ├── ml/ │ ├── make_features.py │ ├── prepare_dataset.py │ ├── sales_transformer.py │ └── train.py └── dashboard/ └── visualizer.py

爬虫脚本和模型训练代码不要混在 Django 应用里,单独放在crawlerml目录,这样职责更清晰。Django 应用只负责对外提供数据落库和查询能力,模型训练任务可以独立运行。

10. 总结与后续实践路径

这篇文章把 Python 爬虫、Django 后端框架、数据分析、Transformer 销量预测和可视化整合到了同一条电商数据分析链路里。核心观点是:做销量预测不能只盯模型,而要把数据采集、数据治理、特征工程、模型训练和业务展示当作一个整体来设计。Django 在这里不是简单的后台模板,而是贯穿数据流转的中枢;Transformer 在整个项目中的价值建立在高质量数据之上,并不存在“用了 Transformer 就能解决一切”的神话。

接下来你可以按这样一个顺序去实践:

  1. 先挑选一个自己熟悉或授权的数据源,哪怕是模拟生成的销售报表,跑通“CSV → pandas → Django 入库”这条链路。
  2. 基于历史销量做简单的滞后特征,使用随机森林先训练一个基础模型并记录指标。
  3. 再用本文的 SalesTransformer 训练一个模型,对比两者的 MAPE 和误差分布。
  4. 最后把真实值和预测值可视化出来,尝试从曲线中找出模型失准的业务原因。

如果你已经有一个正在开发的电商数据分析项目,这篇文章希望帮你少走一些弯路:先建立完整的数据链路思维,再深入 Transformer 的内部细节。把基础流程固化下来之后,再去理解自注意力机制、位置编码、多步预测、模型分布式训练等等,都会更有的放矢。

后续比较值得深入研究的方向包括:基于 Transformer 的增量更新方法、如何处理多个商品之间的相关性和冷启动预测、如何在 Django 中设计模型版本管理和线上推理缓存。这些问题都是销量预测从“能跑通”走向“能上线”的关键。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询