很多做数据分析或后端开发的同学其实已经知道 Python 爬虫、Django、深度学习这些技术各自是什么也看过不少模型教程。但一旦真正接到“电商销量预测”这类任务很快就会发现单独懂一个环节根本不够。数据从哪来、怎么落库、怎么清洗、特征怎么做、模型用什么结构、结果给谁看每一段都是断的。这里有一个很容易被忽略的判断这类项目真正决定上限的往往不是 Transformer 模型调得有多好而是从爬虫采集到数据后端、再到模型预测和可视化展示的整个链路能不能稳定跑通。Django 在这个链路里不只是用来做一个后台管理系统它更像是数据整体流转的“中转站”和“治理层”。Transformer 则承担的是销量序列预测里的关键一步但前提是前序数据已经足够干净、特征已经足够合理。这篇文章我会以“Python 电商数据分析与销量预测”为切入点把爬虫采集、Django 后端框架、数据分析、深度学习预测、可视化这几块放到一条完整的项目链路里讲。读完你会清楚每个环节解决什么问题、哪些坑最常出现以及怎样把几套技术组合成一个可运行、可迭代的电商销量预测系统。本文会用偏实战的示例和代码展开适合刚接触数据分析项目也想往全栈型数据方向走的开发者收藏。1. 电商销量预测为什么难在“链路”而不是“模型”如果你只看各类算法文章可能会以为电商销量预测的核心工作是研究模型结构比如把 Transformer 改一改、把注意力机制调一调预测精度就能上去。但从实际项目视角看真正消耗精力的往往不是模型训练而是数据链路。一个真实的电商销量预测任务至少要处理这样的数据流商品基础信息例如 SKU、品类、价格、上下架时间。每日销售数据例如销量、销售额、访客数、转化率。营销与活动数据例如是否参加大促、折扣力度、优惠券发放时间。外部环境数据例如节假日、天气、竞品价格变化。这些数据分散在多个地方。有些能通过接口或者内部报表拿到有些需要定期采集有些则要靠运营团队手工维护。你首先要解决的是如何把这些零散数据变成一张干净、连续、可以喂给模型的宽表。这里要注意一个常见误区不要以为把销量数据直接丢给深度学习模型模型就会自己“学到”促销、节假日等因素的影响。实际上很多业务特征需要你显式整理出来。如果连“昨天是否参加了秒杀活动”这种字段都没有模型就只能从历史销量的数字变化里间接猜测预测效果自然不稳定。所以我的判断很明确电商销量预测项目百分之七八十的工作量在数据采集、数据整理和特征构造上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?limit1000 def fetch_sales(): resp requests.get(API_URL, timeout10) 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, indexFalse, encodingutf-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_length64, uniqueTrue) title models.CharField(商品标题, max_length255) category models.CharField(品类, max_length64, blankTrue) price models.DecimalField(当前价格, max_digits12, decimal_places2, default0) 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_deletemodels.CASCADE, verbose_name商品) date models.DateField(日期) sales_num models.IntegerField(销量, default0) price models.DecimalField(当日价格, max_digits12, decimal_places2, default0) promotion_flag models.BooleanField(是否参与促销, defaultFalse) page_view models.IntegerField(访客数, default0) order_num models.IntegerField(下单数, default0) class Meta: db_table sales_daily verbose_name 每日销量 verbose_name_plural 每日销量 constraints [ models.UniqueConstraint( fields[product, date], nameuniq_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, typestr) def handle(self, *args, **options): file_path options[csv_file] with open(file_path, newline, encodingutf-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( skusku, defaults{ title: row.get(title, sku), category: row.get(category, ), price: row.get(price, 0), }, ) DailySales.objects.update_or_create( productproduct, datedate, 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__skusku) .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(dropTrue) # 基础日期特征 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(window7).mean() df[sales_ma30] df[sales].shift(1).rolling(window30).mean() # 去掉开头没有完整历史窗口的行 df df.dropna().reset_index(dropTrue) 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(dtypefloat32) targets df[sales].to_numpy(dtypefloat32) 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_modeld_model, nheadnhead, dropoutdropout, batch_firstTrue, ) self.encoder nn.TransformerEncoder(encoder_layer, num_layersnum_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)模型结构分三段理解input_proj把每个时间步的多维特征映射到d_model维空间。pos_embed是简单的位置编码参数用于让模型感知时间先后顺序。TransformerEncoder负责在整个时间窗口内做自注意力编码。预测时只取最后一个时间步的输出。这里我使用了batch_firstTrue这样输入张量形状是(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, dtypefloat32) y_pred np.asarray(y_pred, dtypefloat32) 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真实销量, markero, markersize3) plt.plot(df[date], df[y_pred], label预测销量, markerx, markersize3) plt.xlabel(日期) plt.ylabel(销量) plt.title(电商销量预测结果对比) plt.legend() plt.grid(True, alpha0.3) plt.tight_layout() plt.show()如果后续要嵌入 Django 页面更推荐把预测结果输出为 JSON 接口然后在前端使用 ECharts 来绘制交互图表。这样业务人员可以缩放时间范围也能筛选商品查看单独趋势。Django 后端只需要把date、y_true、y_pred组成列表返回即可不涉及复杂的模板渲染。可视化的另外一层价值在于异常发现。如果预测曲线和历史真实曲线长期存在系统性偏移说明模型可能出现了数据泄漏之外的稳定性问题。电商销量会受到季节、竞争、平台流量变化等因素影响任何模型都不可能永远准确。可视化能帮助你更快识别“什么时候该重新训练模型”而不是等到业务反馈后才后知后觉。8. 常见问题与排查方法这套技术链路包含爬虫、Django、pandas、PyTorch、可视化每一层都可能出问题。这里把实际项目中出现频率较高的问题整理成一张排查表。问题现象可能原因排查方式解决方案爬虫进程退出但没有输出目标接口返回空数据程序没有日志检查返回数据的行数和字段确认请求状态码在关键步骤添加完整日志检查返回结构是否变化Django 模型字段修改后迁移失败已存在数据库中数据与字段约束冲突查看python manage.py makemigrations错误信息先备份数据调整迁移脚本再执行 migrate导入销量 CSV 时重复执行造成重复记录没有设置商品日期的唯一约束检查DailySales表记录数使用UniqueConstraint和update_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.txt或pyproject.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 应用里单独放在crawler和ml目录这样职责更清晰。Django 应用只负责对外提供数据落库和查询能力模型训练任务可以独立运行。10. 总结与后续实践路径这篇文章把 Python 爬虫、Django 后端框架、数据分析、Transformer 销量预测和可视化整合到了同一条电商数据分析链路里。核心观点是做销量预测不能只盯模型而要把数据采集、数据治理、特征工程、模型训练和业务展示当作一个整体来设计。Django 在这里不是简单的后台模板而是贯穿数据流转的中枢Transformer 在整个项目中的价值建立在高质量数据之上并不存在“用了 Transformer 就能解决一切”的神话。接下来你可以按这样一个顺序去实践先挑选一个自己熟悉或授权的数据源哪怕是模拟生成的销售报表跑通“CSV → pandas → Django 入库”这条链路。基于历史销量做简单的滞后特征使用随机森林先训练一个基础模型并记录指标。再用本文的 SalesTransformer 训练一个模型对比两者的 MAPE 和误差分布。最后把真实值和预测值可视化出来尝试从曲线中找出模型失准的业务原因。如果你已经有一个正在开发的电商数据分析项目这篇文章希望帮你少走一些弯路先建立完整的数据链路思维再深入 Transformer 的内部细节。把基础流程固化下来之后再去理解自注意力机制、位置编码、多步预测、模型分布式训练等等都会更有的放矢。后续比较值得深入研究的方向包括基于 Transformer 的增量更新方法、如何处理多个商品之间的相关性和冷启动预测、如何在 Django 中设计模型版本管理和线上推理缓存。这些问题都是销量预测从“能跑通”走向“能上线”的关键。