news 2026/9/12 14:12:39

Python机器学习天气预测与数据可视化完整项目拆解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python机器学习天气预测与数据可视化完整项目拆解

简介:这是一份基于Python的机器学习天气预测与数据可视化完整项目,面向毕业设计、期末大作业及课程设计场景,也可作为机器学习入门实践参考。项目覆盖天气数据采集、清洗、特征处理、模型训练与预测、可视化展示的完整流程,代码注释清晰,新手也能读懂。压缩包共24个文件,体积仅1.42MB,包含4个Python源文件(分别负责数据获取、数据处理、模型训练和主程序)、4个CSV格式的天气数据集、1个已训练好的pkl模型文件、1个HTML前端展示页面,以及12张jpg格式的可视化结果图,还有readme说明文档,便于对照学习与二次开发。目前已有403人学习下载。该项目为个人手打98分高分作品,获导师认可,部署简单,能帮助读者快速理清天气预测类项目的实现思路,是完成毕业设计或课程设计的高质量参考。

1. 天气预测项目为什么值得拆开看

这套基于Python的机器学习天气预测与数据可视化项目,是一个典型的教学型完整工程。源码加数据共24个文件,覆盖了数据采集、预处理、模型训练、结果可视化的完整链路。对于正在做期末大作业、课程设计或毕业设计的同学来说,它的价值不在于某个算法多前沿,而在于把一个真实问题从数据到部署讲清楚了。

项目里最有信息量的部分我个人认为是ProcessData.py到Model.pkl这条线。天气数据本身带有明显的时间序列特征和周期性波动,加上csv里包含的训练集测试集划分,刚好能把回归类模型的训练、评估、调参讲完整。而可视化部分又绑定了HTML页面,不是单纯用matplotlib画两张折线图糊弄过去。下面按数据流顺序把每个模块拆开讲,标注了哪些地方值得照抄、哪些地方容易踩坑。

2. 数据流水线与天气数据的预处理策略

2.1 csv文件结构与字段含义

解压后你会看到date_train.csvdate_test.csvdate_valid.csv三个数据集文件。这三个文件就是整个项目的燃料。训练集和测试集已经按照时间顺序切好,验证集用于模型训练过程中的泛化能力检查,这是标准的监督学习数据划分。

import pandas as pd train_df = pd.read_csv('date_train.csv') test_df = pd.read_csv('date_test.csv') valid_df = pd.read_csv('date_valid.csv') print(train_df.shape, test_df.shape, valid_df.shape) print(train_df.columns.tolist()) print(train_df.head())

这段代码用于确认三份数据的基本规模。read_csv是pandas读取csv文件的标准入口,shape返回的是行列数元组,通过它可以直接判断样本量比例是否合理。columns.tolist会把列名转为列表,用来快速核对字段名拼写,避免后续写特征工程时手误。head则查看前五行,第一时间发现数据错位或空值。

2.2 缺失值处理的常见做法

天气数据经常存在连续缺失,这来源于观测站设备故障或传输中断。ProcessData.py里的处理思路通常是先统计缺失率,再决定填充方式,而不是一股脑全部fillna。

missing_ratio = train_df.isnull().mean().sort_values(ascending=False) print(missing_ratio[missing_ratio > 0])

isnull()把每个单元格转成布尔值,mean()按列计算缺失比例,sort_values把缺失最严重的列排到前面。这一步的意义在于区分"少量缺失"和"大面积缺失":缺失率超过30%的列直接删除或做标记,缺失率低于5%的列用前后时间点的均值或中位数填充。常见的填充手段是train_df['温度'] = train_df['温度'].ffill(),ffill是向前填充,适合温度这类缓慢变化的物理量。

2.3 时间戳转换与特征衍生

原始csv里时间字段大多是字符串格式,必须转成datetime类型才能做时间窗口的特征提取。

train_df['日期'] = pd.to_datetime(train_df['日期']) train_df['月'] = train_df['日期'].dt.month train_df['星期'] = train_df['日期'].dt.dayofweek train_df['是否为周末'] = (train_df['星期'] >= 5).astype(int)

to_datetime把字符串解析为标准时间对象,dt.month取出月份,dayofweek返回星期几的数字表示,周一为0周日为6。天气预测任务里,节假日效应和季节性周期是最强的两个信号来源。把月份转成数值特征,把星期转成是否为周末的0/1标志,模型就能学到此类的周期性规律。另外气压、湿度、风速这类气象要素存在明显的早晚差异,原始数据里如果包含小时粒度,建议再加一列时段划分。

