news 2026/10/7 3:57:06

基于机器学习的城市空气质量等级预测系统:从特征工程到模型部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于机器学习的城市空气质量等级预测系统:从特征工程到模型部署

这几年我在做环境数据相关的项目时,最常被问到的问题就是:“机器学习到底能用在环境监测上做什么?”其实答案比很多人想得实在得多——比如今天要聊的这个基于机器学习的城市空气质量等级预测系统。它不是一个炫技的AI Demo,而是一个能落地、能跑通、能解决实际问题的完整项目:输入过去几小时的污染物浓度和气象数据,输出未来一段时间的空气质量等级(优、良、轻度污染、中度污染、重度污染、严重污染),甚至可以给出每个等级的概率。

我在做同类项目时最大的感受是:这个题目看起来简单,但实际动手就会踩到一堆坑——从数据缺失处理到类别不均衡,从模型过拟合到“看起来精度很高但一上线就拉胯”,每一个环节都有讲究。这篇文章就围绕这个项目,把我自己的设计与实现思路、关键细节、踩坑经历完整捋一遍,适合正在做机器学习课程设计、数据挖掘大作业,或者想入门时序预测 + 分类任务的读者参考。

1. 项目概述与整体设计思路

1.1 这个系统到底解决什么问题

城市空气质量预测,表面上是在预测“明天的空气好不好”,实际上是一个典型的多类别分类问题。我们不是在预测PM2.5的具体数值(那是回归任务),而是预测空气质量等级——这更贴近普通人的日常认知。你打开手机天气App,看到的是“轻度污染”而不是“PM2.5浓度85微克/立方米”,这就是等级预测的价值。

从技术角度看,这个任务的核心链条是:

  • 采集历史空气污染物数据(PM2.5、PM10、SO2、NO2、O3、CO)
  • 融合气象特征(温度、湿度、风速、风向、气压)
  • 使用机器学习模型学习“当前环境状态 → 未来空气质量等级”的映射关系
  • 输出预测结果和概率分布

我当时设计这个系统时,给自己定了三个硬性指标:第一,预测的F1分数(宏平均)不能低于0.82;第二,系统要能处理“未来1小时、3小时、6小时、12小时、24小时”五个预测窗口;第三,整套流程从原始数据到预测结果,必须能一键跑通,而不是在Notebook里东一块西一块。

1.2 为什么用机器学习而不是传统统计方法

很多人第一反应是:“空气质量预测不是有数值模式吗?用CMAQ、WRF-Chem这类大气化学模型不就行了?”

理论上没错,但现实很骨感。大气化学模型需要极其复杂的物理化学机制描述,运算量大,而且对输入数据的要求极高——你需要掌握排放源清单、化学转化参数、边界层高度等一堆专业数据,普通人根本跑不起来。就算跑起来了,对一个城市级别的预测场景来说,性价比也低得惊人。

而机器学习方法在这个场景下有天然优势:

  • 特征提取能力强:空气质量变化受多种因素耦合影响,机器学习能自动学出非线性关系,不需要人为构建复杂的物理方程。
  • 部署成本低:训练好的模型只是一个文件,加载后单次推理只需毫秒级,可以嵌入到Web服务里实时响应。
  • 迭代更新快:城市产业结构和气象规律随时间变化,传统模型要重新调参,机器学习模型只需要定期用新数据重新训练。

我当时选了LightGBM作为主力模型。为什么?因为空气质量数据本身存在明显的周期性和季节性,树模型对这类特征交互的捕捉能力足够强,而且训练速度比深度模型快几个数量级。疫情三年后的城市环境数据噪声比较大,LightGBM对异常值的鲁棒性也比神经网络好一些。

1.3 整体模块划分

我的系统分四个模块:

模块职责技术要点
数据采集与存储获取污染物浓度和气象数据API定时拉取、数据库存储
特征工程构建时序特征、天气特征、衍生特征滑窗统计、滞后特征、周期编码
模型训练与评估训练多窗口预测模型LightGBM多分类、类别不均衡处理
预测服务与可视化对外提供预测API并展示结果Flask服务、前端图表展示

模块和模块之间尽量解耦。数据采集只管把数据安全落库,模型训练只负责出模型文件,预测服务加载模型文件对外服务。这样做的好处是:后期改进任何一个环节,都不会影响整条链路。

