ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Python天气预测与可视化:一套完整可运行的机器学习项目

Python天气预测与可视化:一套完整可运行的机器学习项目 简介面向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.pyPython脚本从中国天气网抓取天气数据落成原始csvProcessData.pyPython脚本清洗数据、解析日期、归一化生成训练/测试/验证三份csvGetModel.pyPython脚本读取date_train.csv构造特征训练模型保存Model.pklmain.pyPython脚本主入口加载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, encodingutf-8) print(df.head()) print(df.columns.tolist()) print(df.shape)逻辑说明这段代码把date_train.csv读进来打印前五行、列名和形状。如果打印出来的列名是date、tmax、tmin这种那后面模型训练直接按这个字段走如果打印出来是中文列名或者空文件就要先跑ProcessData.py重新生成数据。编码这里有个细节爬下来的csv可能是gbk编码直接utf-8读会报错如果遇到解码问题就改成encodinggbk再试。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[ftmax_lag{lag}] df[tmax].shift(lag) df[ftmin_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_estimators200, max_depth8, random_state42, n_jobs-1 ) model.fit(train[features], train[tmax]) joblib.dump(model, Model.pkl)逻辑说明shift(lag)把温度列往下平移lag行相当于把前一天的tmax、tmin变成今天的特征。dropna()删掉前面几行没有历史数据可用的样本。month和dayofyear是给模型补充当前是几月、一年第几天的信息让模型感知到冬天冷、夏天热这种周期性规律。最后用joblib把训练好的模型存成Model.pklmain.py加载这个文件做预测不需要每次重训。参数说明WINDOW大小直接决定特征数量5表示用前5天的最高最低温共10个特征数据量够的话可以调到7或10n_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 调参入口预测天数、滑动窗口、训练集切分跑通之后就要改参数了。大作业最怕的不是跑不通而是不知道去哪改参数。我一般会在代码开头找常量区所有调整集中在文件顶部几行。下面是常见参数及其调整位置参数所在文件作用建议值WINDOWGetModel.py滑动窗口大小用过去几天预测今天5~10n_estimatorsGetModel.py随机森林树的数量200test_sizeProcessData.py测试集比例0.2PREDICT_DAYSmain.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是怎么来的把预测结果映射成图表可视化部分用的是HTMLECharts方案好处是浏览器直接打开就能看不依赖Jupyter演示时不用切换窗口。main.py做预测之后会把结果填充到HTML模板里用折线图把历史温度和未来预测画在一起。核心逻辑类似下面这段!-- 天气网.html 中的数据填充区示意 -- div idchart stylewidth: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页面用浏览器打开按CtrlShiftS截图工具截一张长图把历史曲线和预测曲线放进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, headersheaders, timeout10) 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, indexFalse)把预测日期和预测温度存下来。好处是答辩时可以直接展示结构化数据老师如果现场问能否导出结果你能当场演示。我一般会把预测结果和真实值合并成一个对比csv更直观。6.3 答辩前的自查清单答辩前强制过一遍这几项虚拟环境能一键激活和安装、GetModel.py重训不报错、main.py预测输出有MAE和R2、HTML图表能正常打开、prediction_result.csv有内容。其中任何一个环节断掉都会在演示现场翻车。这些看似最基础的东西往往是返工重来最耗时间的部分。从那以后我每次拿到别人的大作业源码都强制按先看数据文件 → 再确认模型产物 → 最后跑主程序的顺序走一遍把输出文件和评价指标事先截好图再上台。经历过一次演示现场跑不通的尴尬后这个习惯就再没改过希望帮到你。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进