4. 数据预处理与特征工程

代理模型的学习对象是“输入参数 → 输出响应”的映射关系。如果输入数据的量纲、尺度、分布差异过大,神经网络会把大量容量浪费在拟合尺度差异上,而不是学习物理规律。本节围绕六件事展开:归一化、标准化、异常值处理、特征选择、物理量无量纲化与输入编码。它们不是孤立的清洗步骤,而是决定代理模型能否收敛、能否外推的关键前置工作。

一、归一化与标准化:先分清两者的适用边界

归一化(Min-Max)把数据线性映射到 [0,1]:

x' = (x - x_min) / (x_max - x_min)

它保留原始分布形状,适合边界明确、且训练集已覆盖完整取值范围的参数,例如几何尺寸、体积分数、角度。缺点是极值敏感:一个离群点会把其余样本压缩到很窄的区间。

标准化(Z-Score)把数据变换为均值 0、标准差 1:

x' = (x - μ) / σ

它适合近似正态、或存在合理离群点的参数,如材料强度、温度、载荷。标准化不依赖极值,鲁棒性更好,是代理模型中最常用的默认方案。

关键原则:统计量(x_min、x_max、μ、σ)只能从训练集计算,再应用到验证集和测试集。若用全量数据计算统计量,会造成信息泄漏,使验证误差虚低,上线后误差骤增。

二、异常值处理:先判断“错值”还是“真值”

异常值分两类:一是采集/录入错误(单位写错、传感器跳变、仿真不收敛),应修正或剔除;二是物理上真实存在的极端工况,属于模型需要覆盖的边界,不能随意删除。常用识别手段包括:

  • 3σ 准则:适用于近似正态数据,超出 μ±3σ 视为可疑;
  • IQR 准则:Q1−1.5×IQR 与 Q3+1.5×IQR 之外为可疑,对偏态分布更稳健;
  • 物理约束检查:如体积分数必须落在 (0,1)、弹性模量为正、能量守恒残差不得超阈值。

处理方式按优先级为:核对原始记录 → 修正错误 → 对真实极端值保留并单独标记 → 必要时用中位数或模型插补。切忌直接删除所有离群点,否则代理模型在边界区域会严重失真。

三、物理量无量纲化:让模型学到“规律”而非“单位”

无量纲化与统计标准化不同,它利用物理量之间的量纲关系构造无量纲数,使模型在不同尺度、不同单位制下具有一致性。例如:

  • 流体与传热:雷诺数 Re = ρvL/μ、努塞尔数 Nu = hL/k、普朗特数 Pr;
  • 结构力学:长细比 L/r、无量纲载荷 P/(EA)、无量纲挠度 δ/L;
  • 优化设计:以基准值归一,如 x/x_ref、f/f_0。

无量纲化的价值在于:一是减少输入维度(多个有量纲量可合并为一个无量纲数);二是提升外推能力,模型在训练区间外仍可能保持合理趋势;三是便于跨数据集迁移。工程实践中,建议优先使用领域公认的无量纲数,其次才用统计标准化。

四、特征选择:去掉冗余,保留物理信息

输入特征并非越多越好。冗余特征会增加训练成本、加剧过拟合、降低可解释性。常用方法有三类:

  • 过滤法:计算皮尔逊相关系数、互信息,剔除与输出弱相关或彼此高度共线的特征(如 |r|>0.95 的特征对保留其一);
  • 包裹法:以验证误差为目标做前向选择或递归消除,精度高但计算量大;
  • 嵌入法:利用 L1 正则、树模型特征重要性,在训练中自动压缩不重要特征。

对物理代理模型,还应加入“物理可解释性”判据:若某特征与输出之间缺乏已知物理机制支撑,即使统计相关性强,也应谨慎保留,避免模型学到数据采集偏差而非物理规律。

五、输入编码:让类别与结构信息可被网络读取