2. 数据基础与特征工程实战

2.1 数据来源与预处理

我用的数据来自城市环境监测站点公布的逐小时空气质量数据,包含六个污染物指标。这里我必须先泼一盆冷水:官方数据看着整齐,实际脏得让你怀疑人生。缺失值、异常值、传感器校准造成的跳变,一个都不会少。

我的数据处理管线是这样的:

  1. 时间对齐:把不同来源的数据(污染物监测频率是1小时,气象数据可能是3小时间隔)统一重采样到小时级。这一步用Pandas的resample方法就能完成,关键是确定对齐策略——我建议用向前填充(ffill)而不是插值,因为空气质量变化在短时间内的连续性并不像温度那么强。
  2. 缺失值处理:连续缺失小于等于3小时,用前后有效值的线性插值填补;连续缺失超过6小时,直接删除该时段。原因是,超过6小时的缺失已经说明数据质量严重不可靠,硬填补只会污染模型输入。
  3. 异常值剔除:污染物浓度不会出现“负值”或“突变到原先十倍”的情况,这是物理约束。我设置了一个浓度上限阈值,超过则视为传感器故障,替换为缺失值。

实操提示:千万不要用简单的中位数填充缺失值,那会把时间序列的波动性磨平,模型学到的全是“平均空气”,预测结果会严重偏向中间等级。

2.2 特征工程是项目的灵魂

很多新人做预测项目,把数据喂给模型就不管了,结果精度一直上不去。我后来总结出一条经验:在空气质量预测这个场景,特征工程对模型效果的贡献,至少占70%,模型算法只占30%。

我构建的特征分四类:

第一类:实时状态特征。当前时刻六个污染物浓度值、温度、湿度、气压、风速、风向。这些是最基础的输入,但单独使用效果很差,因为它们只反映“此刻”的状态。

第二类:时序统计特征。过去3小时、6小时、24小时的污染物浓度平均值、标准差、最大值、最小值。这类特征的价值在于,它不仅告诉模型“现在空气怎样”,还告诉模型“空气正在怎样变化”——是稳定升高还是剧烈波动,这个信息对预测未来趋势至关重要。

第三类:滞后特征。将目标变量(未来某时刻的空气质量等级)的前1天、前2天、前7天同时刻的值作为特征。这利用了空气质量变化的“惯性效应”和“周效应”,也是我在实测中提升效果最明显的特征之一。

第四类:时间周期特征。将时间转换为小时数、星期几、是否节假日等循环编码。空气质量有非常明显的日变化(早晚高峰污染加重)和季节性变化(冬季比夏季差),周期特征让模型有机会捕捉到这些规律。

第五类(进阶):气象交互特征。比如“湿度×PM2.5”——高湿度条件下PM2.5更容易吸湿增长;再比如“风速×风向”——静风条件下污染物更容易累积。虽然树模型本身能做特征交互,但人为构建这些有物理含义的交互特征,可以显著降低模型学习难度。

2.3 数据清洗的细节经验

这个项目里我栽过一个大跟头——训练数据和测试数据的时间分布不匹配。前几个月数据训练,后几个月测试,结果测试集预测效果奇差。排查后发现,原因是训练数据主要集中在空气质量较好的月份,而测试集里恰好包含了几个重污染时段,属于典型的数据分布漂移问题。

解决办法是:训练集必须覆盖全年的完整周期,至少包含一个完整采暖季。如果数据只有半年,宁可按月份随机抽取训练集和验证集,也不要按时间先后切分。

还有一个容易忽略的点:节假日效应。我在特征里加了“是否节假日”这个布尔特征之后,模型在春节、国庆期间的预测成绩提升了近8个百分点。原因很简单,节假日期间机动车出行和工业活动模式发生剧烈变化,空气质量规律与平时完全不同,如果不告诉模型“今天特殊”,它就会用平时的规律去预测,自然不准。

3. 机器学习模型选型与对比分析

3.1 不同模型的适用性分析

在动手写代码之前,我先对常用模型做了横向对比,这里直接放结论:

