ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Python机器学习天气预测源码:LSTM与MLP模型对比及GUI实现

2026/9/23 18:09:38 拓冰建站 浏览量
Python机器学习天气预测源码:LSTM与MLP模型对比及GUI实现 简介这是一套面向计算机相关专业学生与项目实战学习者的机器学习天气预测完整项目包适用于期末大作业、毕业设计及课程实践场景难度适中可帮助读者快速理解从数据获取到模型训练与可视化展示的全流程。压缩包共38个文件约12.17MB包含10个py脚本、4个ipynb笔记本、10张png结果图以及pkl、h5、joblib等模型文件另有csv、json数据与docx说明文档覆盖数据爬取、模型训练、界面交互与结果展示等环节。项目围绕气温预测展开涉及线性回归、决策树、随机森林、MLP与LSTM等多种算法并配有GUI最简版与正式版界面便于对比不同模型的预测效果。已有115人学习下载适合需要完整项目结构、可运行源码与配套说明的读者参考使用。1. 从一份 98 分气温预测作业说起这套 Python 机器学习源码到底能跑出什么期末大作业选题里天气预测几乎是每年都被抢的方向但真正能跑通、能讲清楚、还能拿高分的没几个。我手上这份 Python 机器学习天气预测与可视化源码评审分 98导师认可通过核心不是它用了多前沿的模型而是它把「数据爬取 → 数据探索 → 多模型训练 → 可视化 → GUI 演示」这条链路完整地串了起来而且每个环节都有可运行的脚本和落地产物。它解决的是学生和初学者最头疼的问题模型代码网上到处都是但数据从哪来、特征怎么选、模型怎么对比、结果怎么展示没人给你一套能直接跑的东西。这套资源适合正在做机器学习期末大作业、毕业设计的学生也适合想拿一个完整项目练手的 Python 入门者。下面我按实际拆包和复现的顺序把这份资源讲透。2. 拆开压缩包先看什么目录结构与技术栈选型2.1 文件清单背后的模块划分拿到压缩包别急着跑代码先把目录结构过一遍。这份资源的文件组织其实很清晰按功能可以分成五块模块代表文件作用数据爬取全国天气信息爬取.py、临沧历史天气爬取.py从天气网站抓取原始数据数据集WeatherData.csv、Lingcang202001-202312.csv训练和测试用的结构化数据模型训练LSTM气温预测.py、3层MLP气温预测.py、机器学习气温预测模型.py不同算法的训练脚本NotebookLSTM气温预测.ipynb、气温可视化.ipynb、3层MLP气温预测.ipynb交互式探索与可视化模型产物models/ 目录下的 .h5、.pkl、.joblib训练好的模型文件可直接加载GUIGUI最简版.py、GUI正式版.py图形界面演示预测效果辅助all_county_dict.json、city_dict_1.json、requirements.txt城市字典、依赖清单这个划分的好处是你不需要从头跑爬虫也能直接用 dataset 里的 CSV 开始训练模型产物也已经保存在 models 目录里想快速看效果可以直接加载。requirements.txt 里列了依赖常见做法是先建虚拟环境再装避免和系统里的包打架。2.2 为什么选 LSTM MLP 传统模型做对比这份资源没有只用一个模型交差而是同时给了 LSTM、3 层 MLP以及随机森林、决策树、线性回归这几个传统模型。这个选型思路值得说一下。气温数据本质是时间序列LSTM 能捕捉时序依赖适合做滑动窗口预测3 层 MLP 是纯前馈网络把历史气温当成特征输入结构简单、训练快适合做 baseline随机森林和决策树属于传统机器学习不需要 GPU在小数据集上反而稳。把这几类放一起对比论文或报告里就有东西写不同模型在同一份数据上的表现差异、训练时间对比、过拟合情况这些都是评分点。我一般会先跑 MLP 和随机森林确认数据管道没问题再上 LSTM。因为 LSTM 对数据缩放、序列长度、batch size 都敏感一旦前面数据有问题LSTM 的 loss 曲线会直接给你脸色看排查起来反而慢。2.3 环境准备与依赖安装在动手之前先把环境弄干净。这份资源的依赖不算复杂但版本要对上尤其是 TensorFlow/Keras 和 scikit-learn。# 创建虚拟环境Python 版本建议 3.8 - 3.10 python -m venv weather_env # 激活环境 # Windows: weather_env\Scripts\activate # macOS/Linux: source weather_env/bin/activate # 安装依赖requirements.txt 在项目根目录 pip install -r requirements.txt # 如果 requirements.txt 里没有锁版本手动补几个关键包 pip install tensorflow2.12.0 scikit-learn1.2.2 pandas1.5.3 matplotlib3.7.1 joblib1.2.0这里有几个参数要注意TensorFlow 2.12 是最后一个支持原生 Windows GPU 的版本之一如果你在 Windows 上想用 GPU 训练 LSTM这个版本比较省心scikit-learn 1.2.x 和 joblib 的兼容性好加载 .pkl 模型不容易报 warning。装完之后用pip list确认一下重点看 tensorflow、sklearn、pandas 三个包的版本。提示如果安装 TensorFlow 时卡在下载可以换国内镜像源比如pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple但要注意镜像同步可能有延迟关键包还是以官方源为准。3. 数据管道怎么搭从爬虫到 CSV 再到特征工程3.1 爬虫脚本的运行逻辑与数据落盘资源里有两个爬虫脚本全国天气信息爬取.py 和临沧历史天气爬取.py。前者抓全国范围的城市天气信息后者专门抓临沧地区 2020 到 2023 年的历史数据对应 Lingcang202001-202312.csv 这个文件。爬虫脚本的核心逻辑一般是读取城市字典city_dict_1.json 或 all_county_dict.json→ 拼接请求 URL → 解析返回的 HTML 或 JSON → 提取日期、气温、天气状况等字段 → 写入 CSV。运行之前先确认城市字典的格式打开 json 文件看一眼通常是{城市名: 城市代码}这种键值对。# 全国天气信息爬取.py 的核心结构示意根据资源文件推断 import json import requests import pandas as pd from bs4 import BeautifulSoup # 加载城市字典 with open(city_dict_1.json, r, encodingutf-8) as f: city_dict json.load(f) records [] for city_name, city_code in city_dict.items(): # 拼接目标 URL具体地址以脚本内为准 url fhttp://www.weather.com.cn/weather/{city_code}.shtml resp requests.get(url, timeout10) resp.encoding utf-8 soup BeautifulSoup(resp.text, html.parser) # 解析七天气温、天气状况等字段 # ... 解析逻辑 ... records.append({city: city_name, date: ..., temp: ...}) # 落盘为 CSV df pd.DataFrame(records) df.to_csv(WeatherData.csv, indexFalse, encodingutf-8-sig)这段代码的关键参数是timeout10爬虫一定要设超时不然某个城市卡住整个脚本就挂在那里。encodingutf-8-sig是为了 Excel 打开 CSV 不乱码这个细节很多新手会忽略。另外爬虫频率别太高加个time.sleep(1)是基本礼貌也能降低被封的风险。3.2 数据探索先看分布再决定怎么洗拿到 CSV 之后别直接丢进模型。资源里的数据探索.py 和 气温可视化.ipynb 就是干这个的。我一般会先跑一遍基础统计看缺失值、异常值、时间范围。import pandas as pd import matplotlib.pyplot as plt # 加载数据 df pd.read_csv(dataset/Lingcang202001-202312.csv) # 基础信息 print(df.info()) print(df.describe()) # 检查缺失值 print(df.isnull().sum()) # 气温随时间变化 df[date] pd.to_datetime(df[date]) df df.sort_values(date) plt.figure(figsize(14, 5)) plt.plot(df[date], df[temp_max], label最高气温) plt.plot(df[date], df[temp_min], label最低气温) plt.legend() plt.title(临沧 2020-2023 气温走势) plt.show()这一步的重点是确认时间列能不能正确解析、气温列有没有超出合理范围的异常值比如 60 度这种明显错误。如果发现缺失常见做法是线性插值或者用前后值填充但要在报告里写清楚处理方式不然评审老师会问。3.3 特征工程与滑动窗口构造气温预测的特征工程核心是把时间序列转成监督学习能吃的格式。LSTM 需要三维输入(样本数, 时间步长, 特征数)MLP 和传统模型需要二维表格。资源里的脚本应该都做了这个转换我按常见做法补一下逻辑。import numpy as np from sklearn.preprocessing import MinMaxScaler # 假设用历史 7 天气温预测第 8 天 def create_sequences(data, seq_length): X, y [], [] for i in range(len(data) - seq_length): X.append(data[i:iseq_length]) y.append(data[iseq_length]) return np.array(X), np.array(y) # 归一化LSTM 对尺度敏感 scaler MinMaxScaler() temp_scaled scaler.fit_transform(df[[temp_avg]].values) SEQ_LEN 7 X, y create_sequences(temp_scaled, SEQ_LEN) # 划分训练集和测试集时间序列不能随机打乱 split int(len(X) * 0.8) X_train, X_test X[:split], X[split:] y_train, y_test y[:split], y[split:] print(X_train.shape) # (样本数, 7, 1)参数说明SEQ_LEN7表示用一周的历史数据预测下一天这个值可以调但别太大否则样本数会急剧减少。归一化用 MinMaxScaler 把气温缩到 0-1LSTM 训练更稳。注意时间序列划分不能 shuffle否则测试集里混入未来数据评估结果会虚高这是血泪经验。注意models 目录里的 lstm_scaler.joblib 和 mlp_scaler.joblib 就是保存好的 scaler加载模型预测时一定要用同一个 scaler 做逆变换不然预测出来的气温数值会完全不对。4. 模型训练与对比LSTM、MLP 和传统模型怎么跑4.1 LSTM 气温预测脚本的关键参数LSTM气温预测.py 和对应的 ipynb 是这份资源的核心。LSTM 的结构一般是Embedding → LSTM层 → Dropout → Dense但气温预测不需要 Embedding直接LSTM → Dropout → Dense就行。from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout from tensorflow.keras.callbacks import EarlyStopping model Sequential([ LSTM(64, return_sequencesTrue, input_shape(SEQ_LEN, 1)), Dropout(0.2), LSTM(32), Dropout(0.2), Dense(1) ]) model.compile(optimizeradam, lossmse, metrics[mae]) # 早停防止过拟合 early_stop EarlyStopping(monitorval_loss, patience10, restore_best_weightsTrue) history model.fit( X_train, y_train, epochs100, batch_size32, validation_split0.1, callbacks[early_stop], verbose1 ) # 保存模型 model.save(models/LSTM_temperature_prediction_model.h5)参数说明第一层 LSTM 用 64 个单元return_sequencesTrue是为了接第二层 LSTM第二层 32 个单元输出二维。Dropout 设 0.2 是常规操作数据量小的时候可以调到 0.3。patience10表示验证集 loss 连续 10 轮不下降就停restore_best_weightsTrue会恢复到最优轮次的权重这个参数很关键不然保存的是最后一轮的模型可能已经过拟合了。batch_size 32 是默认值如果显存不够可以降到 16。4.2 3 层 MLP 的快速 baseline3层MLP气温预测.py 适合快速验证数据管道。MLP 的输入是展平后的历史气温比如 7 天就是 7 个特征。from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Dropout model Sequential([ Dense(128, activationrelu, input_shape(SEQ_LEN,)), Dropout(0.2), Dense(64, activationrelu), Dropout(0.2), Dense(32, activationrelu), Dense(1) ]) model.compile(optimizeradam, lossmse, metrics[mae]) model.fit(X_train_flat, y_train, epochs100, batch_size32, validation_split0.1) model.save(models/MPL_temperature_prediction_model.h5)注意资源里保存的文件名是MPL_temperature_prediction_model.h5不是 MLP加载的时候别写错。MLP 训练快几分钟就能跑完适合先确认数据没问题。如果 MLP 的 loss 都不下降那 LSTM 也不用试了先回去查数据。4.3 传统模型随机森林、决策树、线性回归资源里还有 random_forest_model.pkl、decision_tree_model.pkl、linear_regression_model.pkl 三个传统模型。这些模型用 scikit-learn 训练不需要 GPU适合做对比实验。from sklearn.ensemble import RandomForestRegressor from sklearn.tree import DecisionTreeRegressor from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_absolute_error, mean_squared_error import joblib # 传统模型用二维特征 X_train_2d X_train.reshape(X_train.shape[0], -1) X_test_2d X_test.reshape(X_test.shape[0], -1) models { random_forest: RandomForestRegressor(n_estimators100, random_state42), decision_tree: DecisionTreeRegressor(random_state42), linear_regression: LinearRegression() } for name, model in models.items(): model.fit(X_train_2d, y_train.ravel()) pred model.predict(X_test_2d) mae mean_absolute_error(y_test, pred) rmse mean_squared_error(y_test, pred, squaredFalse) print(f{name}: MAE{mae:.4f}, RMSE{rmse:.4f}) joblib.dump(model, fmodels/{name}_model.pkl)随机森林的n_estimators100是常用值数据量小的话 50 也够。random_state42保证结果可复现报告里写实验设置的时候要提。传统模型的评估指标用 MAE 和 RMSE和 LSTM 的 mae、mse 对应方便做对比表格。4.4 模型对比与结果解读跑完所有模型把结果整理成表格这是报告里的核心内容。模型MAERMSE训练时间备注LSTM待填待填较长需要 GPU 更佳3层 MLP待填待填短快速 baseline随机森林待填待填短无需缩放决策树待填待填极短容易过拟合线性回归待填待填极短欠拟合参考解读的时候注意LSTM 不一定在所有数据集上都最好如果数据量小、噪声大随机森林可能更稳。线性回归如果 MAE 特别高说明气温和滞后特征之间不是纯线性关系这本身就是个可以写进报告的结论。5. 避坑与排查跑这套源码时最容易翻车的五个地方5.1 现象加载 .h5 模型报错「Unknown layer」或「No model found」原因Keras 版本不匹配。资源里的 .h5 模型可能是用 TensorFlow 2.x 某个版本保存的你本地装了 2.15 或更高版本API 变了。另外如果模型里用了自定义层加载时需要custom_objects参数。解决先确认 requirements.txt 里的 TensorFlow 版本严格按那个版本装。如果找不到试 2.12 或 2.13。加载时用tf.keras.models.load_model(models/LSTM_temperature_prediction_model.h5, compileFalse)先不编译加载完再手动 compile。5.2 现象预测出来的气温是 0.2、0.3 这种小数不是真实温度原因忘了做逆变换。模型是在归一化后的数据上训练的输出也是 0-1 范围必须用保存的 scaler 做inverse_transform才能还原成摄氏度。解决加载对应的 scaler 文件LSTM 用 lstm_scaler.joblibMLP 用 mlp_scaler.joblib。import joblib scaler joblib.load(models/lstm_scaler.joblib) pred_real scaler.inverse_transform(pred.reshape(-1, 1))注意 scaler 的 fit 对象要和训练时一致如果重新 fit 了逆变换的结果也是错的。5.3 现象GUI 运行后界面空白或按钮没反应原因GUI最简版.py 和 GUI正式版.py 可能用了 tkinter 或 PyQt如果依赖没装全或者图片路径写的是绝对路径换台机器就找不到资源。解决先确认 GUI 用的库tkinter 一般 Python 自带PyQt 需要pip install PyQt5。然后检查代码里的图片路径改成相对路径比如img/image-20240522210616667.png这种。如果界面能打开但按钮没反应看控制台有没有报错通常是模型加载失败或者回调函数没绑定。5.4 现象爬虫跑一半报「ConnectionError」或返回空数据原因目标网站反爬、网络波动、或者城市代码失效。资源里的 city_dict_1.json 和 all_county_dict.json 可能包含已经变更的代码。解决加 try-except 捕获异常跳过失败的城市继续跑加time.sleep(1)降低频率如果某个城市一直失败手动检查 URL 是否还能访问。另外爬虫脚本里的 User-Agent 最好设一下默认的 python-requests 很容易被识别。5.5 现象LSTM 训练 loss 不下降或者 val_loss 一直震荡原因学习率太大、序列长度不合适、数据没归一化、或者 batch_size 太小导致梯度不稳定。解决先把学习率从默认的 0.001 降到 0.0005 试试检查 SEQ_LEN 是不是太长7 到 14 之间比较合理确认归一化做了batch_size 可以调到 64 看看。如果还是不行把 LSTM 单元数从 64 降到 32减少模型复杂度。玄学的时候换个随机种子也可能有惊喜。6. 进阶用法把模型接进 GUI 并做实时预测验证6.1 GUI 正式版的集成逻辑GUI正式版.py 是这份资源的演示门面。它的逻辑一般是加载模型和 scaler → 提供输入框让用户输入历史气温或选择日期 → 调用模型预测 → 在界面上显示结果和可视化图表。我一般会先跑 GUI最简版.py确认模型能加载、界面能弹出再跑正式版。集成的时候注意一点GUI 里加载模型最好用相对路径并且把模型加载放在界面初始化之前避免用户点击按钮时才加载导致卡顿。如果 GUI 用了 matplotlib 嵌入记得用FigureCanvasTkAgg或者对应的 Qt 后端不然图表显示不出来。6.2 用 key_predictions.py 做预测结果验证资源里的 key_predictions.py 应该是用来做关键预测点验证的。我的习惯是训练完模型后不只看 MAE还要把预测值和真实值画在同一张图上看趋势对不对。import matplotlib.pyplot as plt # 假设 y_test 和 pred 都是归一化后的值 y_test_real scaler.inverse_transform(y_test.reshape(-1, 1)) pred_real scaler.inverse_transform(pred.reshape(-1, 1)) plt.figure(figsize(14, 5)) plt.plot(y_test_real, label真实气温) plt.plot(pred_real, label预测气温) plt.legend() plt.title(LSTM 气温预测对比) plt.xlabel(时间步) plt.ylabel(气温 (℃)) plt.show()如果预测曲线整体滞后于真实曲线说明模型在追趋势但反应慢可以尝试减小 SEQ_LEN 或增加 LSTM 层数。如果预测曲线太平说明模型没学到变化检查归一化范围是不是太窄。6.3 一个具体技巧用滑动窗口做多步预测单步预测只能预测下一天实际场景里可能需要预测未来一周。做法是每次预测完把预测值追加到输入序列末尾滚动预测。def multi_step_predict(model, last_sequence, n_steps, scaler): predictions [] current_seq last_sequence.copy() for _ in range(n_steps): pred model.predict(current_seq.reshape(1, SEQ_LEN, 1), verbose0) predictions.append(pred[0, 0]) # 滚动去掉最早的值追加预测值 current_seq np.append(current_seq[1:], pred) return scaler.inverse_transform(np.array(predictions).reshape(-1, 1)) # 用测试集最后一段做起点 last_seq X_test[-1] future_temps multi_step_predict(model, last_seq, 7, scaler) print(future_temps)这个技巧的坑在于误差会累积预测步数越多越不准。我一般只做 3 到 7 步并且会在报告里说明多步预测的误差会随步数增加。从那以后我每次做时间序列项目都会把单步和多步的结果分开评估不混在一起写。希望帮到你。本文还有配套的精品资源点击获取