Merge branch 'lyf-dev-req0003' into lyf-dev

This commit is contained in:
LYFxiaoan 2025-07-25 16:34:38 +08:00
commit f01a2cbc70
9 changed files with 723 additions and 4 deletions

View File

@ -395,3 +395,18 @@
2. **撰写新指南**: 基于分析结果,撰写并覆盖生成了一份全新的、内容详尽的 **`项目快速上手指南.md`**。 2. **撰写新指南**: 基于分析结果,撰写并覆盖生成了一份全新的、内容详尽的 **`项目快速上手指南.md`**。
3. **文档迭代**: 根据开发者的提问,在新指南中补充了关于“数据库索引 -> JSON文件内容”的读取机制说明以及关于如何管理和清理历史产物的“系统维护与扩展”章节。 3. **文档迭代**: 根据开发者的提问,在新指南中补充了关于“数据库索引 -> JSON文件内容”的读取机制说明以及关于如何管理和清理历史产物的“系统维护与扩展”章节。
- **最终成果**: 产出了一份高质量、与当前代码完全同步的核心技术指南,显著提升了项目的可维护性和知识传承效率。 - **最终成果**: 产出了一份高质量、与当前代码完全同步的核心技术指南,显著提升了项目的可维护性和知识传承效率。
---
## 2025-07-25 (续): 历史数据一致性修复
**开发者**: Roo (AI Assistant) & lyf
### 19:45 - 修复历史预测详情加载失败 (404 Not Found)
- **问题现象**: 在修复了新预测的保存路径后,前端历史预测列表中的旧记录在点击“查看详情”时,会报错“预测结果文件不存在”。
- **根本原因分析**: 这是一个**数据一致性**问题。虽然我们修复了**新数据**的写入逻辑,但数据库中仍然存在大量**旧记录**,这些记录的 `file_path` 字段依然指向了旧的、错误的 `static/predictions/` 路径。
- **解决方案 (数据清理)**:
1. **创建清理脚本**: 创建了一个一次性维护脚本 `server/tools/delete_old_predictions.py`,用于安全地清理这些“脏数据”。
2. **调试与修复**: 脚本的初版存在时区比较逻辑错误未能正确识别本地时区的记录。在经过一轮调试将时间比较基准从UTC修正为本地时间后脚本得以正常工作。
3. **执行清理**: 最终成功执行脚本,从数据库中清除了所有在指定时间点之前创建的、带有错误文件路径的历史记录。
- **最终结论**: 通过对数据库中的存量数据进行清理,彻底解决了因新旧数据路径不一致而导致的 `404` 错误,确保了系统数据的一致性和功能的稳定性。

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,525 @@
{
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"model_type": "cnn_bilstm_attention",
"predictions": [
{
"date": "2025-07-25",
"predicted_sales": 0.8147072196006775
},
{
"date": "2025-07-26",
"predicted_sales": 0.8167740106582642
},
{
"date": "2025-07-27",
"predicted_sales": 0.8197348117828369
},
{
"date": "2025-07-28",
"predicted_sales": 0.8219858407974243
},
{
"date": "2025-07-29",
"predicted_sales": 0.8112776875495911
},
{
"date": "2025-07-30",
"predicted_sales": 0.8004958629608154
},
{
"date": "2025-07-31",
"predicted_sales": 0.8058184385299683
}
],
"prediction_data": [
{
"date": "2025-07-25",
"predicted_sales": 0.8147072196006775
},
{
"date": "2025-07-26",
"predicted_sales": 0.8167740106582642
},
{
"date": "2025-07-27",
"predicted_sales": 0.8197348117828369
},
{
"date": "2025-07-28",
"predicted_sales": 0.8219858407974243
},
{
"date": "2025-07-29",
"predicted_sales": 0.8112776875495911
},
{
"date": "2025-07-30",
"predicted_sales": 0.8004958629608154
},
{
"date": "2025-07-31",
"predicted_sales": 0.8058184385299683
}
],
"history_data": [
{
"date": "2025-06-25",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 2,
"month": 6,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-06-26",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 3,
"month": 6,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-06-27",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 4,
"month": 6,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-06-28",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 5,
"month": 6,
"is_holiday": false,
"is_weekend": true,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-06-29",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 6,
"month": 6,
"is_holiday": false,
"is_weekend": true,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-06-30",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 0,
"month": 6,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-01",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 1,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-02",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 2,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-03",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 3,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-04",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 4,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-05",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 5,
"month": 7,
"is_holiday": false,
"is_weekend": true,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-06",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 6,
"month": 7,
"is_holiday": false,
"is_weekend": true,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-07",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 0,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-08",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 1,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-09",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 2,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-10",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 3,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-11",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 4,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-12",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 5,
"month": 7,
"is_holiday": false,
"is_weekend": true,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-13",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 6,
"month": 7,
"is_holiday": false,
"is_weekend": true,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-14",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 0,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-15",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 1,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-16",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 2,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-17",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 3,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-18",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 4,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-19",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 5,
"month": 7,
"is_holiday": false,
"is_weekend": true,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-20",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 6,
"month": 7,
"is_holiday": false,
"is_weekend": true,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-21",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 0,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-22",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 1,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-23",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 2,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
},
{
"date": "2025-07-24",
"sales": 0.0,
"product_id": "17021449",
"product_name": "布洛芬混悬液(美林)",
"store_id": "GLOBAL",
"store_name": "全部店铺-SUM",
"weekday": 3,
"month": 7,
"is_holiday": false,
"is_weekend": false,
"is_promotion": false,
"temperature": 20.0
}
],
"analysis": {
"trend": {
"slope": -0.0024171343871525353,
"trend_type": "平稳",
"r_squared": 0.4619268323887481,
"p_value": 0.0930247330579927,
"volatility": 0.008749220910445412,
"volatility_level": "低"
},
"statistics": {
"mean": 0.8129705531256539,
"median": 0.8147072196006775,
"min": 0.8004958629608154,
"max": 0.8219858407974243,
"std": 0.007112858962983344,
"q1": 0.8085480630397797,
"q3": 0.8182544112205505
},
"day_over_day": [
0.25368512857903625,
0.36249942896524706,
0.2746045406674448,
-1.3027174820243943,
-1.328993112252526,
0.6649098159565847
],
"influencing_factors": {
"product_id": "17021449",
"model_type": "cnn_bilstm_attention",
"feature_count": 7,
"important_features": [
"价格",
"周末",
"节假日"
]
},
"explanation": "cnn_bilstm_attention模型对产品17021449的预测分析\n预测显示销量整体呈平稳趋势销量基本保持稳定。\n预测期内销量波动性低表明销量相对稳定预测可信度较高。\n预测期内平均日销量为0.81个单位最高日销量为0.82个单位最低日销量为0.80个单位。\n\n主要影响因素包括价格, 周末, 节假日。"
}
}