2.4 训练集与测试集的分布一致性检查

这是很多人在课程设计里忽略的步骤。训练集和测试集如果分布偏差过大,模型在线上的表现会断崖式下跌。检查方式是分别统计关键特征的均值、方差和分位数。

for col in ['最高温度', '最低温度', '湿度']: print(col) print('train:', train_df[col].mean(), train_df[col].std()) print('test:', test_df[col].mean(), test_df[col].std())

mean是均值,std是标准差。两组数据在同一特征上的均值差如果超过一个标准差,就要考虑是不是切分时混入了不同季节的数据。天气数据切分时必须在时间轴上顺序切,不能随机打乱。随机切分会导致训练集里出现未来数据,测试集里出现过去数据,在时间序列场景下属于数据泄露,会高估模型表现。

3. 从ProcessData.py到Model.pkl的训练链路

3.1 特征矩阵构建与目标变量选择

train.csv里的weather(天气现象,如晴/多云/小雨)和气温类字段是预测目标的主要候选。如果是回归任务,预测最高温度最常用;如果是分类任务,预测天气现象类别更贴近真实需求。特征矩阵的构建要把原始字段做数值化处理。

import joblib import numpy as np from sklearn.ensemble import RandomForestRegressor from sklearn.model_selection import cross_val_score feature_cols = ['月', '星期', '是否为周末', '湿度', '气压', '风速'] X_train = train_df[feature_cols].fillna(train_df[feature_cols].median()) y_train = train_df['最高温度'] model = RandomForestRegressor(n_estimators=300, max_depth=12, random_state=42) scores = cross_val_score(model, X_train, y_train, cv=5, scoring='neg_mean_absolute_error') print('MAE:', -scores.mean())

fillna用中位数填充是为了兼容缺失行,median比mean更抗离群值干扰。RandomForestRegressor的n_estimators是树的数量,300棵是一个平衡训练时间和精度的数值;max_depth限制单棵树深度,防止过拟合;random_state固定随机种子保证结果可复现。cross_val_score做五折交叉验证,scoring='neg_mean_absolute_error'表示用平均绝对误差作为评估指标,负号是sklearn的统一约定,数值越小越好。这里不用R2作为唯一指标,是因为天气预测场景中绝对误差更能反映实际可用性。

3.2 为什么选择随机森林和梯度提升的组合

单棵决策树容易过拟合,线性回归对非线性交互捕捉不足。项目里用随机森林作为基线模型,如果精度不够,一般再叠加梯度提升决策树。

from sklearn.ensemble import GradientBoostingRegressor gbr = GradientBoostingRegressor( n_estimators=200, learning_rate=0.05, max_depth=4, subsample=0.8, random_state=42 ) gbr.fit(X_train, y_train) print('训练完成, 特征重要性:', gbr.feature_importances_)

GradientBoostingRegressor的learning_rate是每棵树贡献的缩放系数,0.05是偏保守的设置,配合200棵树既能控制过拟合又不会让训练时间失控。subsample是每轮迭代随机抽样的样本比例,0.8让每棵树看到的样本略有不同,增加模型多样性。feature_importances_输出每个特征的贡献度,如果发现月份和气压排在前两位,说明季节性和气压场变化主导气温预测,这是符合气象常识的。

3.3 模型保存与加载的坑

项目里提供了Model.pkl文件,这就是训练完成后序列化保存的产物。使用joblib或pickle保存模型时有一个常见坑:环境依赖版本不一致会导致加载报错。

import joblib joblib.dump(gbr, 'Model.pkl') loaded_model = joblib.load('Model.pkl')

joblib.dump把模型对象序列化到磁盘,joblib.load从磁盘恢复模型对象。注意,加载模型时所在的Python环境和训练时保持一致,尤其是sklearn版本。如果版本不一致,常见的报错是ModuleNotFoundErrorValueError: Unknown label type。解决方法是在项目说明里记录依赖版本,或者用joblib.dump时同时保存模型对应的特征列名列表。项目里readme.md应该做了相关说明,实际复现时建议先pip install scikit-learn==版本号再加载。

3.4 交叉验证与滑动窗口验证

时间序列预测不能直接用普通K折交叉验证,因为随机划分会打乱时间顺序,导致模型在未来数据上训练、在过去数据上验证,产生时间穿越问题。

