ARTICLE DETAIL

建站实战干货

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

五种回归模型对比气温预测:从数据清洗到GUI部署实战

2026/9/17 10:57:06 拓冰建站 浏览量
五种回归模型对比气温预测:从数据清洗到GUI部署实战 简介基于Python机器学习技术实现的气温预测与可视化课程设计资源面向计算机相关专业学生的期末大作业与课程设计场景覆盖数据爬取、模型对比、结果可视化的完整流程。资源重点对比了MLP、LSTM、随机森林、决策树和线性回归五种模型的预测效果并提供图形化界面直观展示结果适配新手快速上手完成高分项目。压缩包共包含38个文件以Python源码、Jupyter Notebook、模型权重文件、CSV数据集及使用文档为主整体大小仅12.17MB结构清晰便于部署与二次开发。已有426人学习下载适合需要借鉴完整方案或快速搭建同类型项目的学生。内含带注释的多个训练脚本、已训练好的模型文件、GUI界面程序、可视化图表和详细使用说明下载后简单配置环境即可运行也可根据需求替换数据或调整模型参数具有较强的工程参考价值。1. 一份课设源码为什么值得拆五种回归模型对比气温预测一份标着“满分”的 Python 课程设计真正拉开分值的往往不是 LSTM 训练得有多准而是数据怎么切、模型怎么对比、结果怎么用 GUI 讲清楚。这套源码同时给了线性回归、决策树、随机森林、3 层 MLP、LSTM 五种模型覆盖一条完整的气温预测和可视化链路爬数据、清洗、做窗口、训练、评估、存模型、画界面。对期末大作业来说能照着跑通就不慌对已经工作的人值得看的是时间序列转监督学习这一步怎么处理以及不同格式模型如何被同一个 GUI 加载。文章后面所有代码都针对这个项目结构展开路径和文件名按压缩包原样保留。2. 从 WeatherData.csv 到训练集数据清洗、窗口化与标准化2.1 原始数据的构成与缺失值处理压缩包里的dataset/WeatherData.csv存的是多城市天气汇总Lingcang202001-202312.csv是按城市整理的长期气温记录。两个文件字段基本一致至少包含日期、平均气温、湿度、风速、天气现象这几类。课程设计文档里要求做“气温预测”所以目标列默认是平均气温其他字段作为可选特征。拿到 CSV 后第一件事不是急着建模而是先把日期列处理成datetime再按时间升序排序。很多初学者会在这一步直接读文件导致后续窗口化时序列顺序错乱。排序之后做缺失值处理平均气温一般用前向填充ffill因为气温变化在相邻几天内是连续的湿度、风速可以用滚动窗口均值填充。天气现象这类文本列线性回归和神经网络用不了常见做法是直接舍弃或者做标签编码后只喂给树模型。字段示例处理方式说明date解析为 datetime升序排序时间顺序决定训练集和测试集如何切分avg_temp前向填充删除明显异常值预测目标单位默认摄氏度humidityrolling mean 填充可选特征对树模型有价值wind_speed缺失值删除或填充可选特征量纲与温度不同需标准化weather_condition舍弃或标签编码文本型神经网络需 onehot 后才好用2.2 单变量序列转监督学习构造滑动窗口气温预测本质上是一维时间序列预测但 sklearn 和神经网络回归器都要求输入是(样本数, 特征数)。因此需要把原始序列转换成监督学习形式用过去 7 天或 30 天的平均气温作为特征预测下一天的气温。窗口长度是一个关键超参数天气系统一般以周为周期变化项目里 7 天是更稳妥的默认值。import pandas as pd import numpy as np df pd.read_csv(dataset/WeatherData.csv, parse_dates[date]) df df.sort_values(date).reset_index(dropTrue) df[avg_temp] df[avg_temp].ffill() def make_windows(data, featureavg_temp, window7): X, y [], [] for i in range(len(data) - window): X.append(data[feature].iloc[i:i window].values) y.append(data[feature].iloc[i window]) return np.array(X), np.array(y) X, y make_windows(df, window7) print(X.shape, y.shape)这段代码用了最简单的循环切窗而不是shift或rolling目的是让第一次接触课程设计的同学能直接看懂逻辑。X的每一行是连续 7 天平均气温y是第 8 天的值。实际项目里还会把湿度等特征拼进来但单变量窗口更适合做模型对比因为五种模型共享同一套输入比较起来更公平。2.3 标准化、划分与保存 scaler线性回归、MLP、LSTM 对特征尺度敏感如果输入在十几到三十几摄氏度之间而湿度是百分比梯度下降的收敛速度会受影响。随机森林和决策树不关心尺度但在同一套流程里统一标准化没有坏处。项目里用MinMaxScaler把输入压到 0 到 1 之间训练完成后需要把 scaler 保存下来否则 GUI 加载模型做预测时无法把新输入变换到同一空间。from sklearn.preprocessing import MinMaxScaler from joblib import dump scaler MinMaxScaler(feature_range(0, 1)) X_scaled scaler.fit_transform(X) train_size int(len(X_scaled) * 0.8) X_train, X_test X_scaled[:train_size], X_scaled[train_size:] y_train, y_test y[:train_size], y[train_size:] dump(scaler, models/mlp_scaler.joblib)这里特别要注意切分方式。时间序列不能随机打乱否则未来数据会泄漏进训练集导致评测结果虚高。所以这里直接按索引顺序切前 80% 训练后 20% 测试。dump保存 scaler 到models/mlp_scaler.joblib之后 GUI 预测时用joblib.load读回来对输入做同样变换。feature_range(0,1)对 LSTM 尤其重要因为 LSTM 默认使用tanh激活函数输入落在 0 到 1 区间能让梯度更稳定。3. 五模型原理与实验线性回归、决策树、随机森林、MLP 和 LSTM 怎么对比3.1 线性回归与决策树的基线意义线性回归是整个实验的基准线它假设过去 7 天气温与第 8 天气温存在线性加权关系。如果窗口只有 7 天这个假设基本成立因此线性回归不会太差但它无法刻画“连续三天降温后出现寒潮”这种非线性突变。决策树则走向另一个极端它通过特征阈值分裂能拟合任意非线性关系但单棵树很容易把训练集里的噪声记住所以必须限制max_depth。在实际训练时线性回归直接用LinearRegression决策树用DecisionTreeRegressor(max_depth8)。深度限制在 8 左右是一个折中气温序列本身有周期性太浅拟合不足太深过拟合。这里的要点是两个模型都属于需要“看结果说话”的对照组课程设计展示时先放这两个模型的结果再引出更复杂的结构逻辑上更有说服力。3.2 随机森林如何缓解过拟合随机森林是决策树的集成版本通过随机抽取样本和特征训练多棵树最后取平均。它的优势是方差小对异常值和缺失值更稳健。在气温预测场景里随机森林通常比单棵决策树表现更好但有一个明显缺陷树模型无法外推超出训练集范围的值。如果测试阶段出现历史从未记录过的极端高温树模型预测结果会被限制在训练标签的最大值附近而 LSTM 这类神经网络则具备一定的外推能力。这个项目的random_forest_model.pkl对应RandomForestRegressor(n_estimators100, max_depth10)。n_estimators100是精度和训练时间的平衡点再增大对结果的提升非常有限max_depth10控制了单棵树的复杂度。随机森林在特征数量少、时间序列短的情况下依然可靠所以它适合作为“传统机器学习”这边的代表。3.3 MLP 与 LSTM 的结构差异3 层 MLP 是MLPRegressor(hidden_layer_sizes(64, 32))输入是展平后的 7 维向量经过 64、32 个神经元的全连接层最后输出一个气温值。MLP 的优势是能学习任意非线性映射但它把 7 个时间点当成互不相关的 7 个特征丢失了“第 2 天和第 3 天相邻”这一位置关系。LSTM 不同它接收的输入形状是(样本数, 时间步长, 特征数)也就是把时间维度显式保留下来。LSTM 单元内部有遗忘门、输入门和输出门能记住几天前甚至几周前的温度变化模式。这也解释了为什么项目最终结论是 LSTM 在性能上表现最佳气温序列具有明显的周期性和自相关性LSTM 的结构天然适合捕捉这种短周期依赖。但 LSTM 训练更慢数据量少时容易过拟合所以课程设计里需要用其他四个模型做对照才能得出让人信服的结论。3.4 统一训练与评测五种模型的训练代码可以拆成两部分sklearn 模型走fit/predict流程LSTM 走 Keras 编译和训练流程。先看传统模型这一组。from sklearn.linear_model import LinearRegression from sklearn.tree import DecisionTreeRegressor from sklearn.ensemble import RandomForestRegressor from sklearn.neural_network import MLPRegressor from sklearn.metrics import mean_absolute_error, r2_score models { linear: LinearRegression(), dt: DecisionTreeRegressor(max_depth8, random_state42), rf: RandomForestRegressor(n_estimators100, max_depth10, random_state42), mlp: MLPRegressor(hidden_layer_sizes(64, 32), max_iter300, random_state42) } for name, model in models.items(): model.fit(X_train, y_train) pred model.predict(X_test) print(name, MAE, round(mean_absolute_error(y_test, pred), 3), R2, round(r2_score(y_test, pred), 3))这里所有模型都吃同一个X_train保证对比公平。random_state42固定随机种子是为了让每次运行结果一致答辩时如果老师要求重新跑一遍数字不会变。LSTM 单独处理需要先把输入 reshape 成三位张量。import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense X_lstm_train X_train.reshape((X_train.shape[0], X_train.shape[1], 1)) X_lstm_test X_test.reshape((X_test.shape[0], X_test.shape[1], 1)) model Sequential([ LSTM(64, activationtanh, input_shape(X_train.shape[1], 1)), Dense(1) ]) model.compile(optimizeradam, lossmse) model.fit(X_lstm_train, y_train, epochs50, batch_size32, validation_data(X_lstm_test, y_test))reshape 成(样本数, 7, 1)这一步经常被忽略feature的 1 代表每个时间点上只有一个温度值。如果以后加入湿度需要 reshape 成(样本数, 7, 2)。epochs50对这个小数据集足够再多容易过拟合batch_size32是稳定性比较好的默认值。下表是这套实验里五种模型在课程设计中最常出现的定位。模型核心优势主要风险本项目通常结论线性回归可解释性强训练最快无法捕捉非线性作为基线决策树非线性能力强过拟合无法外推弱于随机森林随机森林稳健抗过拟合无法预测极端值传统模型中较好MLP非线性拟合强忽略时序结构优于部分树模型LSTM显式建模时间依赖训练慢需调参综合分数最高4. 模型保存、GUI 与可视化从训练结果到可演示的界面4.1 模型持久化pkl、joblib、h5 的分工训练完成后的产物是五种不同格式的模型文件很多同学在答辩现场会混淆这些后缀。linear_regression_model.pkl和decision_tree_model.pkl用pickle保存适合纯 Python 对象random_forest_model.pkl同样是 pickle但随机森林内部结构更复杂pickle 也能完整保留。mlp_scaler.joblib和lstm_scaler.joblib用joblib它比 pickle 更擅长序列化包含 NumPy 数组的对象是 sklearn 官方推荐方式。MPL_temperature_prediction_model.h5和LSTM_temperature_prediction_model.h5是 Keras 的HDF5格式保存了网络结构、权重、优化器状态。加载时必须保证 TensorFlow 版本一致否则可能遇到Unknown layer这类错误。加载代码如下。import joblib import pickle from tensorflow.keras.models import load_model scaler joblib.load(models/mlp_scaler.joblib) rf_model pickle.load(open(models/random_forest_model.pkl, rb)) lstm_model load_model(models/LSTM_temperature_prediction_model.h5)load_model最省事不需要重新定义网络结构。pickle.load有安全隐患只加载自己生成的文件。GUI 启动时应该把加载过程放在__init__里而不是每次点击按钮都读一次文件否则界面会卡顿。4.2 用一个 Tkinter 最简界面接住预测项目里的GUI最简版.py是理解整个预测流程的金钥匙它只用标准库tkinter就完成了输入、预测、展示三步。核心逻辑是用户输入过去 7 天的平均气温程序先通过 scaler 变换再调用已加载模型输出结果。下面是一个符合项目结构的简化版实现。import tkinter as tk import joblib from tensorflow.keras.models import load_model class TempPredictor: def __init__(self): self.scaler joblib.load(models/lstm_scaler.joblib) self.model load_model(models/LSTM_temperature_prediction_model.h5) self.window tk.Tk() self.window.title(气温预测) self.entry tk.Entry(self.window, width40) self.entry.pack(pady10) tk.Button(self.window, text预测明天, commandself.predict).pack() self.result tk.Label(self.window, text) self.result.pack(pady10) def predict(self): raw self.entry.get().split(,) values [float(x) for x in raw] import numpy as np arr np.array(values).reshape(1, -1) arr_scaled self.scaler.transform(arr) arr_lstm arr_scaled.reshape((1, arr_scaled.shape[1], 1)) pred self.model.predict(arr_lstm)[0][0] self.result.config(textf预测平均气温{pred:.1f} °C) def run(self): self.window.mainloop() TempPredictor().run()这段代码里的Entry接收逗号分隔的 7 个温度值split(,)后转成浮点数。reshape 成(1, 7)后先做标准化再给 LSTM 加一维特征轴。需要注意 LSTM 要求输入形状里包含 batch 维度所以最终是(1, 7, 1)。如果模型换成了随机森林就不需要 reshape 成三维直接rf_model.predict(arr_scaled)即可。4.3 用 Matplotlib 把预测曲线画出来GUI 显示单个预测值只是结果课程设计里还要有整条测试集的预测对比曲线。气温可视化.ipynb里的做法是把测试集实际气温和模型预测气温画在同一张图上用折线图直接暴露模型在哪些时间段偏差最大。import matplotlib.pyplot as plt plt.figure(figsize(12, 5)) plt.plot(range(len(y_test)), y_test, label实际气温, linewidth2) plt.plot(range(len(y_test)), pred_lstm, labelLSTM 预测, alpha0.8) plt.xlabel(时间点) plt.ylabel(平均气温°C) plt.legend() plt.grid(True) plt.show()pred_lstm来自lstm_model.predict(X_lstm_test)预测输出没有经过 inverse_transform所以如果训练时对 y 也做了缩放这里还需要把预测结果还原到真实摄氏度。项目里没有对 y 做缩放因此可以直接画图。曲线图中应重点观察峰值和低谷处的拟合情况LSTM 往往在转折点比线性回归反应更快这也是答辩时最有说服力的可视化证据。文件加载方式使用场景mlp_scaler.joblibjoblib.load标准化新输入random_forest_model.pklpickle.load快速预测无时序依赖LSTM_temperature_prediction_model.h5load_model最终 GUI 主模型MPL_temperature_prediction_model.h5load_modelMLP 对照展示5. 课程设计跑通后接得住提问切分、指标、依赖与模型复现5.1 时间序列切分不能用随机划分把train_test_split(X, y, test_size0.2)直接用在时间序列上是项目里最容易被发现的错误。随机打乱会让训练集里出现未来日期的样本模型在测试时相当于已经“看过答案”MAE 会异常低。正确做法是直接用索引切分或者使用TimeSeriesSplit做交叉验证。如果老师问为什么不用 sklearn 的默认切分这个问题回答清楚就很容易拿分。5.2 评估指标的组合拳气温预测里“准确率”不是合适指标连续回归任务至少要看 MAE 和 R²。MAE 的单位是摄氏度能直观说明平均差 1.5 度还是 0.8 度R² 衡量模型对数据方差的解释程度接近 1 说明拟合较好。RMSE 也可以加上它对大误差更敏感。课程设计报告里最好像第 3 章那样列一个表格同时展示 MAE 和 R²避免只写“准确率 95%”这种不专业的表述。5.3 依赖锁定与模型文件版本对齐requirements.txt里需要锁定核心库版本尤其是 tensorflow、scikit-learn、joblib、pandas。不同版本的 sklearn 可能导致pickle.load失败TensorFlow 2.x 的 H5 模型在 2.6 和 2.15 之间通常能兼容但如果实测中报AttributeError优先检查numpy版本是否过高。课程设计部署到另一台电脑时建议用python -m venv venv建独立环境再执行pip install -r requirements.txt这样能避免把开发机上的残留包带到演示环境中。models目录下的.joblib、.pkl、.h5要和源码一起提交缺少任何一个文件GUI 都会在启动时直接报错这个细节检查一遍比多跑一个模型更值得。本文还有配套的精品资源点击获取