简介:面向Python期末大作业与课程设计场景的天气预测和可视化项目源码,基于机器学习完成气温、天气状态等数据的获取、清洗、建模、预测与图表展示全流程,适合需要可直接运行的高分作业模板的高校学生。压缩包共23个文件,大小仅1.42MB,包含4个Python脚本(覆盖数据爬取、数据处理、模型训练与主运行入口)、4份CSV训练与测试数据、1个已训练好的Model.pkl模型文件,以及12张项目效果展示图和天气网HTML可视化页面,代码结构清晰、目录层次完整。下载后无需修改即可直接复现运行,既能作为Python课程设计或机器学习实践作业的完整交付方案,也可帮助初学者理解数据预处理、模型持久化与可视化呈现的典型流程。目前已有1099人学习浏览,适合想要快速拿到高分大作业成果的开发者参考借鉴。
1. 天气预测加可视化:一套能直接跑的Python机器学习项目
期末大作业要写一个"机器学习应用",天气预测加可视化几乎是公认的稳妥选题:数据公开、特征直观、展示效果好。这次我拆的,就是一个基于Python的天气预测与可视化项目源码,包里从爬虫、数据清洗、模型训练到HTML可视化一条链路全都有,而且是跑通状态,下载后不用改代码就能复现。适合三类人:要交Python课程设计或期末大作业的、刚学完scikit-learn想刷完整流程的、以及想找一个能边演示边答辩的实战模板的。下面我按文件逐个拆,说清楚每个文件在干什么、运行顺序是什么、坑在哪里。
2. 项目拆解:六个文件各管一段活,数据链路一眼看穿
2.1 文件地图:先搞清包里每个文件是干什么的
打开压缩包,里面是一个weather-master目录,所有代码和数据都在里面。很多同学拿到大作业源码第一反应是直接双击main.py,结果各种报错,就是因为没搞清文件之间的关系。先看这张文件清单,心里有个地图再动手。
| 文件 | 类型 | 在项目里的活 |
|---|---|---|
| GetData.py | Python脚本 | 从中国天气网抓取天气数据,落成原始csv |
| ProcessData.py | Python脚本 | 清洗数据、解析日期、归一化,生成训练/测试/验证三份csv |
| GetModel.py | Python脚本 | 读取date_train.csv,构造特征,训练模型,保存Model.pkl |
| main.py | Python脚本 | 主入口:加载Model.pkl,读测试集做预测,输出结果并生成可视化 |
| Model.pkl | 模型文件 | 训练产物,main.py直接加载它做推理,不需要重训 |
| date_train.csv | 数据文件 | 训练集,模型从这里学规律 |
| date_test.csv | 数据文件 | 测试集,用来评估模型真实表现 |
| date_valid.csv | 数据文件 | 验证集,调参时看效果用 |
| china_today.csv | 数据文件 | 最近一天天气快照,画"今日实况"对比用 |
| 天气网.html | 页面文件 | 可视化模板,浏览器打开看图表 |
| .gitignore | 配置文件 | 让git忽略中间文件,交作业或传GitHub时用 |
这套代码的核心思路是"数据 → 清洗 → 训练 → 推理 → 展示"五段式。GetData.py负责第一段,ProcessData.py负责第二段,GetModel.py和Model.pkl负责第三段,main.py负责第四段和第五段。包里自带了三份csv,意味着爬虫部分可以跳过,直接跑模型训练和预测。
2.2 数据流向:从爬虫到csv再到训练集
先看数据长什么样。用pandas读一下date_train.csv的头部,确认字段名,后面所有特征工程都依赖这些列。包里的三个csv不是随便分的,date_train是历史数据,date_test是留出来的评估数据,date_valid是调参时用的,分工不同,不能混着用。
import pandas as pd # 常见做法是先读训练集,确认列名和数据形态 df = pd.read_csv("date_train.csv", encoding="utf-8") print(df.head()) print(df.columns.tolist()) print(df.shape)逻辑说明:这段代码把date_train.csv读进来,打印前五行、列名和形状。如果打印出来的列名是date、tmax、tmin这种,那后面模型训练直接按这个字段走;如果打印出来是中文列名或者空文件,就要先跑ProcessData.py重新生成数据。编码这里有个细节:爬下来的csv可能是gbk编码,直接utf-8读会报错,如果遇到解码问题就改成encoding="gbk"再试。
ProcessData.py在这条链路里干的活通常是:把日期字符串转成datetime、把缺失的温度值用前后均值补上、按日期排序、再按比例切出三份csv。之所以要排序,是因为后面做滑动窗口特征时,时间顺序乱了会导致预测结果完全失效,这一点在避坑章节会细说。
2.3 核心训练代码:窗口特征与模型保存
GetModel.py是整个项目的核心,它决定模型能不能学到天气的规律。天气数据本质上是时间序列,直接用当天数据预测当天没意义,常见做法是构造"过去N天特征预测今天"的窗口结构。下面是一段与项目思路一致的核心训练代码:
# GetModel.py 训练核心(节选) import pandas as pd import numpy as np from sklearn.ensemble import RandomForestRegressor import joblib # 窗口大小:用过去5天的温度预测今天 WINDOW = 5 def build_features(df): # 生成滑动窗口特征:往前取WINDOW天的最高/最低温度 for lag in range(1, WINDOW + 1): df[f"tmax_lag{lag}"] = df["tmax"].shift(lag) df[f"tmin_lag{lag}"] = df["tmin"].shift(lag) # 日期辅助特征:让模型感知季节和月份周期 df["month"] = pd.to_datetime(df["date"]).dt.month df["dayofyear"] = pd.to_datetime(df["date"]).dt.dayofyear return df.dropna() train = build_features(pd.read_csv("date_train.csv")) features = [c for c in train.columns if c not in ("date", "tmax", "tmin")] model = RandomForestRegressor( n_estimators=200, max_depth=8, random_state=42, n_jobs=-1 ) model.fit(train[features], train["tmax"]) joblib.dump(model, "Model.pkl")逻辑说明:shift(lag)把温度列往下平移lag行,相当于把前一天的tmax、tmin变成今天的特征。dropna()删掉前面几行没有历史数据可用的样本。month和dayofyear是给模型补充"当前是几月、一年第几天"的信息,让模型感知到冬天冷、夏天热这种周期性规律。最后用joblib把训练好的模型存成Model.pkl,main.py加载这个文件做预测,不需要每次重训。
参数说明:WINDOW大小直接决定特征数量,5表示用前5天的最高最低温共10个特征,数据量够的话可以调到7或10;n_estimators是随机森林里树的数量,200棵对于大作业规模足够大;max_depth限制树深度,8层防止过拟合;random_state固定随机种子,保证每次跑出来的结果一致,答辩时老师可能会追问这个参数,要能答上来。
3. 把代码跑起来:环境、顺序和参数,三次命令出结果
3.1 环境准备:Python版本、依赖库清单
这套代码不挑版本,Python 3.8到3.11都能跑,核心依赖就几个:pandas做数据处理,numpy做数值计算,scikit-learn提供模型,matplotlib画图,joblib读写模型,requests和beautifulsoup4是爬虫用的。如果你只用自带数据跑通流程,requests和beautifulsoup4甚至可以暂时不装。
# 在项目目录下创建虚拟环境并激活(推荐) python -m venv venv venv\Scripts\activate # Windows # source venv/bin/activate # macOS / Linux # 安装依赖 pip install pandas numpy scikit-learn matplotlib joblib requests beautifulsoup4逻辑说明:创建虚拟环境是为了避免污染系统Python,也不会被系统里其他版本的库干扰。pip install把项目需要的库一次装齐。如果网络下载慢,可以在pip后面加 -i https://pypi.tuna.tsinghua.edu.cn/simple 用国内镜像源加速。
参数说明:pandas、numpy、scikit-learn这三个库版本兼容性最强,不需要锁定具体版本。如果你用的是Python 3.11,建议scikit-learn装1.3以上版本,旧版本在新解释器上可能会报编译错误。
3.2 复现顺序:先训练模型,再跑主程序,最后开HTML
装完依赖,直接按顺序跑两个命令就能看到效果。前提是csv文件都在,Model.pkl还没生成或想重新训练。第一次跑建议全程盯着控制台输出,每个阶段都有打印信息,能看出卡在哪一步。
cd weather-master # 第一步:训练模型,生成Model.pkl python GetModel.py # 第二步:跑主程序,控制台输出预测结果并生成可视化 python main.py逻辑说明:这两个命令的顺序不能颠倒。main.py的逻辑是"读取Model.pkl → 读测试数据 → 预测 → 画图",如果Model.pkl不存在,main.py会在加载模型那一行直接报FileNotFoundError。先跑GetModel.py就是为了确保模型文件存在。包里如果已经带了Model.pkl,可以跳过第一步直接跑main.py,但重新训练一遍也没什么坏处,还能亲眼看到训练过程的输出。
跑完main.py之后,项目目录下会多出可视化页面文件,或者在控制台看到预测结果。双击打开HTML文件,就能看到历史气温曲线和未来几天预测曲线的对比图。到这一步,整个流程就算跑通了。
3.3 调参入口:预测天数、滑动窗口、训练集切分
跑通之后就要改参数了。大作业最怕的不是跑不通,而是不知道去哪改参数。我一般会在代码开头找"常量区",所有调整集中在文件顶部几行。下面是常见参数及其调整位置:
| 参数 | 所在文件 | 作用 | 建议值 |
|---|---|---|---|
| WINDOW | GetModel.py | 滑动窗口大小,用过去几天预测今天 | 5~10 |
| n_estimators | GetModel.py | 随机森林树的数量 | 200 |
| test_size | ProcessData.py | 测试集比例 | 0.2 |
| PREDICT_DAYS | main.py | 预测未来几天 | 7 |
在main.py里通常会有一段类似这样的常量区:
# main.py 顶部常量区:改这里就能换场景 CITY = "北京" PREDICT_DAYS = 7 MODEL_PATH = "Model.pkl"参数说明:PREDICT_DAYS改成3就是预测未来三天,改成14就是预测两周。注意预测天数越长,模型累计误差越大,大作业演示时用7天最稳妥,既能展示趋势又不至于离谱。WINDOW如果改大,训练数据会减少,因为前WINDOW行都被dropna删掉了;数据总量不大时别超过10。
4. 验证与可视化:让模型的"准"和"不准"都有依据
4.1 main.py到底输出了什么:控制台结果与评价指标
跑完main.py之后,控制台不会只输出一句"运行成功",而是会打印预测结果和模型在测试集上的评估指标。这些数字是答辩时最重要的素材。一个典型的输出长这样:
==== 天气预测结果 ==== 未来7天预测最高温度(℃): 第1天: 12.5 第2天: 13.1 第3天: 14.0 第4天: 13.8 第5天: 15.2 第6天: 16.1 第7天: 15.5 ==== 模型评估 ==== 测试集MAE: 1.82℃ 测试集R2: 0.91逻辑说明:MAE是平均绝对误差,单位是摄氏度,1.82意味着预测温度和真实温度平均偏差不到2度,这种精度在天气预测大作业里已经能拿得出手。R2是决定系数,越接近1说明模型解释力越强,0.91意味着测试集上91%的温度波动能被模型解释。这两个指标要结合起来看:MAE衡量误差大小,R2衡量拟合程度。
如果跑出来的MAE超过3度,说明模型效果一般,别急着改模型,先检查数据里有没有异常值或者特征有没有对齐。天气预测本身就是个带随机性的任务,2度以内的误差完全正常,不用为了追求更小误差去疯狂堆参数。
4.2 "天气网.html"是怎么来的:把预测结果映射成图表
可视化部分用的是HTML+ECharts方案,好处是浏览器直接打开就能看,不依赖Jupyter,演示时不用切换窗口。main.py做预测之后,会把结果填充到HTML模板里,用折线图把历史温度和未来预测画在一起。核心逻辑类似下面这段:
<!-- 天气网.html 中的数据填充区(示意) --> <div id="chart" style="width:100%;height:400px;"></div> <script src="./echarts.min.js"></script> <script> // 未来7天预测温度,由main.py动态生成或从JSON读取 var predictData = [12.5, 13.1, 14.0, 13.8, 15.2, 16.1, 15.5]; var chart = echarts.init(document.getElementById("chart")); chart.setOption({ xAxis: { type: "category", data: ["周一","周二","周三","周四","周五","周六","周日"] }, yAxis: { type: "value", name: "最高气温(℃)" }, series: [{ type: "line", data: predictData, smooth: true, areaStyle: { opacity: 0.3 } }] }); </script>逻辑说明:这个HTML文件既是爬虫抓下来的参考页面,也是可视化的承载模板。main.py预测完会把结果写进页面或者生成一份新的HTML,用ECharts把数据画成折线图。smooth: true让曲线平滑,看起来更专业;areaStyle给折线下方加渐变填充,视觉上更像一个完整的数据产品。
参数说明:xAxis的data是日期标签,如果main.py输出的是实际日期,这里改成从预测结果里动态取日期;yAxis的name单位改成"℃"更严谨。如果你想把图表换成柱状图,把series里的type改成bar就行,但天气预测用折线图更直观。
4.3 从HTML到答辩演示:截图、对比与讲解顺序
代码跑通只是第一步,怎么演示决定了老师的第一印象。我见过太多同学打开一个光秃秃的图表,张口就是"这个模型预测还挺准的",没有任何对比,说服力很差。正确的演示顺序是:先展示历史数据曲线说明数据来源和时间范围,再展示预测结果曲线说清楚"预测了未来7天的最高气温",最后亮出MAE和R2两个指标。
把HTML页面用浏览器打开,按Ctrl+Shift+S截图工具截一张长图,把历史曲线和预测曲线放进PPT里。讲解时强调"模型在测试集上的平均误差是1.82度",这句话比你描述十句模型结构都有用。老师最关心的永远是:你的模型到底准不准,怎么证明它准。
5. 避坑指南:天气预测大作业最容易翻车的五个点
5.1 ModuleNotFoundError:一运行就报缺包
现象:双击运行main.py,控制台第一行就报ModuleNotFoundError: No module named 'sklearn',或者pandas、matplotlib报类似的错。
原因:操作系统里装了好几个Python环境,你运行命令的这个环境里根本没有这些第三方库。有时候是之前在Anaconda里装过库,换了终端窗口后默认Python变成了系统自带的那个,库全都不见了。
解决:在项目目录下重新建一个虚拟环境,激活后把依赖一次装齐。
python -m venv venv venv\Scripts\activate pip install pandas numpy scikit-learn matplotlib joblib requests beautifulsoup4装完之后用python main.py运行,不要直接双击文件。如果还报错,看报错信息里是哪个库缺了,单独补装。血泪经验:报错第一行永远是最有用的,别只看最后的Traceback。
5.2 预测结果是一条水平直线:特征窗口没对齐
现象:main.py跑通了,但预测出来未来7天温度全是一个值,比如全是12.5,折线图画出来是平的,看起来像模型没学到东西。
原因:这个翻车场景在时间序列项目里特别常见。滑动窗口构造特征时shift(lag)会留下NaN,如果dropna之后数据量太小,甚至所有特征列都是同一行;或者原始数据没有按日期排序,shift取到的是完全无关的相邻行,模型学不到规律。
解决:回到GetModel.py,检查build_features里有没有按日期排序和dropna。正确的做法是先按date升序排序,再构造窗口特征,最后dropna。可以在pandas里加上df = df.sort_values("date")再shift。另外检查特征列表里有没有意外混入"date"列本身,日期当特征是典型的用未来信息偷看答案。
5.3 爬虫GetData.py拿不到数据:网站结构变了或UA被拦
现象:运行GetData.py,爬了半天,最后生成的csv只有表头没有数据,或者请求直接超时。
原因:中国天气网的页面结构偶尔会调整,爬虫里如果写死了标签选择器,改版后就定位不到数据了。另外requests默认的User-Agent被服务器识别为脚本,被反爬挡掉。
解决:先给requests加上浏览器标识,这是最常被忽略的坑。
# GetData.py 请求头设置 import requests url = "https://example-weather-site.com/city_forecast.html" 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"如果加了UA还是空数据,大概率是页面结构变了,检查resp.text里有没有原来的标签结构。大作业场景下我不建议花太多时间在爬虫上,包里已经有现成的csv,优先跑通模型,爬虫当作加分项去修。
5.4 生成的HTML图表空白:路径、CDN和编码三重坑
现象:main.py运行完,HTML也生成了,但用浏览器打开后图表区域是空白,控制台F12里能看到红色报错。
原因:三种情况最常见。一是HTML里引用的echarts.min.js是CDN链接,电脑没联网或者CDN被墙,JS根本没加载;二是main.py写HTML时用了绝对路径,换目录后JS文件找不到;三是HTML默认编码不是utf-8,温度数据里的中文或摄氏度符号显示乱码。
解决:把echarts.min.js下载到项目本地,HTML里用相对路径引用;确保HTML文件头部有 。用浏览器按F12打开开发者工具,看Console面板里的报错信息,JS文件加载失败会直接显示404。
5.5 换城市后模型明显变差:训练分布的边界问题
现象:用北京的数据训练出来的Model.pkl好好的,换成广州的数据重新训练后,MAE从1.8涨到4.0,甚至预测出负温度。
原因:不同城市的气候分布差别很大,ProcessData.py里的归一化参数是在原始数据集上fit出来的,如果换了城市但没有重新fit归一化,模型输入特征的范围就错位了。另外Model.pkl里存的是旧城市的模型,直接用新城市数据做预测,属于拿错误的分布做推理。
解决:换城市或换数据源时,强制走一遍完整流程:ProcessData.py重新生成csv → GetModel.py重新训练 → 主程序再预测。不要想着偷懒只改数据文件不重训模型。Model.pkl这个名字看起来是个黑匣子,其实它就是一堆参数,换数据必须重新拟合,没有捷径。
6. 进阶:从"能运行"到"能拿高分"的三个加分点
6.1 加一个Baseline对比,让实验结果立体
只给一个模型结果,老师没法判断你模型的真实水平。常见做法是加一个最简单的Baseline,比如"用昨天最高气温直接预测今天最高气温"的朴素预测,和你的随机森林模型放在一起表格式对比。只要模型MAE明显低于Baseline,就说明机器学习的引入是有价值的,这一个表格顶过十页PPT描述。
6.2 把预测结果落盘成csv,给数据留痕
main.py除了打印控制台和生成HTML,再加一行df.to_csv("prediction_result.csv", index=False),把预测日期和预测温度存下来。好处是答辩时可以直接展示结构化数据,老师如果现场问"能否导出结果",你能当场演示。我一般会把预测结果和真实值合并成一个对比csv,更直观。
6.3 答辩前的自查清单
答辩前强制过一遍这几项:虚拟环境能一键激活和安装、GetModel.py重训不报错、main.py预测输出有MAE和R2、HTML图表能正常打开、prediction_result.csv有内容。其中任何一个环节断掉,都会在演示现场翻车。这些看似最基础的东西,往往是返工重来最耗时间的部分。
从那以后我每次拿到别人的大作业源码,都强制按"先看数据文件 → 再确认模型产物 → 最后跑主程序"的顺序走一遍,把输出文件和评价指标事先截好图再上台。经历过一次演示现场跑不通的尴尬后,这个习惯就再没改过,希望帮到你。
本文还有配套的精品资源,点击获取