我们应该在进行高斯过程回归时对数据进行标准化吗?

机器算法验证 回归 正常化 标准化 高斯过程
2022-03-12 02:54:56

我正在执行高斯过程回归 (GPR) 并优化超参数。我正在使用minFunc执行所有优化。我的问题是我们应该(或者更确切地说,我们可以)在将数据提供给目标函数之前对其进行标准化吗?如果我们进行标准化,那么超参数将根据标准化数据进行学习。但是,在测试时,假设我们一个接一个地获取样本,就不可能独立地对每个样本进行标准化,对吧?(除非我们使用训练数据中的一些标准化因素)。如果重要的话,我数据中的所有元素都在 -1 到 1 之间,但是,与其他列相比,某些列的均值和方差可能非常小。

所以我的问题是,我们应该在进行 GPR 时对数据进行标准化吗?

PS 实际上,如果我不标准化我的数据,我会观察到一些奇怪的行为。例如,minFunc突然给我step direction is illegal错误。一些在线阅读让我相信你的梯度计算有问题或者你的数据没有标准化。我确信我的梯度函数计算,我也用DerivativeCheck选项检查了它。因此,这留下了数据未标准化的可能性。

2个回答

是的,在学习高斯过程回归的同时对数据进行标准化是可取的。有几个原因:

  1. 在常见的高斯过程回归模型中,我们假设输出y均值为零,所以我们应该标准化y符合我们的假设。
  2. 对于许多协方差函数,我们在协方差函数中有尺度参数。因此,我们应该标准化输入以更好地估计协方差函数的参数。
  3. 高斯过程回归容易出现数值问题,因为我们必须逆病态协方差矩阵。为了使这个问题不那么严重,您应该标准化您的数据。

一些软件包为您完成这项工作,例如 sklearn 中的 GPR 有一个选项normalize用于规范化输入,而不是输出(http://scikit-learn.org/stable/modules/generated/sklearn.gaussian_process.GaussianProcess.html

我同意 Alexey Zaytsev 的回答(以及对该答案的讨论),即出于各种原因,在输出上也可以进行标准化。但是,我只想添加一个示例,说明为什么标准化输出很重要。

对输出进行标准化/标准化很重要的一个例子是对于小而嘈杂的输出值。下图通过一个非常简单的示例对其进行了说明。MATLAB 代码如下图。

蓝点代表来自 sin() 函数的噪声样本。橙色/红色圆圈代表预测的高斯过程值。

  1. 在顶部的子图中,幅度是统一的(有噪声)。
  2. 在第二个子图中,输出值已按 1e-5 缩放,我们可以看到高斯过程模型(使用默认设置)预测了一个常数模型。默认设置优化了噪声参数并且具有相当高的下限。
  3. 在第三个子图中,噪声参数设置为零且未优化。在这种情况下,模型过拟合。
  4. 第四个子图显示了标准化输出和适合该数据的模型。
  5. 在最后一个子图中,输出从标准化操作缩减(未缩减到原始值),并且预测值也被缩减。请注意,预测值是使用训练数据标准化的平均值和标准差进行缩放的。

简单的例子

function importance_normgp()
% small outputs

% data
x = 0:0.01:1; x = x(:);
xp = linspace(0.1, 0.9, length(x)); xp = xp(:);

% noise free model
y = sin(2*pi*x) + 5e-1*randn(length(x), 1);

% train and predict gp model
mdl = fitrgp(x, y);
yp = predict(mdl, xp);

figure
subplot(5, 1, 1)
plot(x, y, '.')
hold on
plot(xp, yp, 'o')
title('original problem')

%% make outputs small (below noise lower bound)
ym = y/1e5;

% train and predict gp model
mdlm = fitrgp(x, ym);
ypm = predict(mdlm, xp(:));

subplot(5, 1, 2)
plot(x, ym, '.')
hold on
plot(xp, ypm, 'o')
title('small outputs')

%% outputs small and set sigma = 0

% train and predict gp model
mdlm1 = fitrgp(x, ym, 'Sigma', 1e-12, 'ConstantSigma', true, 'SigmaLowerBound', eps);
ypm1 = predict(mdlm1, xp(:));

subplot(5, 1, 3)
plot(x, ym, '.')
hold on
plot(xp, ypm1, 'o')
title('small outputs and sigma = 0')

%% normalise/standardise
nu = mean(ym);
sigma = std(ym);
yms = (ym - nu)/sigma;

% train and predict gp model
mdlms = fitrgp(x, yms);
ypms = predict(mdlms, xp(:));

subplot(5, 1, 4)
plot(x, yms, '.')
hold on
plot(xp, ypms, 'o')
title('standardised outputs')

% rescale
ypms2 = ypms*sigma + nu;

subplot(5, 1, 5)
plot(x, ym, '.')
hold on
plot(xp, ypms2, 'o')
title('scaled predictions')

legend('true model', 'prediction', 'Location', 'best')
end