from sklearn.model_selection import TimeSeriesSplit tscv = TimeSeriesSplit(n_splits=5) for train_index, test_index in tscv.split(X_train): X_tr, X_te = X_train.iloc[train_index], X_train.iloc[test_index] y_tr, y_te = y_train.iloc[train_index], y_train.iloc[test_index] gbr.fit(X_tr, y_tr) score = gbr.score(X_te, y_te) print('fold score:', score)

TimeSeriesSplit是sklearn提供的专门用于时间序列的交叉验证器,它保证测试集的索引永远大于训练集索引。n_splits=5表示切出5组训练验证对,每一组都逐步往后滚。这样做出来的评估结果才能真实反映模型对未来天气的预测能力。

4. 天气图表可视化与HTML前端的联动

4.1 matplotlib绘图的参数细节

项目包含12张jpg图像文件,这些是模型评估和EDA阶段产出的图表。常见的可视化内容包括气温时序折线图、湿度分布直方图、预测值与真实值散点图。这里给出一个高频使用的绘图模板。

import matplotlib.pyplot as plt import matplotlib matplotlib.rcParams['font.sans-serif'] = ['SimHei'] matplotlib.rcParams['axes.unicode_minus'] = False plt.figure(figsize=(12, 5)) plt.plot(test_df['日期'], y_test, label='真实温度', color='#333333') plt.plot(test_df['日期'], y_pred, label='预测温度', color='#d62728', linestyle='--') plt.xlabel('日期') plt.ylabel('温度 (℃)') plt.title('最高温度预测对比') plt.legend() plt.xticks(rotation=45) plt.tight_layout() plt.savefig('预测对比图.jpg', dpi=150) plt.show()

font.sans-serif设置为SimHei是为了让中文标签正常显示,axes.unicode_minus设为False是为了让负号正常显示。figure里的figsize控制画布宽高,dpi=150控制保存分辨率。plot中linestyle='--'把预测线设为虚线,与真实值实线区分。xticks(rotation=45)旋转日期刻度标签,防止重叠。tight_layout自动调整子图间距,避免标签被裁切。

4.2 用HTML组织图表的零依赖方案

项目里weather网.html把图片整合到页面中,这是最轻量的前端展示方式。不需要启动Flask或Django,双击HTML就能在浏览器里查看效果。原理是通过img标签引用本地jpg文件。

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>天气预测可视化</title> <style> body { background: #f5f7fa; font-family: "Microsoft YaHei"; } .chart-container { max-width: 1000px; margin: 20px auto; background: #fff; padding: 20px; } h1 { text-align: center; color: #2c3e50; } img { width: 100%; border-radius: 8px; } </style> </head> <body> <h1>天气预测与数据可视化</h1> <div class="chart-container"> <img src="预测对比图.jpg" alt="预测对比"> </div> </body> </html>

这个页面的核心价值在于展示成果,不需要后端参与就能跑。CSS里max-width限制内容宽度保证大屏下不拉伸变形,margin: 20px auto让容器水平居中,border-radius给图片圆角提升观感。如果想把多张图放进来,复制chart-container这个div追加即可。

4.3 预测误差分布图的三种画法

误差分析是评估模型上限的关键。预测值和真实值的差值分布能直观暴露系统偏差。

error = y_pred - y_test plt.hist(error, bins=30, edgecolor='white', alpha=0.8) plt.axvline(x=0, color='red', linestyle='--', linewidth=1) plt.xlabel('预测误差 (℃)') plt.ylabel('频数') plt.title('预测误差分布') plt.savefig('误差分布图.jpg', dpi=150)

hist是直方图函数,bins=30把误差范围切为30个区间,alpha=0.8控制柱子透明度,edgecolor给柱子描边便于区分相邻柱体。axvline在x=0处画一条红色虚线作为零误差参考线,观察误差分布相对这条线的偏移就能判断模型系统性偏高还是偏低。

5. GetData.py与实时天气数据采集

5.1 静态数据与动态采集的取舍

date_train.csv和date_test.csv是打包自带的静态数据,适合复现项目流程。但如果要部署成每日更新的预报系统,就需要用GetData.py从公开天气接口拉取新数据。项目采用requests模块发送HTTP请求,解析JSON响应。

5.2 天气接口调用的最小实现

import requests import pandas as pd from datetime import datetime def fetch_weather(city_code): url = "https://restapi.amap.com/v3/weather/weatherInfo" params = { "key": "你的API_KEY", "city": city_code, "extensions": "all" } resp = requests.get(url, params=params, timeout=10) data = resp.json() forecasts = data.get("forecasts", []) return forecasts result = fetch_weather("110000") print(result)

requests.get中的timeout=10是请求超时阈值,防止接口无响应时程序卡死。resp.json()把响应体解析为Python字典,get方法从嵌套字典里安全取值,避免KeyError。extensions参数传all时返回多日预报数据,传base只返回实时天气。项目里如果没有真实的API_KEY,建议把获取到的数据转为csv格式,保持和原有训练数据结构一致。

5.3 新采集数据如何喂给Model.pkl

采集到新数据后,要走和训练时一致的特征工程流程。

def preprocess_new(df): df['日期'] = pd.to_datetime(df['日期']) df['月'] = df['日期'].dt.month df['星期'] = df['日期'].dt.dayofweek df['是否为周末'] = (df['星期'] >= 5).astype(int) features = df[feature_cols].fillna(df[feature_cols].median()) return features

month和dayofweek保证新增数据具备模型在训练时见过的特征。fillna用中位数是为了处理新采集数据可能存在的空值。特征列的顺序必须与原训练时feature_cols完全一致,否则输入模型时列位置错位会得到错误预测结果。

5.4 爬虫脚本的完善点

如果没有现成的API_KEY,用requests直接抓网页时需要处理编码和反爬。

headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } resp = requests.get(url, headers=headers, timeout=10) resp.encoding = 'utf-8'

