简介这份资源是面向气候科学与机器学习交叉领域研究者、数据科学学习者的端到端管道项目聚焦干旱预测与理解这一具体问题提供从数据准备到方法评估的完整流程。项目以 Jupyter Notebook 为主要载体结合 Copernicus 气候数据与 2019 年相关实践将创建统一训练测试数据格式、相互比较与评估不同机器学习方法等任务拆分为 src 目录下的多个类便于按模块复用与扩展。压缩包约 49.31MB内含 Notebook、Python 源码及环境配置文件可通过 conda 环境快速搭建运行环境适合具备 Python 基础的使用者上手。已有 142 人学习读者可借此理解气候数据预处理、模型对比实验设计与评估思路并基于现有管道替换数据或方法开展自己的干旱预测实验。1. 干旱预测的玄学困局为什么传统指标总在关键时刻翻车干旱这件事最反直觉的地方在于——它不是一个有没有下雨的问题。某地连续四十天无降水放在湿润区是灾难前兆放在干旱区却是常态。传统干旱监测依赖 SPI、SPEI 这类标准化降水指数本质是把降水量做统计标准化再套一个阈值分级。这套方法用了半个多世纪工程上足够稳但它有一个绕不过去的硬伤它只看水进来多少不看水怎么被消耗、地表能撑多久。这就导致一个经典翻车场景气象干旱指标还在正常区间农业干旱已经悄悄发生了。因为高温、强蒸散、土壤质地、植被覆盖这些因素SPI 根本装不进去。机器学习介入干旱预测的价值恰恰在于它能把这些异质变量塞进同一个模型里学出降水—蒸散—土壤—植被之间的非线性耦合关系。ml_drought 这个项目就是干这件事的用 Copernicus 体系下的遥感与再分析数据配合 Jupyter Notebook 做端到端的干旱建模。搞懂它为什么能 work比会跑通一个 notebook 重要得多。2. 从气象干旱到综合干旱机器学习到底在拟合什么2.1 干旱不是单一变量而是一个多尺度滞后系统要理解 ml_drought 的设计先得接受一个事实干旱是有记忆的。今天土壤缺水可能是过去三个月降水亏缺累积的结果也可能是上周一场异常高温把蒸散拉爆了。这种时间上的滞后与累积正是传统阈值法最无力的地方——它把每个时间窗口独立看待而真实系统里前一个月的状态会显著影响这个月的响应。机器学习模型在这里的角色不是预测下雨而是学习一个状态转移函数给定过去若干时间步的降水、温度、蒸散、土壤湿度、植被指数输出未来某个时间点的干旱等级或连续干旱指数。常见的实现思路是把问题构造成监督学习里的序列回归或序列分类用滑动窗口把时间序列切成样本。窗口长度这个参数非常关键它直接决定了模型能记住多久的历史。窗口太短模型学不到累积效应窗口太长样本数骤减且噪声被放大。我一般会这么理解窗口长度应该覆盖当地干旱的形成周期比如半干旱区取 3 到 6 个月湿润区可以短一些。这里有个容易被忽略的设计动机为什么不用纯气象指标做特征非要引入遥感因为遥感提供的是地表真实响应而不是大气输入。降水是输入土壤湿度和植被指数是输出侧的状态。把输入和状态一起喂给模型等于让模型同时看到因和果它才能学到中间的传导机制。这也是 Copernicus 数据体系在这个项目里不可替代的原因——它同时提供气象再分析产品和地表遥感产品时间与空间分辨率能对齐。2.2 特征工程把物理先验塞进模型输入纯数据驱动的模型在样本有限时很容易学偏所以 ml_drought 这类项目通常会在特征层面注入物理先验。最典型的是构造水分亏缺类特征比如降水减去潜在蒸散的累积值这本质上就是 SPEI 的计算逻辑但把它作为一个特征而不是最终指标。这样做的好处是模型不必从零学水少了会旱这个常识而是站在一个已经有物理意义的基线上继续学非线性修正。另一个常见做法是对不同滞后阶分别构造特征。比如降水取 lag1、lag3、lag6 三个累积窗口蒸散取 lag1 和 lag3土壤湿度取 lag1。这样模型在结构上就具备了捕捉多尺度响应的能力。代码层面通常是一个特征拼接函数import pandas as pd import numpy as np def build_lagged_features(df, var_lags): df: 含时间索引的原始变量表列名如 precip, et, soil_moisture var_lags: dict形如 {precip: [1, 3, 6], et: [1, 3], soil_moisture: [1]} 返回拼接了滞后累积特征的新表 out df.copy() for var, lags in var_lags.items(): for lag in lags: # 滚动累积模拟干旱的累积效应min_periods 保证不引入虚假早期值 out[f{var}_cum{lag}] df[var].rolling(windowlag, min_periodslag).sum() return out.dropna() # 丢掉因滚动产生的缺失头部这段逻辑的关键在rolling(...).sum()而不是shift()。shift只取单点滞后rolling sum才表达累积亏缺这个物理含义。min_periodslag是为了避免窗口没填满时用部分数据算出偏小的累积值那会污染训练集。参数上var_lags的取值不是拍脑袋应该参考当地干旱的形成时间尺度并且要在验证集上做敏感性检查——窗口选错模型在极端干旱年份的表现会明显塌陷。2.3 标签怎么定义决定了模型在学什么这是整个建模里最容易被低估的一环。干旱预测的标签通常有两种来源一是用现成的干旱指数如 SPEI分级作为分类标签二是用遥感干旱指数如植被条件指数 VCI作为回归目标。前者偏气象后者偏农业。ml_drought 这类项目如果目标是了解干旱往往会把两者都做形成对照。分类标签的阈值切分有个坑干旱等级本身是高度不平衡的极端干旱样本极少。直接训练分类器模型会倾向于全预测正常准确率看着很高但毫无用处。常见的处理是重采样、类别加权或者干脆把问题转成回归——预测连续干旱指数再在评估阶段按阈值转等级。回归的好处是保留了序信息模型不会把中度和极端当成两个无关类别。代价是回归对极端值的拟合更难需要在损失函数上做文章比如对高干旱区间加权。3. Copernicus 数据管线遥感与再分析怎么对齐到同一张表3.1 时空重采样为什么对齐比建模还费劲多源数据建模八成的工程量花在对齐上。Copernicus 体系里气象再分析产品通常是规则网格、逐小时或逐日遥感产品可能是不同的空间分辨率、不同的过境时间还有云污染导致的缺测。要把它们拼成一张时间 × 站点/网格的表必须做时空重采样。空间上常见做法是把所有变量重采样到同一个较粗的网格或者重采样到站点位置做点提取。时间上遥感产品如果是 8 天合成或 16 天合成需要决定是取合成期均值还是做时间插值到日尺度。这里没有唯一正确答案但有一个原则重采样的方向要跟物理过程匹配。降水适合累积温度适合平均植被指数适合取合成期最大值减少云影响。用错聚合方式等于在特征里注入系统性偏差。# 示意按变量类型选择聚合方式避免一刀切均值 agg_rules { precip: sum, # 降水在时间窗口内累积 temp: mean, # 温度取平均 et: sum, # 蒸散同样累积 ndvi: max, # 植被指数取最大值抑制云污染 } resampled raw.resample(1D).agg(agg_rules)resample(1D)把不同原始频率统一到日尺度agg字典则保证每个变量用它该用的聚合函数。这一步如果偷懒全用mean降水会被严重低估模型学到的干旱就失真了。3.2 缺测与云污染数据质量决定模型上限遥感数据的缺测不是随机缺失而是系统性缺失——云多的地方、雨季缺测更集中。如果直接dropna()等于把湿润季节的样本大量删掉训练集分布会偏向干旱季模型在湿润条件下的泛化能力被悄悄削弱。这是血泪经验很多人模型指标好看一换年份就崩根子就在缺测处理。常见的补救思路有三种。一是时间插值用前后有效观测线性填补适合短缺口。二是气候态填补用同期的多年均值替代适合长缺口但会平滑掉异常信号。三是把缺测本身作为一个指示特征missing indicator让模型知道这个时间点数据不可靠。第三种在样本量足够时最稳因为它不伪造数据而是把不确定性显式交给模型。ml_drought 这类项目在 notebook 里通常会把这几种策略做成可切换的选项方便对比。提示缺测处理策略要在训练集和测试集上用同一套逻辑且填补统计量只能从训练集计算否则会造成信息泄漏验证指标虚高。3.3 数据泄漏时间序列建模里最隐蔽的坑时间序列的交叉验证不能随机打乱。随机切分会让模型在训练时看到未来测试指标虚高得离谱。正确做法是按时间切块比如前 70% 时间做训练后 30% 做测试或者用滚动前向验证walk-forward。滚动前向验证更贴近真实部署场景每次用截至某时刻的历史训练预测下一段然后窗口前移。这个原则听起来简单但实操里经常翻车在特征工程阶段——比如标准化用了全量数据的均值和方差或者滞后特征在切分边界处跨到了测试集。这些都属于隐性泄漏。稳妥的做法是把特征构造和标准化都封装进一个 pipeline在每次切分内部 fit而不是在全局 fit 一次。4. 模型选型与训练为什么梯度提升树常是这类任务的默认答案4.1 树模型 vs 神经网络样本量决定路线干旱预测的样本量通常不大——几十年的月度数据站点或网格数量有限有效样本可能就几千条。在这个量级上深度神经网络容易过拟合而梯度提升树如 XGBoost、LightGBM对中小样本、异质特征、非线性交互的适应性更好且对特征尺度不敏感省掉了大量预处理。这不是说神经网络不行而是说在样本受限时树模型的性价比更高。树模型的另一个优势是可解释性。特征重要性、部分依赖图能告诉你模型到底在看什么这对干旱这种需要物理解释的领域很重要。如果模型说未来干旱加剧但特征重要性显示它主要靠某个无关变量那这个预测就不可信。ml_drought 的 notebook 里通常会包含特征重要性可视化这不是装饰而是模型可信度的一部分。4.2 超参数与验证别让调参调出过拟合树模型的超参数里对干旱预测影响最大的是树的深度/叶子数、学习率、以及正则化项。深度太深模型记住训练年份的噪声太浅学不到多变量交互。常见做法是先固定一个较小学习率如 0.05用早停early stopping在验证集上确定树的数量再网格搜索深度和正则参数。验证集必须来自时间上的后段且不能和测试集重叠。如果数据量实在少可以用滚动前向验证的每一折做超参数评估取平均表现最好的配置。这里有个容易忽略的点早停的监控指标要和最终评估指标一致。如果最终看的是极端干旱的召回率早停却盯着整体 MSE那模型会偏向拟合平均状态极端事件照样漏。# 示意时间序列友好的早停配置 model lgb.LGBMRegressor( learning_rate0.05, num_leaves31, min_child_samples20, # 防止叶子过小抑制过拟合 subsample0.8, colsample_bytree0.8, n_estimators2000, ) model.fit( X_train, y_train, eval_set[(X_val, y_val)], eval_metricl2, callbacks[lgb.early_stopping(50), lgb.log_evaluation(100)], )min_child_samples在小样本场景下尤其重要它限制了每个叶子至少覆盖多少样本避免模型为个别极端年份单独开叶子。subsample和colsample_bytree引入随机性提升泛化。早停的50轮耐心值不宜太小否则验证曲线的小波动会导致过早停止。4.3 评估指标准确率会骗人要看极端事件干旱预测的评估不能只看 RMSE 或准确率。极端干旱样本少模型即使完全漏掉它们整体指标依然好看。必须单独看极端区间的表现比如高干旱等级上的召回率、F1或者回归任务里对高值段的 MAE。另一个有用的做法是画预测-观测散点图看模型在高值端是否系统性低估——树模型因为对极端值做平均天然倾向于压缩极值这个偏差必须被看见。如果目标是业务预警还要考虑提前量和误报代价的权衡。提前太久不确定性大、误报多提前太短预警价值低。这个权衡没有通用答案得结合具体应用场景定但评估时必须把不同提前量下的指标都列出来而不是只报一个最好看的数。5. 避坑清单干旱建模里那些让人后悔药的细节5.1 现象验证指标很好换一年就崩原因通常是数据泄漏或分布偏移。检查标准化是否在全局 fit、滞后特征是否跨了切分边界、缺测填补是否用了未来信息。解决把所有预处理封装进 pipeline按时间切分内部 fit对每一年的表现单独评估看是否存在系统性偏移。5.2 现象模型几乎不预测极端干旱原因是类别不平衡加树模型的极值压缩。解决回归任务对高值段加权损失分类任务用类别权重或重采样评估时单独看极端区间指标别被整体准确率麻痹。5.3 现象降水特征重要性异常低原因是聚合方式用错比如降水用了均值而非累积导致特征信息量被抹平。解决按变量物理含义选聚合函数降水、蒸散用累积温度用均值植被指数用最大值改完重跑特征重要性对照。5.4 现象不同年份的干旱指数尺度不一致原因是标签来源或计算窗口不统一比如有的年份用 3 个月 SPEI有的用 6 个月。解决标签定义必须全时段一致窗口长度在建模前固定并在文档里写清楚避免后续对比时口径混乱。5.5 现象notebook 能跑换数据就报错原因是硬编码了列名、时间格式或网格尺寸。解决把数据读取和列映射抽成配置输入校验前置缺列或时间不连续时尽早报错而不是等到模型训练阶段才崩。6. 设计取舍为什么能解释比高一分更值得追求干旱预测这类问题模型指标和实际价值之间隔着一层东西可信度。一个 RMSE 低 5% 但特征重要性讲不通的模型在业务侧很难被采纳反过来一个指标稍逊但每一步都能对应到物理过程的模型更容易被信任和迭代。ml_drought 用 Jupyter Notebook 组织全流程本身就是一种取舍——它牺牲了工程化的封装度换来了每一步的可检查性。你可以逐单元格看数据长什么样、特征怎么构造、模型学了什么这对理解和调试的价值远大于一个打包好的黑匣子。另一个取舍在数据源。Copernicus 体系的数据质量高、变量全但下载和预处理成本不低。如果换成更轻量的数据源建模速度会快但特征丰富度下降模型能学到的耦合关系变少。这个权衡没有标准答案取决于你是要做快速原型还是做可复用的分析基线。我的判断是如果目标是了解干旱机制数据丰富度优先如果目标是快速出预警可以先窄后宽先跑通最小闭环再逐步加变量。验证一个干旱模型是否真的 work我习惯做三件事一是按年份滚动评估看指标稳定性而不是平均值二是看极端事件上的表现漏报比误报更值得警惕三是做特征消融去掉某类变量看性能掉多少掉得合理才说明模型真的在用物理信号。这三步走完模型能不能信心里基本有数。从那以后我每次碰时间序列建模都强制先画一张时间轴上的训练/验证/测试切分图确认没有任何未来信息漏进去再谈调参。这个习惯救过我很多次。希望帮到你。本文还有配套的精品资源点击获取