当输入包含非数值信息时,需要编码:

  • 类别型(材料牌号、工况类型):优先用 One-Hot;若类别多且存在序关系,可用序数编码或嵌入层;
  • 几何/拓扑:可用参数化描述(控制点坐标、截面参数)或图像/体素表示;
  • 周期型(角度、相位):用 sin/cos 双通道编码,避免 0° 与 360° 被人为拉远;
  • 缺失值:显式增加缺失指示位,再对数值做插补,让模型知道该位是否可信。

六、完整预处理流水线示例

下面给出一段可直接参考的 Python 预处理流程,示例数据为合理假设,用于说明顺序与接口:

import numpy as np
from sklearn.preprocessing import StandardScaler, MinMaxScaler

# X_raw: (N, D) 原始输入, y_raw: (N, 1) 输出
# 1) 物理约束过滤
mask = (X_raw[:, 0] > 0) & (X_raw[:, 0] < 1)   # 体积分数在 (0,1)
X, y = X_raw[mask], y_raw[mask]

# 2) 异常值:IQR 标记(仅标记,不直接删)
q1, q3 = np.percentile(X, [25, 75], axis=0)
iqr = q3 - q1
outlier = (X < q1 - 1.5*iqr) | (X > q3 + 1.5*iqr)

# 3) 划分训练/验证/测试(先划分,再拟合统计量)
idx = np.random.permutation(len(X))
n_tr, n_va = int(0.7*len(X)), int(0.15*len(X))
tr, va, te = idx[:n_tr], idx[n_tr:n_tr+n_va], idx[n_tr+n_va:]

# 4) 标准化:仅用训练集拟合
scaler = StandardScaler().fit(X[tr])
X_tr, X_va, X_te = scaler.transform(X[tr]), scaler.transform(X[va]), scaler.transform(X[te])

# 5) 输出同样标准化,便于损失函数平衡
ys = StandardScaler().fit(y[tr])
y_tr, y_va, y_te = ys.transform(y[tr]), ys.transform(y[va]), ys.transform(y[te])

判断预处理是否合格,可观察三点:训练集与验证集标准化后的均值/方差是否接近;损失曲线是否平稳下降而非剧烈震荡;模型在边界工况上的预测是否仍符合物理趋势。若验证误差远小于测试误差,通常意味着统计量泄漏或异常值处理不当。

代理模型输入预处理流水线 统计量仅由训练集拟合,再应用到验证/测试集 原始输入 X_raw 几何 / 材料 / 工况 含量纲、量级差异大 物理约束过滤 体积分数∈(0,1) 模量>0、能量残差 异常值识别 3σ / IQR 标记 错值修正,真值保留 数据集划分 训练 70% 验证 15% / 测试 15% 拟合统计量 μ, σ 或 x_min, x_max 仅用训练集! 归一化 Min-Max x'=(x−x_min)/(x_max−x_min) 适用:边界明确的几何量 标准化 Z-Score x'=(x−μ)/σ 适用:近似正态、含合理离群 无量纲化 Re、Nu、L/r、δ/L 合并量纲、提升外推 输入编码 One-Hot / 序数 / 嵌入 周期量 sin/cos 双通道 特征选择 过滤法:|r|>0.95 共线剔除 包裹法:前向选择 / 递归消除 嵌入法:L1 正则、树重要性 标准化后的训练张量 X_tr, X_va, X_te y_tr, y_va, y_te 均值≈0,方差≈1 质量检查 训练/验证分布是否一致 损失曲线是否平稳下降 边界工况是否符合物理趋势 顺序要点:物理过滤 → 异常值标记 → 划分 → 训练集拟合统计量 → 变换 → 特征选择 → 编码

把上述流程固化为可复用的预处理模块,是代理模型工程化的第一步。建议将 scaler、特征列表、编码映射与模型权重一起保存为推理包,确保训练与部署使用完全一致的变换参数,避免“训练时标准化、推理时忘记标准化”这类高频错误。