View File

@ -0,0 +1,98 @@
import sqlite3
import os
import datetime
# --- 配置 ---
DB_PATH = 'prediction_history.db'
# 用户指定的时间2025年7月25日下午两点 (14:00)
# 数据库中存储的是本地时区的ISO格式字符串所以我们直接用本地时间构建字符串
CUTOFF_DATETIME_LOCAL = datetime.datetime(2025, 7, 25, 14, 0, 0)
# 生成与数据库格式匹配的ISO字符串
CUTOFF_ISO_STRING = CUTOFF_DATETIME_LOCAL.isoformat()
def get_db_connection():
"""创建并返回数据库连接"""
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
return conn
def main():
"""主执行函数"""
print("--- 开始清理旧的预测历史数据 ---")
print(f"数据库路径: {os.path.abspath(DB_PATH)}")
print(f"时间分界点 (本地时间): {CUTOFF_ISO_STRING}")
conn = None
try:
conn = get_db_connection()
cursor = conn.cursor()
# 1. 找出所有需要删除的记录
query = "SELECT id, file_path, created_at FROM prediction_history WHERE created_at < ?"
cursor.execute(query, (CUTOFF_ISO_STRING,))
records_to_delete = cursor.fetchall()
if not records_to_delete:
print("\n[INFO] 没有找到需要清理的旧数据。")
return
print(f"\n[INFO] 发现了 {len(records_to_delete)} 条需要清理的记录。")
ids_to_delete_from_db = []
files_deleted_count = 0
files_not_found_count = 0
# 2. 遍历记录删除关联的JSON文件
for record in records_to_delete:
record_id = record['id']
file_path = record['file_path']
created_at = record['created_at']
print(f" - 正在处理记录 ID: {record_id} (创建于: {created_at})")
if file_path and isinstance(file_path, str):
# 确保我们处理的是项目根目录下的相对路径
absolute_file_path = os.path.abspath(file_path)
if os.path.exists(absolute_file_path):
try:
os.remove(absolute_file_path)
print(f" [SUCCESS] 已删除文件: {absolute_file_path}")
files_deleted_count += 1
except OSError as e:
print(f" [ERROR] 删除文件失败: {e}")
else:
print(f" [WARNING] 文件未找到 (可能已被删除): {absolute_file_path}")
files_not_found_count += 1
else:
print(f" [INFO] 此记录没有关联的文件路径。")
ids_to_delete_from_db.append(record_id)
# 3. 从数据库中删除记录
if ids_to_delete_from_db:
# 使用元组来传递给 a, b, c IN (?, ?, ?)
placeholders = ','.join('?' for _ in ids_to_delete_from_db)
delete_query = f"DELETE FROM prediction_history WHERE id IN ({placeholders})"
cursor.execute(delete_query, ids_to_delete_from_db)
conn.commit()
print(f"\n[SUCCESS] 已从数据库中删除 {cursor.rowcount} 条记录。")
print("\n--- 清理完成 ---")
print(f"总计处理记录: {len(records_to_delete)}")
print(f"成功删除文件: {files_deleted_count}")
print(f"未找到的文件: {files_not_found_count}")
except sqlite3.Error as e:
print(f"\n[FATAL] 数据库操作失败: {e}")
except Exception as e:
print(f"\n[FATAL] 发生未知错误: {e}")
finally:
if conn:
conn.close()
print("\n数据库连接已关闭。")
if __name__ == '__main__':
# 确保脚本在项目根目录执行
# os.chdir(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
main()

