4. 代理模型入门
在实验优化中,真正昂贵的往往不是算法,而是每一次实验或仿真本身。代理模型(Surrogate Model)的作用,是用少量已完成的实验点,拟合出输入参数与响应之间的近似映射,从而在后续搜索中替代真实实验进行快速预测。本节聚焦三类最常用的响应面代理模型:高斯过程回归(GPR)、随机森林(RF)与神经网络(NN),重点讲清它们各自适合什么条件,以及如何用最小代码快速跑通。
一、三类代理模型的本质差异
理解适用条件,先要理解它们对数据的“假设”不同。
高斯过程回归把响应看作一个随机过程,任意有限个点的响应服从联合高斯分布,由均值函数和核函数(协方差函数)决定。核函数刻画“相近输入应有相近输出”的平滑程度。它的最大特点是自带不确定性估计:对每个预测点不仅给出均值,还给出方差。这使它天然适合贝叶斯优化中的采集函数(如EI、UCB)。代价是计算复杂度随样本数n约为O(n³),样本超过一两千后训练明显变慢。
随机森林由多棵决策树集成,每棵树在自助采样和随机特征子集上训练,最终取平均。它不假设平滑性,能自然处理非线性、特征交互和类别型变量,对异常值不敏感,几乎不需要调参就能得到稳健结果。缺点是预测在训练点之外趋于常数(外推能力弱),且不确定性估计不如GPR规范。
神经网络通过多层非线性变换拟合复杂函数,参数量大、表达能力强,适合高维、大样本、响应面高度复杂甚至不连续的场景。但它需要更多数据才能稳定,训练对学习率、网络结构、归一化敏感,且默认不提供可靠的不确定性。
二、快速实现:以“反应产率优化”为例
假设我们优化一个化学反应的产率,两个输入变量:温度T(60~100℃)和催化剂用量C(0.5~2.0 mol%),响应为产率Y(%)。已有20组实验数据。下面用Python快速实现三种代理模型,并比较其交叉验证表现。
import numpy as np
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, WhiteKernel
from sklearn.ensemble import RandomForestRegressor
from sklearn.neural_network import MLPRegressor
from sklearn.model_selection import cross_val_score, KFold
from sklearn.preprocessing import StandardScaler
# 示例数据(20组,仅作教学演示)
X = np.array([[70,1.0],[80,1.5],[90,0.8],[75,1.2],[85,1.8],
[65,0.6],[95,1.4],[72,1.1],[88,1.6],[78,0.9],
[82,1.3],[68,0.7],[92,1.7],[76,1.0],[86,1.5],
[74,1.2],[84,0.8],[90,1.9],[66,0.5],[80,1.4]])
y = np.array([62,78,71,69,82,55,85,64,80,67,
75,58,83,66,79,68,73,86,52,77])
# 标准化(NN和GPR对尺度敏感)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
kf = KFold(n_splits=5, shuffle=True, random_state=42)
# 1) GPR:RBF核 + 白噪声核
kernel = RBF(length_scale=1.0) + WhiteKernel(noise_level=1.0)
gpr = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=5, random_state=42)
gpr_scores = cross_val_score(gpr, X_scaled, y, cv=kf, scoring='r2')
# 2) 随机森林
rf = RandomForestRegressor(n_estimators=300, random_state=42)
rf_scores = cross_val_score(rf, X, y, cv=kf, scoring='r2')
# 3) 神经网络
nn = MLPRegressor(hidden_layer_sizes=(32,16), activation='relu',
max_iter=2000, random_state=42)
nn_scores = cross_val_score(nn, X_scaled, y, cv=kf, scoring='r2')
print("GPR R2:", gpr_scores.mean().round(3))
print("RF R2:", rf_scores.mean().round(3))
print("NN R2:", nn_scores.mean().round(3))
在类似的小样本(n=20)、平滑响应面场景中,典型结果往往是GPR的交叉验证R²最高(示例中约0.85~0.92),RF次之(约0.78~0.88),NN因数据太少容易欠拟合或过拟合,R²波动较大(约0.60~0.85)。这些数值仅为教学示例,实际结果取决于数据本身。
三、如何根据条件选择模型
选择不是凭偏好,而是看三个维度:样本量、响应面平滑性、是否需要不确定性。
- 样本少(n<200)且响应平滑:优先GPR。核函数选RBF或Matern,配合WhiteKernel吸收噪声。若用于贝叶斯优化,GPR的方差可直接驱动EI采集。
- 样本中等、含类别变量或噪声大:优先RF。它不需要标准化,对异常点稳健,还能输出特征重要性,帮助判断哪些参数真正影响响应。
- 样本充足(n>1000)、高维或强非线性:考虑NN。务必先标准化输入输出,用早停或交叉验证控制过拟合。若需要不确定性,可用MC Dropout或集成多个网络。
- 不确定时:先跑RF作为基线,再用GPR对比。若两者R²接近且样本少,选GPR以获取方差;若RF明显更稳,则选RF。
四、快速验证与结果判读
训练完成后,不要只看一个R²数字。建议做两件事:一是画出预测值 vs 真实值的散点图,理想情况应沿对角线分布;二是检查残差是否随预测值变化,若呈喇叭形说明存在异方差,可能需要变换响应或改用RF。
对于GPR,还可以输出预测方差,观察哪些区域方差大——这些区域正是实验设计下一步应该补充采样的位置。这正是代理模型驱动实验优化的核心逻辑:用模型的不确定性指导下一轮实验,而不是均匀撒点。
小结:GPR适合小样本、平滑、需要不确定性的场景;RF适合中等样本、含噪、需要稳健和可解释性的场景;NN适合大样本、高维、强非线性的场景。快速实现时,统一用交叉验证比较,再结合预测图和残差图判断是否可用。下一轮实验前,先让代理模型告诉你“哪里最不确定”。