17 KiB
项目快速上手指南 (v2.0 - 2025年7月版)
欢迎加入项目!本指南旨在帮助你快速理解项目的核心功能、最新的技术架构和开发流程。
1. 项目核心功能
这是一个基于历史销售数据的 智能销售预测系统,其核心是实现一个 "数据 -> 训练 -> 模型 -> 预测 -> 可视化" 的完整闭环。
所有功能均通过Web界面操作:
- 模型训练: 用户可以选择某个药品、某个店铺或全局数据,然后选择一种机器学习算法(如Transformer、KAN等)进行训练。训练过程是异步的,并能通过WebSocket实时反馈进度。
- 销售预测: 使用已经训练好的模型,对未来的销量进行预测。
- 结果可视化: 将历史销量和预测销量在同一个图表中展示出来,方便用户直观地看到趋势。
- 模型与历史管理: 提供对已训练模型和历史预测记录的查询、详情查看和删除功能。
2. 技术栈
层面 | 本项目技术 | 说明 |
---|---|---|
后端框架 | Flask | 轻量级的Python Web框架,用于提供API接口。 |
前端框架 | Vue.js | 用于构建用户交互界面的现代化JavaScript框架。 |
核心算法库 | PyTorch | 实现深度学习算法的核心库。 |
数据处理 | Pandas | Python中用于数据分析和处理的核心库。 |
数据库 | SQLite | 一个轻量级的本地文件数据库,用于记录模型元数据和预测历史。 |
实时通信 | Flask-SocketIO | 用于后端在训练时向前端实时推送日志和进度。 |
异步任务 | multiprocessing | Python标准库,用于将耗时的训练任务放到独立的子进程中执行,避免阻塞API服务。 |
3. 系统架构与数据流
本项目是经典的前后端分离架构,其数据流和核心组件如下:
+-----------------------------------------------------------------+
| 用户 (Browser - Vue.js) |
+-----------------------------------------------------------------+
| (1. HTTP/WebSocket请求)
+-----------------------------------------------------------------+
| 后端API层 (Backend API - Flask) |
| - api.py: 定义所有RESTful接口 (e.g., /api/training) |
| - 接收请求, 验证参数, 调用核心服务层 |
+-----------------------------------------------------------------+
| (2. 调用核心服务)
+-----------------------------------------------------------------+
| 核心服务与管理层 (Core Services) |
| - training_process_manager.py: 异步训练任务管理器 (关键) |
| - model_manager.py: 模型保存、加载、版本控制 (关键) |
| - model_registry.py: 算法与训练器的注册表 (关键) |
+-----------------------------------------------------------------+
| (3. 执行具体任务)
+-----------------------------------------------------------------+
| 算法实现与数据处理层 (Algorithm & Data) |
| - trainers/*.py: 具体的算法训练逻辑 (e.g., kan_trainer.py) |
| - predictors/model_predictor.py: 模型加载与预测逻辑 |
| - models/*.py: PyTorch模型定义 (e.g., kan_model.py) |
| - utils/data_utils.py: 数据预处理和转换工具 |
+-----------------------------------------------------------------+
| (4. 读写物理文件)
+-----------------------------------------------------------------+
| 物理存储层 (Storage) |
| - data/*.parquet: 原始时序数据 |
| - saved_models/*.pth: 训练好的模型文件 (权重、配置、缩放器) |
| - saved_predictions/*.json: 详细的预测结果文件 |
| - prediction_history.db: SQLite数据库 (存储元数据和文件路径索引) |
+-----------------------------------------------------------------+
4. 核心工作流详解:“数据 -> 训练 -> 预测”
步骤一:数据准备
- 原始数据: 存储在
data/timeseries_training_data_sample_10s50p.parquet
。 - 数据存储模式: 本项目采用“数据库作索引,文件系统存内容”的设计模式。
- 元数据 (索引): 存储在根目录的
prediction_history.db
SQLite数据库中。它只记录轻量级的元信息(如模型版本、预测参数)和指向真实数据文件的路径。 - 真实数据 (内容):
- 模型: 训练好的模型(
.pth
文件)存放在saved_models/
目录。 - 预测结果: 详细的预测数据(
.json
文件)存放在saved_predictions/
目录。
- 模型: 训练好的模型(
- 元数据 (索引): 存储在根目录的
步骤二:模型训练 (异步)
- API触发: 前端调用
POST /api/training
(server/api.py
)。 - 任务提交:
api.py
将训练请求提交给训练进程管理器 (training_process_manager
),并立即返回一个任务ID,不阻塞主服务。 - 动态执行:
- 管理器在新的子进程中运行任务。
- 它通过模型注册表 (
model_registry
) 找到model_type
对应的训练器函数(例如,kan
->kan_trainer.py
中的函数)。 - 训练器加载数据,进行归一化,然后执行PyTorch训练循环。
- 模型保存:
- 训练完成后,调用模型管理器 (
model_manager
) 的save_model
方法。 - 模型(权重、配置、缩放器)被打包保存在
saved_models/
目录下,命名如kan_product_P001_v1.pth
。 - 模型的元数据(路径、版本、指标)被写入数据库的
model_versions
表。
- 训练完成后,调用模型管理器 (
步骤三:模型预测 (同步)
- API触发: 前端调用
POST /api/prediction
(server/api.py
)。 - 模型定位:
api.py
调用模型管理器 (model_manager
),根据参数从数据库中找到对应的模型文件路径。 - 加载与预测:
- 核心逻辑在
server/predictors/model_predictor.py
的load_model_and_predict
函数中。 - 该函数加载
.pth
文件,并利用其中的config
和state_dict
精确重建模型实例。 - 执行自回归预测:预测一天,将结果作为下一天输入的一部分,循环往复。
- 核心逻辑在
- 结果保存:
- 完整的预测结果(历史、预测、分析等)被保存为一个JSON文件到
saved_predictions/
目录。 - 该次预测的元数据(包括JSON文件路径)被写入数据库的
prediction_history
表。
- 完整的预测结果(历史、预测、分析等)被保存为一个JSON文件到
- 返回与渲染: 完整的JSON结果被返回给前端,前端使用图表库进行可视化。
5. 如何添加一个新的算法?(开发者指南)
假设你要添加一个名为 NewNet
的新算法。
目标: 让 NewNet
出现在前端的“模型类型”下拉框中,并能成功训练和预测。
-
创建模型定义文件:
- 在
server/models/
目录下,创建newnet_model.py
。 - 在其中定义你的
NewNet
模型类,继承自torch.nn.Module
。
- 在
-
创建训练器文件:
- 在
server/trainers/
目录下,创建newnet_trainer.py
。 - 复制一份现有训练器(如
kan_trainer.py
)的内容作为模板。 - 关键修改:
- 导入你的
NewNet
模型。 - 在训练函数中,实例化你的
NewNet
模型。 - 在保存checkpoint时,确保
config
字典里包含了重建NewNet
所需的所有超参数。 - 在文件末尾,注册你的训练器:
register_trainer('newnet', your_training_function)
。
- 导入你的
- 在
-
创建预测器逻辑 (如果需要):
- 大多数情况,你可以复用默认的预测器。打开
server/predictors/model_predictor.py
。 - 在
load_model_and_predict
函数中,添加一个elif loaded_model_type == 'newnet':
分支,确保它能根据config
正确地创建NewNet
模型实例。 - 在文件末尾,注册你的预测器:
register_predictor('newnet', default_pytorch_predictor)
。如果你的模型有特殊的预测逻辑,可以自定义一个预测函数并注册它。
- 大多数情况,你可以复用默认的预测器。打开
-
更新前端界面:
- 打开
server/api.py
中的get_model_types
函数。 - 在
model_meta
字典中添加'newnet'
的元数据,包括名称、描述和标签类型。 - 无需修改前端代码,前端的下拉框会自动从这个API获取最新的模型列表。
- 打开
完成以上步骤后,重启服务,你就可以在界面上选择并使用你的新算法了。这个插件式的设计大大简化了新算法的集成过程。
6. 系统维护与扩展
随着系统的持续运行,会不断产生模型文件、预测结果等历史产物。理解如何管理这些产物对于保持系统的健康至关重要。
6.1. 历史产物管理 (Artifacts Management)
问题:
随着时间推移,saved_models/
和 saved_predictions/
目录下的文件会越来越多,导致项目体积变得臃肿。
当前状态: 系统目前依赖手动清理。您可以通过Web界面删除单个模型或单条预测历史,程序会自动删除对应的文件。
推荐的解决方案: 为了实现自动化管理,推荐创建一个独立的维护脚本,并实施数据保留策略 (Data Retention Policy)。
自动化清理策略
-
创建清理脚本:
- 可以在
server/tools/
目录下创建一个新脚本,例如cleanup_artifacts.py
。
- 可以在
-
定义保留规则:
- 对于预测结果 (
.json
insaved_predictions/
):- 基于时间: 只保留最近30天的记录。
- 基于数量: 只保留最新的1000条记录。
- 对于模型 (
.pth
insaved_models/
):- 基于版本: 只保留每个模型(同一种药品、同一种算法)最新的3个版本。
- 保留最佳模型: 始终保留性能最佳的
best
版本,不参与自动清理。
- 对于预测结果 (
-
执行脚本:
- 脚本的逻辑是:连接数据库,查询出所有符合清理条件的记录,然后安全地删除硬盘上对应的文件,最后再删除数据库中的条目。
- 这个脚本可以通过服务器的定时任务(如Linux的Cron Job或Windows的Task Scheduler)设置为每日自动执行。
企业级方案:归档到冷存储
对于需要长期保留数据以备审计的场景,更专业的做法是将旧文件归档至廉价的云对象存储(如阿里云OSS, AWS S3等),而不是直接删除。数据库中仅更新文件路径指向云端地址即可。
核心概念扫盲:算法、模型、训练与预测
对于初次接触AI和数据科学的开发者来说,这些术语可能会令人困惑。本章节旨在用最通俗易懂的方式,解释本项目核心的AI部分是如何工作的。
1. 一个简单的比喻:学生备考
让我们把整个AI预测系统想象成一个准备参加数学考试的学生:
- 历史数据 (Data):就像是学生的教科书和练习册 (
pharmacy_sales.xlsx
文件)。里面包含了大量的历史题目(过去的销售情况)和对应的正确答案。 - 算法 (Algorithm):是学生的学习方法和大脑结构 (本项目中的
KAN
神经网络)。它定义了学生如何去理解问题、寻找规律,但算法本身不包含任何知识。它只是一套空的学习框架。 - 训练 (Training):就是学生学习和复习的过程 (
server/trainers/kan_trainer.py
脚本)。学生通过不断地做练习册上的题(读取历史数据),然后对照答案(真实的销售额),分析自己错在哪里(计算损失/Loss),然后反思并修正自己的解题思路(反向传播与优化)。这个过程会重复很多遍(Epochs),直到学生在模拟考试(测试集)中取得好成绩。 - 模型 (Model):是学生学习完成后,学到的所有知识和解题技巧 (保存在
saved_models/
下的.pth
文件)。它不再是空的大脑框架,而是包含了所有规律和知识、准备好上考场的“成型的知识体系”。 - 预测 (Prediction):就是学生正式上考场考试的过程 (
server/predictors/model_predictor.py
脚本)。我们给学生一套他从未见过的新题目(例如,提供最近30天的数据,让他预测未来7天),学生利用他已经学到的知识(加载.pth
模型文件),给出他认为最可能的答案(未来的销售额)。
2. 训练和预测在本项目中的区别与联系
Q: 训练和预测所使用的算法有区别吗?
A: 核心算法(大脑结构)是完全相同的,都是 KAN
网络。但它们所做的事情(功能)截然不同。
-
训练 (
train_product_model_with_kan
)- 目标:创造一个模型。
- 输入:大量的历史数据(特征+答案)。
- 过程:是一个学习和迭代的过程。它会反复调整算法内部的参数(权重),目标是让预测结果与真实答案的差距越来越小。这是一个计算量巨大、非常耗时的过程。
- 输出:一个
.pth
文件,这就是训练好的模型。
-
预测 (
load_model_and_predict
)- 目标:使用一个已有的模型。
- 输入:一小段最近的历史数据(只有特征,没有答案)。
- 过程:是一个计算和应用的过程。它加载训练好的
.pth
模型文件,将输入数据“喂”给模型,模型根据已经固化的参数,直接计算出结果。这个过程非常快。 - 输出:对未来的预测数据(JSON格式)。
总结:训练是“从0到1”打造模型的过程,预测是“使用这个1”来解决实际问题的过程。
3. 模型的具体实现是怎样的?
-
我们如何得到模型?
- 我们运行训练脚本 (
uv run train_model
)。 - 该脚本调用
kan_trainer.py
中的train_product_model_with_kan
函数。 - 这个函数会加载销售数据,对数据进行预处理(例如,将“星期一”转换为数字1,将所有数据缩放到0-1之间以便于神经网络处理)。
- 然后,它将数据切分成“用连续30天的数据,预测未来7天销量”这样的样本对。
- 最后,它通过成千上万次的学习迭代,将学到的知识保存为一个
.pth
文件。
- 我们运行训练脚本 (
-
预测的具体实现是怎样的?
- 我们通过API请求预测。
- API调用
model_predictor.py
中的load_model_and_predict
函数。 - 该函数首先根据请求,找到对应的
.pth
模型文件并加载它。 - 然后,它获取预测开始日期前最新的30天真实数据。
- 它将这30天数据输入模型,得到对未来第1天的预测销量。
- 关键一步(自回归):它将第1天的预测结果,当作“真实发生过”的数据,拼接到历史数据的末尾,并丢掉最老的一天,形成一个新的30天数据序列。
- 它用这个新的序列去预测第2天的销量。
- ……如此循环往复,直到预测出未来7天的全部结果。
4. 我需要具备哪些技术才能理解?
这是一个很好的问题,可以分层来看:
-
初级(能使用和调试):
- Python基础:能读懂基本的Python代码和逻辑。
- Pandas库:了解如何操作和处理表格数据(DataFrame)。我们项目中的数据预处理大量使用Pandas。
- 理解本章节内容:对训练和预测有宏观概念,知道输入什么、输出什么即可。
-
中级(能修改和优化):
- PyTorch框架:了解PyTorch的基本概念,如
Tensor
(张量)、nn.Module
(模型结构)、Optimizer
(优化器)、DataLoader
(数据加载器)。我们的KAN
模型就是用PyTorch构建的。 - 机器学习基础概念:了解什么是特征工程、训练集/测试集、损失函数、过拟合与欠拟合等。
- PyTorch框架:了解PyTorch的基本概念,如
-
高级(能设计和创新):
- 深度学习理论:深入理解神经网络、反向传播等原理。
- 时间序列分析:了解ARIMA、LSTM、Transformer等其他时间序列预测模型的原理和优劣。
给您的建议: 您现在完全不需要焦虑。从“初级”开始,先尝试理解数据的流转,即数据是如何从文件加载,被Pandas处理,然后输入给训练器或预测器的。当您能熟练地进行使用和调试后,再逐步去了解PyTorch和机器学习的细节。边学边做是最高效的方式。