headers模拟浏览器标识,避免部分站点返回403状态码。resp.encoding手动指定解析编码,防止中文乱码。这类方式适合作为演示补充,不建议在生产环境长期使用,因为页面结构一变脚本就要跟着改。GetData.py在这个项目里的最佳定位是数据补充,而不是核心模块。

6. 模型部署到本地运行时的几个关键检查

6.1 readme.md里最容易遗漏的依赖清单

把项目下载下来后自己动手跑一遍时,最容易卡住的是环境依赖。天气预测的可复现要求每行代码都能在当前环境执行。readme.md里建议标注完整的依赖清单。

pip install pandas numpy scikit-learn matplotlib requests python main.py

python main.py是项目入口,它会读取训练好的Model.pkl并对test数据集做预测,最终生成对比图和HTML页面。无论从哪个环节跑,保证pandas版本不低于1.2、scikit-learn版本不低于0.24是一个安全边界。

6.2 预测结果的验证方法

模型能不能用,最后要看预测值和真实值之间的偏差是否收敛。

from sklearn.metrics import mean_absolute_error, r2_score mae = mean_absolute_error(y_test, y_pred) r2 = r2_score(y_test, y_pred) print(f"MAE: {mae:.2f} ℃, R2: {r2:.3f}")

mean_absolute_error计算平均绝对误差,单位仍是摄氏度,用于直观描述平均偏差点数;r2_score反映模型对真实值方差的解释比例,越接近1越好。在天气预测场景下,MAE低于2℃、R2高于0.85,可以认为项目达到了课程设计比较优秀的水平。

6.3 把jpg图表嵌入HTML展示的最终技巧

最后收尾阶段,要把六张以上的图整合到一份HTML中,建议先统一输出尺寸。在遍历生成图表时固定figsize和dpi,这样HTML里所有img元素可以共用一套CSS宽度设置,页面效果更整洁。

for idx, (col, dataseries) in enumerate(data_dict.items()): plt.figure(figsize=(12, 5), dpi=120) plt.plot(dataseries['date'], dataseries['value']) plt.title(col) plt.savefig(f'chart_{idx}.jpg') plt.close()

enumerate同时拿到序号和内容,f-string拼出文件名。plt.close每画一张图就关闭画布,是为了释放内存,否则循环画几十张图内存占用会持续累积。生成的chart_0.jpg、chart_1.jpg这类命名可以直接写进HTML模板,用Python字符串替换批量生成页面代码,不用手动一条条粘贴。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 14:10:21

Spring Boot全栈开发入门与实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 14:10:11

AI视频工具选型指南:小云雀、即梦、可灵、PixVerse深度对比

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 14:08:50

JSP文件上传插件开发:拖拽上传与局域网优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 14:08:18

基于Arnold与Logistic的MATLAB图像加解密及传输仿真解析

简介&#xff1a;基于MATLAB的图像加解密及传输仿真课程设计资源包&#xff0c;面向电子信息、通信工程、计算机等专业在校生&#xff0c;可用于课程设计、大作业或毕业设计选题。资源针对图像加密、解密及传输链路仿真需求&#xff0c;提供完整可运行的MATLAB源码、标准测试图…

作者头像 李华