模型准确率(24h窗口)F1(宏平均)训练时间可解释性适用性评价
逻辑回归0.710.66秒级高太弱,无法捕捉非线性关系
K近邻0.680.62无需训练中预测速度慢,高维失效
随机森林0.820.78分钟级高可以,但调参费力
XGBoost0.850.81分钟级中不错,但调参复杂
LightGBM0.870.84分钟级中最优选择
LSTM0.830.79小时级低数据量大可考虑

这套数据是我在真实的城市数据上跑出来的,环境不同会有差异,但大体趋势不会变——LightGBM在这个任务上有明显的综合优势。当然,我并不是否定深度学习,如果你有至少三年的逐小时数据,LSTM能学到更丰富的时序依赖。但作为课程设计或工程落地方案,LightGBM是投入产出比最高的选项。

3.2 为什么LightGBM是最佳选择

LightGBM是微软开源的梯度提升树框架,核心优势有三个:

  • 直方图算法:将连续特征离散化成直方图,大幅减少内存占用和计算量。
  • Leaf-wise生长策略:每次选择增益最大的叶子节点进行分裂,相比Level-wise策略,在相同叶子数下精度更高。
  • 原生支持类别特征:空气质量等级、风向等类别特征可以直接输入,不需要额外做独热编码。

更重要的是,LightGBM自带特征重要性评估,我可以直接看到哪些特征在影响预测结果。实测下来,排名前五的特征是:过去6小时PM2.5均值、当前PM2.5浓度、过去24小时PM10均值、相对湿度、小时数。这个结果完全符合气象常识,也说明模型学到的规律是合理可信的。

3.3 多分类问题还是回归问题

设计系统时我反复纠结过一个问题:直接预测“等级”还是先预测“AQI数值”再映射到等级?

两种方案各有道理:

  • 直接分类:模型直接输出六个等级的概率,简单直观,评估指标直接对应业务需求。
  • 先回归后分类:先预测AQI指数数值,再根据《环境空气质量指数(AQI)技术规定》的区间映射到等级。这样做的优势是预测结果具备数值含义,可以做趋势分析。

我的最终方案是双轨并行——主模型做多分类,副模型做数值回归,两者输出合并成最终结果。主模型给出的概率分布用于展示“模型有多确定”,副模型给出的数值用于刻画污染趋势的连续变化。说实话,双轨设计让我在答辩和汇报时底气足了很多,因为可以从多个维度解释预测的合理性。

4. 核心算法实现与系统构建

4.1 数据预处理代码实践

直接上核心代码,这是我整理后的可运行版本:

import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.preprocessing import LabelEncoder import lightgbm as lgb from sklearn.metrics import accuracy_score, f1_score, classification_report # ========== 1. 数据加载与预处理 ========== df = pd.read_csv('air_quality_history.csv', parse_dates=['time'], index_col='time') # 缺失值处理:连续缺失<=3小时线性插值,>6小时删除 df = df.interpolate(method='linear', limit=3, limit_area='inside') df = df.dropna(thresh=len(df.columns) - 2) # 异常值处理:超过物理上限的置为缺失再插值 phys_limit = {'PM2.5': 500, 'PM10': 600, 'SO2': 200, 'NO2': 300, 'O3': 400, 'CO': 20} for col, limit in phys_limit.items(): df.loc[df[col] > limit, col] = np.nan df = df.interpolate(method='linear', limit=3) # ========== 2. 特征工程 ========== def build_features(data): data = data.copy() # 时序统计特征:过去6小时和24小时的均值与标准差 for col in ['PM2.5', 'PM10', 'NO2', 'O3']: data[f'{col}_mean_6h'] = data[col].rolling(6).mean() data[f'{col}_std_6h'] = data[col].rolling(6).std() data[f'{col}_mean_24h'] = data[col].rolling(24).mean() data[f'{col}_std_24h'] = data[col].rolling(24).std() # 滞后特征:前1天、前2天同时刻的PM2.5浓度 data['PM2.5_lag_1d'] = data['PM2.5'].shift(24) data['PM2.5_lag_2d'] = data['PM2.5'].shift(48) # 时间周期特征 data['hour'] = data.index.hour data['dayofweek'] = data.index.dayofweek data['is_weekend'] = (data['dayofweek'] >= 5).astype(int) # 气象交互特征 data['humidity_pm25_inter'] = data['RH'] * data['PM2.5'] data['wind_pm10_inter'] = data['WIND_SPEED'] * data['PM10'] return data df = build_features(df) df = df.dropna() # ========== 3. 构造标签:预测未来24小时的空气质量等级 ========== # 先计算AQI再分级,具体算法参考环境标准规定 def calc_aqi(pm25, pm10, so2, no2, o3, co): # 简化版:只按PM2.5和PM10主污染物计算 iaqi_table = [ (0, 35, 0, 50), (35, 75, 50, 100), (75, 115, 100, 150), (115, 150, 150, 200), (150, 250, 200, 300), (250, 500, 300, 500) ] def sub_index(concentration, table): for low, high, ilow, ihigh in table: if low <= concentration <= high: return (ihigh - ilow) / (high - low) * (concentration - low) + ilow return 500 return max(sub_index(pm25, iaqi_table), sub_index(pm10, iaqi_table)) df['AQI'] = df.apply( lambda row: calc_aqi( row['PM2.5'], row['PM10'], row['SO2'], row['NO2'], row['O3'], row['CO'] ), axis=1 ) def aqi_to_level(aqi): if aqi <= 50: return 0 # 优 elif aqi <= 100: return 1 # 良 elif aqi <= 150: return 2 # 轻度污染 elif aqi <= 200: return 3 # 中度污染 elif aqi <= 300: return 4 # 重度污染 else: return 5 # 严重污染 df['level_24h'] = df['AQI'].shift(-24).apply(aqi_to_level) df = df.dropna(subset=['level_24h'])

