基于深度学习的农产品价格智能预测系统
目录
- 项目概述
- 数据集介绍
- 系统架构设计
- 项目目录结构
- 数据库设计
- 算法原理与实现
- 数据预处理流程
- 模型训练过程
- 模型评估方法
- 系统界面详解
- 技术栈详解
- 使用说明
项目概述
1.1 项目背景
农产品价格预测是农业市场分析的核心问题之一。准确的价格预测可以帮助:
- 农户:合理安排种植和销售时机
- 经销商:优化采购和库存管理
- 政府:制定农业政策和市场调控措施
- 消费者:了解价格趋势,合理消费
1.2 项目目标
本项目旨在构建一个基于深度学习的农产品价格智能预测系统,实现:
- 多维度数据分析:对农产品价格数据进行全面探索性分析
- 深度学习预测:使用 LSTM 和 GRU 模型进行价格预测
- 可视化展示:提供直观的数据分析和预测结果展示
- 历史记录管理:保存和管理预测历史记录
1.3 技术特点
- ✅ 采用时间序列深度学习模型(LSTM/GRU)
- ✅ 支持多农产品、多市场的价格预测
- ✅ 交互式可视化大屏展示
- ✅ SQLite 数据库管理预测历史
- ✅ 完整的模型评估指标体系
数据集介绍
2.1 数据集来源
数据集名称:Nigerian Agriculture Commodity Market Prices Dataset
数据来源:Hugging Face 开源数据集
数据集链接:https://huggingface.co/datasets/electricsheepafrica/nigerian_agriculture_commodity_market_prices
2.2 数据集特点
- 数据规模:180,000+ 条记录
- 时间跨度:2022-01-01 至 2025-03-30
- 数据格式:CSV/Parquet
- 数据性质:合成数据(基于 FAO、NBS、NiMet、FMARD 等真实数据生成)
2.3 数据字段说明
| 字段名 | 类型 | 说明 | 示例值 |
|---|---|---|---|
market | string | 交易市场名称 | “Dawanau”, “Ariaria”, “Mile 12” |
commodity | string | 农产品名称 | “rice”, “maize”, “beans” |
date | string | 交易日期 | “2022-01-01” |
price_ngn_kg | float | 价格(奈拉/公斤) | 507.21 |
volume_kg | float | 交易量(公斤) | 6978.1 |
2.4 数据统计信息
- 农产品种类:12 种(rice, maize, beans, cassava, yam, tomato, onion, groundnut, sorghum, millet, cocoa, oil_palm)
- 市场数量:5 个(Dawanau, Ariaria, Mile 12, Bodija, Wuse)
- 价格范围:50.00 ~ 1,767.58 NGN/kg
- 平均价格:509.28 NGN/kg
- 价格标准差:282.68 NGN/kg
系统架构设计
3.1 系统架构图
┌─────────────────────────────────────────────────────────────┐ │ 用户界面层 (Streamlit) │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │系统介绍 │ │数据概览 │ │数据分析 │ │预测界面 │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │历史记录 │ │模型分析 │ │结论总结 │ │ │ └──────────┘ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 业务逻辑层 │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │数据管理模块 │ │预测模块 │ │可视化模块 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │模型加载模块 │ │评估模块 │ │历史管理模块 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 数据层 │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │CSV 数据文件 │ │SQLite 数据库 │ │模型文件(.h5) │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │JSON 配置文件 │ │图片文件 │ │Scaler 文件 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────┘3.2 核心模块说明
3.2.1 数据管理模块
- 数据加载与清洗
- 多维度数据筛选(农产品、市场、时间范围)
- 数据统计与概览
3.2.2 预测模块
- LSTM/GRU 模型加载
- 时间序列数据预处理
- 多步长预测(1-7天)
3.2.3 可视化模块
- 交互式图表展示(Plotly)
- 数据分析大屏
- 预测结果可视化
3.2.4 历史管理模块
- SQLite 数据库操作
- 预测记录保存与查询
- 历史趋势分析
项目目录结构
program/ ├── algorithm/ # 算法与模型目录 │ ├── algorithm.ipynb # Jupyter Notebook:数据分析和模型训练 │ ├── streamlit_app.py # Streamlit 应用主程序 │ └── artifacts/ # 模型和数据处理产物目录 │ ├── raw_prices.csv # 原始数据 │ ├── processed_prices.csv # 处理后的数据 │ ├── lstm_model.h5 # LSTM 模型文件 │ ├── gru_model.h5 # GRU 模型文件 │ ├── scaler.pkl # 数据归一化器 │ ├── metrics.json # 模型评估指标 │ ├── train_history.json # 训练历史记录 │ ├── train_meta.json # 训练元数据 │ ├── predictions.csv # 预测结果 │ ├── history.db # SQLite 历史记录数据库 │ ├── price_distribution.png # 价格分布图 │ ├── price_trend.png # 价格趋势图 │ ├── eda_comparison.png # EDA 对比分析图 │ ├── prediction_compare.png # 预测对比图 │ ├── metrics_bar.png # 指标柱状图 │ └── train_history_curve.png # 训练历史曲线图 │ └── explaination/ # 文档说明目录 ├── 详解.md # 本文档 └── images/ # 图片资源目录 ├── algorithm/ # 算法相关图片 │ ├── price_distribution.png │ ├── price_trend.png │ ├── eda_comparison.png │ ├── prediction_compare.png │ ├── metrics_bar.png │ └── train_history_curve.png └── system/ # 系统界面截图 ├── 系统介绍.png ├── 数据概览.png ├── 数据分析.png ├── 预测界面.png ├── 历史记录.png ├── 模型分析.png └── 结论总结.png数据库设计
5.1 数据库概述
系统使用SQLite作为轻量级数据库,用于存储预测历史记录。SQLite 是一个嵌入式数据库,无需单独的服务器进程,非常适合中小型应用。
5.2 数据表设计
5.2.1 预测历史表(predict_history)
表名:predict_history
表说明:存储用户每次进行价格预测的记录,包括预测时间、农产品、市场、使用的模型、预测步长和预测结果。
表结构:
| 字段名 | 数据类型 | 长度 | 非空 | 唯一 | 主键 | 说明 |
|---|---|---|---|---|---|---|
id | INTEGER | - | ✅ | ✅ | ✅ | 自增主键,唯一标识每条记录 |
created_at | TEXT | - | ✅ | ❌ | ❌ | 预测创建时间,ISO 格式字符串 |
commodity | TEXT | - | ✅ | ❌ | ❌ | 农产品名称,如 “rice”, “maize” |
market | TEXT | - | ✅ | ❌ | ❌ | 市场名称,如 “Dawanau”, “Ariaria” |
model | TEXT | - | ✅ | ❌ | ❌ | 使用的模型,值为 “LSTM” 或 “GRU” |
horizon | INTEGER | - | ✅ | ❌ | ❌ | 预测步长(天数),范围 1-7 |
prediction | REAL | - | ✅ | ❌ | ❌ | 预测价格值(NGN/kg),浮点数 |
字段详细说明:
id (INTEGER PRIMARY KEY AUTOINCREMENT)
- 类型:整数
- 约束:主键,自增
- 说明:每条记录的唯一标识符,系统自动生成
created_at (TEXT)
- 类型:文本字符串
- 格式:ISO 8601 格式(如 “2026-01-15T10:30:00”)
- 约束:非空
- 说明:记录预测操作的时间戳
commodity (TEXT)
- 类型:文本字符串
- 约束:非空
- 说明:预测的农产品名称,与数据集中的 commodity 字段对应
market (TEXT)
- 类型:文本字符串
- 约束:非空
- 说明:预测的市场名称,与数据集中的 market 字段对应
model (TEXT)
- 类型:文本字符串
- 约束:非空
- 取值:只能是 “LSTM” 或 “GRU”
- 说明:用于预测的深度学习模型类型
horizon (INTEGER)
- 类型:整数
- 约束:非空
- 范围:1-7
- 说明:预测未来多少天的价格
prediction (REAL)
- 类型:浮点数
- 约束:非空
- 单位:NGN/kg(奈拉/公斤)
- 说明:模型预测的价格值
SQL 建表语句:
CREATETABLEIFNOTEXISTSpredict_history(idINTEGERPRIMARYKEYAUTOINCREMENT,created_atTEXTNOTNULL,commodityTEXTNOTNULL,marketTEXTNOTNULL,modelTEXTNOTNULL,horizonINTEGERNOTNULL,predictionREALNOTNULL);索引设计:
为了提高查询性能,建议创建以下索引:
-- 按创建时间倒序查询(用于显示最新记录)CREATEINDEXIFNOTEXISTSidx_created_atONpredict_history(created_atDESC);-- 按农产品和市场查询CREATEINDEXIFNOTEXISTSidx_commodity_marketONpredict_history(commodity,market);-- 按模型类型查询CREATEINDEXIFNOTEXISTSidx_modelONpredict_history(model);数据示例:
| id | created_at | commodity | market | model | horizon | prediction |
|---|---|---|---|---|---|---|
| 1 | 2026-01-15T10:30:00 | rice | Dawanau | LSTM | 1 | 507.23 |
| 2 | 2026-01-15T10:30:00 | rice | Dawanau | GRU | 1 | 508.45 |
| 3 | 2026-01-15T11:15:00 | maize | Ariaria | LSTM | 3 | 650.12 |
5.3 数据库操作
5.3.1 初始化数据库
definit_db():"""初始化数据库,创建表结构"""withsqlite3.connect(DB_PATH)asconn:conn.execute(""" CREATE TABLE IF NOT EXISTS predict_history ( id INTEGER PRIMARY KEY AUTOINCREMENT, created_at TEXT NOT NULL, commodity TEXT NOT NULL, market TEXT NOT NULL, model TEXT NOT NULL, horizon INTEGER NOT NULL, prediction REAL NOT NULL ) """)conn.commit()5.3.2 插入预测记录
defsave_history(commodity,market,model,horizon,prediction):"""保存预测记录到数据库"""withsqlite3.connect(DB_PATH)asconn:conn.execute(""" INSERT INTO predict_history (created_at, commodity, market, model, horizon, prediction) VALUES (?, ?, ?, ?, ?, ?) """,(datetime.now().isoformat(timespec="seconds"),commodity,market,model,horizon,float(pr