# 项目快速上手指南 (v2.0 - 2025年7月版) 欢迎加入项目!本指南旨在帮助你快速理解项目的核心功能、最新的技术架构和开发流程。 ## 1. 项目核心功能 这是一个基于历史销售数据的 **智能销售预测系统**,其核心是实现一个 **"数据 -> 训练 -> 模型 -> 预测 -> 可视化"** 的完整闭环。 所有功能均通过Web界面操作: 1. **模型训练**: 用户可以选择某个**药品**、某个**店铺**或**全局**数据,然后选择一种机器学习算法(如Transformer、KAN等)进行训练。训练过程是**异步**的,并能通过WebSocket实时反馈进度。 2. **销售预测**: 使用已经训练好的模型,对未来的销量进行预测。 3. **结果可视化**: 将历史销量和预测销量在同一个图表中展示出来,方便用户直观地看到趋势。 4. **模型与历史管理**: 提供对已训练模型和历史预测记录的查询、详情查看和删除功能。 ## 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`](data/timeseries_training_data_sample_10s50p.parquet)。 - **数据存储模式**: 本项目采用“数据库作索引,文件系统存内容”的设计模式。 - **元数据 (索引)**: 存储在根目录的 `prediction_history.db` SQLite数据库中。它只记录轻量级的元信息(如模型版本、预测参数)和指向真实数据文件的**路径**。 - **真实数据 (内容)**: - **模型**: 训练好的模型(`.pth`文件)存放在 [`saved_models/`](saved_models/) 目录。 - **预测结果**: 详细的预测数据(`.json`文件)存放在 [`saved_predictions/`](saved_predictions/) 目录。 #### **步骤二:模型训练 (异步)** 1. **API触发**: 前端调用 `POST /api/training` ([`server/api.py`](server/api.py:815))。 2. **任务提交**: `api.py` 将训练请求提交给**训练进程管理器** (`training_process_manager`),并立即返回一个任务ID,不阻塞主服务。 3. **动态执行**: * 管理器在**新的子进程**中运行任务。 * 它通过**模型注册表** (`model_registry`) 找到 `model_type` 对应的训练器函数(例如,`kan` -> `kan_trainer.py` 中的函数)。 * 训练器加载数据,进行归一化,然后执行PyTorch训练循环。 4. **模型保存**: * 训练完成后,调用**模型管理器** (`model_manager`) 的 `save_model` 方法。 * 模型(权重、配置、缩放器)被打包保存在 [`saved_models/`](saved_models/) 目录下,命名如 `kan_product_P001_v1.pth`。 * 模型的元数据(路径、版本、指标)被写入数据库的 `model_versions` 表。 #### **步骤三:模型预测 (同步)** 1. **API触发**: 前端调用 `POST /api/prediction` ([`server/api.py`](server/api.py:1273))。 2. **模型定位**: `api.py` 调用**模型管理器** (`model_manager`),根据参数从数据库中找到对应的模型文件路径。 3. **加载与预测**: * 核心逻辑在 [`server/predictors/model_predictor.py`](server/predictors/model_predictor.py) 的 `load_model_and_predict` 函数中。 * 该函数加载 `.pth` 文件,并利用其中的 `config` 和 `state_dict` **精确重建模型实例**。 * 执行**自回归预测**:预测一天,将结果作为下一天输入的一部分,循环往复。 4. **结果保存**: * 完整的预测结果(历史、预测、分析等)被保存为一个JSON文件到 [`saved_predictions/`](saved_predictions/) 目录。 * 该次预测的元数据(包括JSON文件路径)被写入数据库的 `prediction_history` 表。 5. **返回与渲染**: 完整的JSON结果被返回给前端,前端使用图表库进行可视化。 ## 5. 如何添加一个新的算法?(开发者指南) 假设你要添加一个名为 `NewNet` 的新算法。 **目标**: 让 `NewNet` 出现在前端的“模型类型”下拉框中,并能成功训练和预测。 1. **创建模型定义文件**: * 在 `server/models/` 目录下,创建 `newnet_model.py`。 * 在其中定义你的 `NewNet` 模型类,继承自 `torch.nn.Module`。 2. **创建训练器文件**: * 在 `server/trainers/` 目录下,创建 `newnet_trainer.py`。 * 复制一份现有训练器(如 `kan_trainer.py`)的内容作为模板。 * **关键修改**: * 导入你的 `NewNet` 模型。 * 在训练函数中,实例化你的 `NewNet` 模型。 * 在保存checkpoint时,确保 `config` 字典里包含了重建 `NewNet` 所需的所有超参数。 * 在文件末尾,**注册你的训练器**: `register_trainer('newnet', your_training_function)`。 3. **创建预测器逻辑 (如果需要)**: * 大多数情况,你可以复用默认的预测器。打开 [`server/predictors/model_predictor.py`](server/predictors/model_predictor.py)。 * 在 `load_model_and_predict` 函数中,添加一个 `elif loaded_model_type == 'newnet':` 分支,确保它能根据 `config` 正确地创建 `NewNet` 模型实例。 * 在文件末尾,**注册你的预测器**: `register_predictor('newnet', default_pytorch_predictor)`。如果你的模型有特殊的预测逻辑,可以自定义一个预测函数并注册它。 4. **更新前端界面**: * 打开 `server/api.py` 中的 `get_model_types` 函数。 * 在 `model_meta` 字典中添加 `'newnet'` 的元数据,包括名称、描述和标签类型。 * **无需修改前端代码**,前端的下拉框会自动从这个API获取最新的模型列表。 完成以上步骤后,重启服务,你就可以在界面上选择并使用你的新算法了。这个插件式的设计大大简化了新算法的集成过程。 ## 6. 系统维护与扩展 随着系统的持续运行,会不断产生模型文件、预测结果等历史产物。理解如何管理这些产物对于保持系统的健康至关重要。 ### 6.1. 历史产物管理 (Artifacts Management) **问题**: 随着时间推移,`saved_models/` 和 `saved_predictions/` 目录下的文件会越来越多,导致项目体积变得臃肿。 **当前状态**: 系统目前依赖**手动清理**。您可以通过Web界面删除单个模型或单条预测历史,程序会自动删除对应的文件。 **推荐的解决方案**: 为了实现自动化管理,推荐创建一个独立的维护脚本,并实施**数据保留策略 (Data Retention Policy)**。 #### **自动化清理策略** 1. **创建清理脚本**: * 可以在 `server/tools/` 目录下创建一个新脚本,例如 `cleanup_artifacts.py`。 2. **定义保留规则**: * **对于预测结果 (`.json` in `saved_predictions/`)**: * **基于时间**: 只保留最近30天的记录。 * **基于数量**: 只保留最新的1000条记录。 * **对于模型 (`.pth` in `saved_models/`)**: * **基于版本**: 只保留每个模型(同一种药品、同一种算法)最新的3个版本。 * **保留最佳模型**: 始终保留性能最佳的 `best` 版本,不参与自动清理。 3. **执行脚本**: * 脚本的逻辑是:连接数据库,查询出所有符合清理条件的记录,然后安全地删除硬盘上对应的文件,最后再删除数据库中的条目。 * 这个脚本可以通过服务器的定时任务(如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. 模型的具体实现是怎样的? 1. **我们如何得到模型?** * 我们运行训练脚本 (`uv run train_model`)。 * 该脚本调用 `kan_trainer.py` 中的 `train_product_model_with_kan` 函数。 * 这个函数会加载销售数据,对数据进行预处理(例如,将“星期一”转换为数字1,将所有数据缩放到0-1之间以便于神经网络处理)。 * 然后,它将数据切分成“用连续30天的数据,预测未来7天销量”这样的样本对。 * 最后,它通过成千上万次的学习迭代,将学到的知识保存为一个 `.pth` 文件。 2. **预测的具体实现是怎样的?** * 我们通过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构建的。 * **机器学习基础概念**:了解什么是特征工程、训练集/测试集、损失函数、过拟合与欠拟合等。 * **高级(能设计和创新)**: * **深度学习理论**:深入理解神经网络、反向传播等原理。 * **时间序列分析**:了解ARIMA、LSTM、Transformer等其他时间序列预测模型的原理和优劣。 **给您的建议**: 您现在完全不需要焦虑。从“初级”开始,先尝试理解数据的流转,即数据是如何从文件加载,被Pandas处理,然后输入给训练器或预测器的。当您能熟练地进行使用和调试后,再逐步去了解PyTorch和机器学习的细节。边学边做是最高效的方式。