这里面有两个关键设计:一是用shift(-24)构造未来标签,这样训练时每个样本天然对应“未来24小时后的等级”;二是AQI计算函数虽然简化了,但保留了两个主要污染物(PM2.5和PM10)的IAQI子指数,确保分级有依据。

4.2 模型训练与超参数调优

训练代码的骨架如下:

# ========== 4. 划分训练集和验证集 ========== feature_cols = [ 'PM2.5', 'PM10', 'SO2', 'NO2', 'O3', 'CO', 'RH', 'TEMP', 'PRESSURE', 'WIND_SPEED', 'PM2.5_mean_6h', 'PM2.5_std_6h', 'PM2.5_mean_24h', 'PM2.5_std_24h', 'PM10_mean_6h', 'PM10_std_6h', 'PM10_mean_24h', 'PM10_std_24h', 'NO2_mean_6h', 'O3_mean_24h', 'PM2.5_lag_1d', 'PM2.5_lag_2d', 'hour', 'dayofweek', 'is_weekend', 'humidity_pm25_inter', 'wind_pm10_inter' ] X = df[feature_cols] y = df['level_24h'] # 按时间切分,避免数据泄漏 train_size = int(len(df) * 0.8) X_train, X_test = X.iloc[:train_size], X.iloc[train_size:] y_train, y_test = y.iloc[:train_size], y.iloc[train_size:] # ========== 5. 处理类别不均衡 ========== from sklearn.utils.class_weight import compute_class_weight classes = np.unique(y_train) weights = compute_class_weight(class_weight='balanced', classes=classes, y=y_train) class_weight_dict = dict(zip(classes, weights)) # ========== 6. 训练LightGBM多分类模型 ========== model = lgb.LGBMClassifier( n_estimators=500, learning_rate=0.05, num_leaves=63, max_depth=8, class_weight=class_weight_dict, random_state=42 ) model.fit( X_train, y_train, eval_set=[(X_test, y_test)], eval_metric='multi_logloss', callbacks=[lgb.early_stopping(stopping_rounds=50, verbose=True)] ) # ========== 7. 评估 ========== y_pred = model.predict(X_test) y_proba = model.predict_proba(X_test) print("准确率:", accuracy_score(y_test, y_pred)) print("F1分数(宏平均):", f1_score(y_test, y_pred, average='macro')) print(classification_report(y_test, y_pred))

关于参数选择,我踩过几个坑,这里展开讲讲:

关于类别不均衡:空气质量预测里最烦人的就是“严重污染”样本特别少。某城市全年严重污染可能只有几十个小时,模型容易把它们全部忽略,导致“永远预测良”的偷懒行为。直接用class_weight='balanced'能缓解,但如果严重污染样本实在太少,光靠加权重还不够——需要配合过采样手段,比如用SMOTE算法合成少数类样本。我当时在六类样本量缺口极大的情况下,把SMOTE和类别权重结合使用,F1分数从0.79直接拉到了0.84。