View File

@ -59,7 +59,7 @@
| - data/*.parquet: 原始时序数据 | | - data/*.parquet: 原始时序数据 |
| - saved_models/*.pth: 训练好的模型文件 (权重、配置、缩放器) | | - saved_models/*.pth: 训练好的模型文件 (权重、配置、缩放器) |
| - saved_predictions/*.json: 详细的预测结果文件 | | - saved_predictions/*.json: 详细的预测结果文件 |
| - prediction_history.db: SQLite数据库 (存储元数据) | | - prediction_history.db: SQLite数据库 (存储元数据和文件路径索引) |
+-----------------------------------------------------------------+ +-----------------------------------------------------------------+
``` ```
@ -67,7 +67,11 @@
#### **步骤一:数据准备** #### **步骤一:数据准备**
- **原始数据**: 存储在 [`data/timeseries_training_data_sample_10s50p.parquet`](data/timeseries_training_data_sample_10s50p.parquet)。 - **原始数据**: 存储在 [`data/timeseries_training_data_sample_10s50p.parquet`](data/timeseries_training_data_sample_10s50p.parquet)。
- **元数据**: 存储在根目录的 `prediction_history.db` SQLite数据库中。 - **数据存储模式**: 本项目采用“数据库作索引,文件系统存内容”的设计模式。
- **元数据 (索引)**: 存储在根目录的 `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))。 1. **API触发**: 前端调用 `POST /api/training` ([`server/api.py`](server/api.py:815))。
@ -159,3 +163,78 @@
#### **企业级方案:归档到冷存储** #### **企业级方案:归档到冷存储**
对于需要长期保留数据以备审计的场景更专业的做法是将旧文件归档至廉价的云对象存储如阿里云OSS, AWS S3等而不是直接删除。数据库中仅更新文件路径指向云端地址即可。 对于需要长期保留数据以备审计的场景更专业的做法是将旧文件归档至廉价的云对象存储如阿里云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和机器学习的细节。边学边做是最高效的方式。