关于早停机制:我用early_stopping防止过拟合,验证集选用的是未来时间段的数据。这里有个细节很容易被人忽略——验证集必须晚于训练集的时间,否则会造成未来信息泄漏,模型评估结果会虚高。

4.3 模型效果验证与特征重要性分析

训练完成后,我做了两件必须做的事:

第一,看特征重要性排序。LightGBM原生支持特征重要性输出,排序结果可以帮助我们发现模型是否学到了规律性的信息。我前面提到过,PM2.5相关的时序特征排在前面,风向和CO浓度排在后位,这个排序的逻辑让我对模型有信心。

第二,分等级看混淆矩阵。整体准确率好看不够,因为“优”和“良”占了绝大多数样本,就算全部预测成“良”也有接近60%的准确率。真实水平要看“中度污染”以上的类别有多少被正确识别。我的模型在“轻度污染”和“中度污染”上表现尚可,但在“重度污染”和“严重污染”上召回率偏低——这是数据量太少导致的,属于先天限制,通过更多数据积累可以解决。

4.4 系统整体架构与流程

系统的核心逻辑很简单,是一个标准的“数据进、预测出”流水线:

定时任务 → 拉取最新监测数据 → 特征工程 → 模型推理 → 结果入库 → Web服务展示

整个流程用Flask搭建Web服务,对外提供JSON接口:

from flask import Flask, jsonify, request import joblib app = Flask(__name__) model = joblib.load('aqi_level_model.pkl') @app.route('/api/predict', methods=['POST']) def predict(): data = request.get_json() features = build_features_from_json(data) proba = model.predict_proba(features)[0] pred = int(model.predict(features)[0]) level_names = ['优', '良', '轻度污染', '中度污染', '重度污染', '严重污染'] return jsonify({ 'predicted_level': level_names[pred], 'probability': round(float(max(proba)), 4), 'level_distribution': { level_names[i]: round(float(p), 4) for i, p in enumerate(proba) } }) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)

前端展示我用的是ECharts,画了污染物浓度趋势折线图和空气质量等级概率分布条形图。一个真正可用的系统,视觉效果很重要——不是花架子,而是让使用者能快速理解预测结果的可信度。

4.5 多时间窗口预测的实现

我在系统里还实现了“未来1小时、3小时、6小时、12小时、24小时”五个预测窗口。实现方法不是简单地把模型复制五份,而是利用同一个特征工程框架,只改变标签的shift参数。

比如预测未来1小时,标签就是df['AQI'].shift(-1);预测未来12小时,就是shift(-12)。这样每个窗口单独训练一个模型,好处是每个模型可以针对性的调参,坏处是要维护五个模型文件。不过LightGBM模型文件非常小,每个大概20MB左右,五个也才100MB,完全可接受。

实测下来,窗口越短准确率越高——这也是符合预期的:空气质量变化在短时间内的确定性更强。短期内污染物浓度和气象条件的变化范围有限,规律更明显。但有意思的是,6小时窗口的准确率下降并不显著,因为空气质量变化的主导因素(气象过程和排放源)在6小时尺度上已经具备一定规律,模型能捕捉到这种日变化模式。真正挑战在24小时以上窗口——气象因素的大尺度变化让预测准确率明显下降,模型的置信度也会整体降低。这说明该系统更适合作为短中期的预警辅助工具,而不是气候尺度的模拟工具。

5. 常见问题与排查技巧实录

5.1 问题一:模型在重污染时段严重失效

这是我在项目中最头疼的问题。训练集的F1分数还能看,但一碰到连续的雾霾天气,模型预测结果几乎全错,要么报良,要么报轻度污染,从不报重度污染。

排查后发现两个原因:

一是数据不均衡导致模型“不敢”预测极端类别。轻中度污染样本占了80%以上,模型只要把那两类预测准,整体准确率就能达到80%以上。我观察概率输出发现,即使出现重度污染的紧急情况,模型给出的重度污染概率也只有0.2左右——它宁可给出一个“中庸”的答案,也不愿意承担预测极端类别的风险。

二是特征分布偏移。重污染时段通常是静稳天气加上高湿度,这种组合在训练数据里出现的次数本身就不多,模型训练时对这片特征空间的探索极不充分。

解决办法我分了三步走:

  1. 用SMOTE对少数类做过采样,增加极端类别的样本多样性
  2. 引入“气象分型”特征,比如把天气分为“静稳型”、“扩散型”和“过渡型”,让模型在相似气象条件下更容易找到相似的历史案例
  3. 设置损失函数的类别权重,让模型在训练时对错分少数类施加更大的惩罚

这三板斧下来,重度污染的召回率从15%提升到了52%,虽然还不够完美,但至少能用于预警参考。

5.2 问题二:特征泄漏导致评估虚高

这是我写过最隐晦的一个bug。最初我在构造特征时,把未来时间段的滚动均值也算了进去——比如用rolling(6).mean()计算均值时没注意min_periods参数,导致某些未来数据被引入当前样本。验证集分数高得离谱,准确率直接0.93,但一旦换成在线预测就崩得一塌糊涂。

排查技巧是:手动检查特征矩阵里每一列的时间对齐情况。如果某个特征值看起来“平滑得出奇”,很可能就是泄漏了未来信息。另外,评估时我强烈建议用滚动时间窗口验证法代替随机K折交叉验证——时间序列数据按随机方式切分会打破时间依赖,得到过于乐观的结果。我只能用第1天到第200天训练,第201天到第250天验证,逐日滑动重复,这样才跟实际部署场景一致。

5.3 问题三:在线预测比离线评估差很多

模型在测试集上F1有0.84,一部署到线上每天定时预测,结果却频繁失手。这个问题我花了两周才定位清楚。

原因在于:离线评估用的是“同一批次的历史数据”,而在线预测的输入数据是实时拉取的,经常缺字段、值异常、或者时间戳不整齐。数据质量不对,再好的模型也白搭。

解决办法是:在预测服务里加固数据校验层——对每个输入特征做范围校验、空值校验、时间漂移校验,不满足要求的直接拒绝预测并返回错误码。宁可让调用方看到“数据暂不可用”,也绝对不能让脏数据进入模型。

5.4 问题速查参考

症状可能原因处理方向
验证集分数极高,线上拉胯特征泄漏检查滚动窗口特征是否包含未来数据
永远预测“良”/“轻度污染”类别不均衡类别权重、SMOTE过采样、更换评估指标
重污染时段预测失效特征分布漂移增加气象分型特征,扩充训练集覆盖范围
短窗口准、长窗口差时序信号自然衰减长窗口单独调参,降低期望精度
新数据预测时出现NaN异常在线数据质量不过关服务层增加数据校验与兜底逻辑

6. 系统部署与扩展方向

6.1 部署环境的简易方案

这个系统不需要高性能GPU,一台普通服务器甚至树莓派就能跑。我最终的部署方案是:模型文件+Flask服务打包成Docker镜像,用docker-compose管理三个容器——MySQL存数据、Redis做缓存、Flask做预测服务。定时任务用Crontab触发Python脚本拉取数据。

部署中最容易出问题的是版本兼容性。LightGBM版本不同,模型文件的兼容格式会有变化,Docker可以很好地解决环境一致性的问题。我建议在Dockerfile里锁定依赖版本,避免“在我电脑上能跑,部署就报错”的尴尬。

6.2 后续可以怎么扩展

这个项目做到基本可用之后,我还有几个已经想好但还没动手的扩展方向:

引入深度学习模型做对比:可以加入LSTM或Transformer的时序预测,和LightGBM做集成,虽然训练成本高,但有可能在长窗口预测上再提几个点。

加入空间维度:目前的预测是针对单一站点的。如果能同时拉取城市内多个国控站点的数据,用图神经网络建模站点之间的空间相关性,理论上能提升城市尺度整体预测的准确率。

转化为回归任务的混合架构:当前主模型是分类,如果能把AQI数值预测作为辅助输出,两者融合起来置信度会更高。我实际测试过,把分类模型的概率和回归模型的预测数值同时输出给前端,用户反馈“对预测结果的信任感明显提升了”。

模型可解释性模块:用SHAP分析每一个预测结果的特征贡献度,让使用者知道“为什么预测为轻度污染”,这对环保部门的应用非常有价值。

7. 一些踩坑后的实感

做完这个项目,我最大的体会是:做AI项目最难的从来不是算法,而是“让算法在真实世界中可靠地工作”。我在这个项目里花在数据清洗和特征工程上的时间,是模型调参时间的五倍以上。这也是我跟所有做课程设计朋友反复强调的一句话——如果你发现你的模型精度上不去,先不要急着换模型、调参数,回去仔细检查你的特征工程和数据质量,大概率问题都在那里。

另一个心得是,评估指标一定要跟业务目标对齐。如果你的目标是预警重度污染,那就不应该只看整体准确率,而应该盯住重度污染的召回率。我最初只盯着整体准确率,误以为模型效果很好,实际上对真正需要关注的极端污染事件预测能力很差。换到预警视角后,我在模型设计和训练策略上做了完全不同的一系列选择,最终效果也更符合实际落地的需要。

如果你正在做一个类似的城市空气预测项目,我的建议很简单:先把数据管线做扎实,再把特征做丰富,最后才让模型上场。环境数据的特点是“噪声大、规律弱但真实”,你只有真正走进数据、理解数据的脾性,模型才会回报你可靠的预测结果。

最后再分享一个小技巧:训练之前,把目标类别的分布打印出来看一眼。如果六类样本量差距超过十倍,那你的时间线里必然藏着一个“模型作弊”的隐患,提早处理能省掉后面大量返工时间。

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

二极管双向限幅电路设计与选型:原理、计算与实战要点

1. 双向限幅电路的用武之地&#xff1a;先搞清楚你为什么要加它说实话&#xff0c;很多刚入门做硬件的人第一次接触“二极管双向限幅电路”&#xff0c;都是从教科书上那一页“两个二极管反并联”的图开始的。图上画得简单&#xff0c;但真正到了项目里&#xff0c;你会发现这个…

作者头像 李华
网站建设 2026/10/7 3:55:37

从函数到技能:构建可维护的Agent能力体系agent-skills实践指南

前阵子在重构项目里的Agent模块时&#xff0c;我盯着一个个散落的工具函数发了好一阵呆。它们什么都能干&#xff0c;但谁也不听谁的话&#xff1a;有的要JSON输入&#xff0c;有的只吃字符串&#xff1b;有的会自己记状态&#xff0c;有的每次都要把上下文从头传一遍。新来的同…

作者头像 李华
网站建设 2026/10/7 3:55:36

Navicat成高校数据库课程新宠:可视化教学如何破解三大痛点

最近在高校圈子里看到西安交通大学的推荐案例&#xff0c;数据库相关课程和实验环节开始把Navicat作为官方推荐的教学工具之一&#xff0c;这其实挺能说明问题的。以前高校数据库课普遍用命令行客户端配合一堆零散插件&#xff0c;学生上课光配置环境就要浪费半节课&#xff1b…

作者头像 李华
网站建设 2026/10/7 3:55:32

风电智能制造与绿色供应链落地实践指南

简介&#xff1a;本资源是一份聚焦风电产业数字化转型的深度技术课件&#xff0c;面向新能源装备制造业工程师、智能制造系统集成商及绿色供应链管理者&#xff0c;系统解析风电设备智能制造与绿色供应链协同落地的关键路径。课件以PPTX格式呈现&#xff0c;共1个文件&#xff…

作者头像 李华
网站建设 2026/10/7 3:55:07

小公司产品实习面试全流程拆解:用实战能力拿下offer

刚开始投产品实习那阵子&#xff0c;我把大部分精力都花在了研究大厂的简历写法上。结果简历投出去十几份&#xff0c;回复寥寥。后来阴差阳错进了一家几十人的小公司面试&#xff0c;三轮聊完直接给了offer。说实话&#xff0c;这段经历对我的冲击比想象中大得多——小公司的产…

作者头像 李华
网站建设 2026/10/7 3:54:27

Loop Engineering实战:用Claude Code打造AI编程自动循环

1. 从“会写代码”到“会设计循环”&#xff1a;Loop Engineering 到底在解决什么问题第一次听到 Loop Engineering 这个词&#xff0c;很多人会以为是某种新的编程语言或者框架。其实不是。它更像是一种工作方法论&#xff0c;核心就一句话&#xff1a;把 AI 编程工具从“一问…

作者头像 李华