高斯过程回归(Gaussian Process Regression, GPR):原理与MATLAB实现
一、核心原理
1.1 什么是高斯过程回归?
高斯过程是一种非参数的贝叶斯机器学习方法,通过定义在函数空间上的概率分布来建模数据,相比传统回归方法有以下特性:
| 对比维度 | 线性回归 | 支持向量回归(SVR) | 高斯过程回归(GPR) |
|---|---|---|---|
| 参数规模 | 固定(等于特征维度) | 固定(支持向量数量) | 无固定参数,由核函数决定 |
| 不确定性量化 | 仅能给出置信区间 | 不支持 | 天然输出预测方差 |
| 小样本表现 | 泛化能力弱 | 较好 | 极强,10个样本即可达到高精度 |
| 非线性拟合 | 需手动特征工程 | 依赖核函数选择 | 自动学习非线性关系 |
1.2 数学模型
高斯过程由均值函数m(x)m(\mathbf{x})m(x)和协方差函数k(x,x′)k(\mathbf{x},\mathbf{x}')k(x,x′)完全定义:
f(x)∼GP(m(x),k(x,x′))f(\mathbf{x}) \sim \mathcal{GP}(m(\mathbf{x}), k(\mathbf{x},\mathbf{x}'))f(x)∼GP(m(x),k(x,x′))
对于观测数据D={(xi,yi)}i=1N\mathcal{D}=\{(\mathbf{x}i,y_i)\}{i=1}^ND={(xi,yi)}i=1N,预测新样本x∗\mathbf{x}*x∗的后验分布为高斯分布:
y^∗∼N(μ∗,σ∗2)\hat{y}* \sim \mathcal{N}(\mu_*, \sigma_*^2)y^∗∼N(μ∗,σ∗2)
其中:
μ∗=m(x∗)+k∗T(K+σn2I)−1(y−m(X))\mu_* = m(\mathbf{x}*) + \mathbf{k}*^T (\mathbf{K} + \sigma_n^2\mathbf{I})^{-1} (\mathbf{y} - m(\mathbf{X}))μ∗=m(x∗)+k∗T(K+σn2I)−1(y−m(X))
σ∗2=k(x∗,x∗)+σn2−k∗T(K+σn2I)−1k∗\sigma_*^2 = k(\mathbf{x}*,\mathbf{x}*) + \sigma_n^2 - \mathbf{k}*^T (\mathbf{K} + \sigma_n^2\mathbf{I})^{-1} \mathbf{k}*σ∗2=k(x∗,x∗)+σn2−k∗T(K+σn2I)−1k∗
- K\mathbf{K}K:训练样本间的协方差矩阵
- k∗\mathbf{k}_*k∗:新样本与训练样本的协方差向量
- σn2\sigma_n^2σn2:观测噪声方差
二、MATLAB实现
2.1 基础GPR实现
matlab
%% 基础高斯过程回归实现
clc; clear; close all;
% ========== 1. 生成测试数据 ==========
rng(42); % 固定随机种子保证可复现
X_train = linspace(0, 10, 20)'; % 20个训练样本
y_train = sin(X_train) + 0.3 * randn(size(X_train)); % 带噪声的正弦函数
X_test = linspace(0, 10, 100)'; % 100个测试样本
y_test = sin(X_test) + 0.3 * randn(size(X_test));
% ========== 2. 定义核函数 ==========
function K = kernel_func(X1, X2, l, sigma_f)
% 径向基函数(RBF)核:k(x,x') = sigma_f^2 * exp(-||x-x'||^2/(2*l^2))
sq_dist = pdist2(X1, X2, 'sqeuclidean');
K = sigma_f^2 * exp(-sq_dist / (2 * l^2));
end
% ========== 3. 训练GPR模型 ==========
% 核函数超参数:l=1.5(长度尺度), sigma_f=1.0(信号方差), sigma_n=0.3(噪声方差)
l = 1.5; sigma_f = 1.0; sigma_n = 0.3;
% 计算训练样本协方差矩阵
K_train = kernel_func(X_train, X_train, l, sigma_f);
K_train_noisy = K_train + sigma_n^2 * eye(length(X_train));
% 计算新样本与训练样本协方差
K_star = kernel_func(X_test, X_train, l, sigma_f);
K_star_self = kernel_func(X_test, X_test, l, sigma_f);
% Cholesky分解加速计算
L = chol(K_train_noisy, 'lower');
alpha = L' \ (L \ (y_train - mean(y_train)));
% 预测均值和方差
mu_pred = mean(y_train) + K_star * alpha;
sigma_pred = sqrt(diag(K_star_self + sigma_n^2 - K_star * (K_train_noisy \ K_star'));
% ========== 4. 评估性能 ==========
mse = mean((y_test - mu_pred).^2);
rmse = sqrt(mse);
mae = mean(abs(y_test - mu_pred));
r2 = 1 - sum((y_test - mu_pred).^2) / sum((y_test - mean(y_test)).^2);
fprintf('=== 基础GPR性能评估 ===\n');
fprintf('MSE: %.6f\nRMSE: %.6f\nMAE: %.6f\nR²: %.4f\n', mse, rmse, mae, r2);
% ========== 5. 结果可视化 ==========
figure('Position', [100, 100, 1000, 400]);
subplot(1,2,1);
plot(X_train, y_train, 'ro', 'MarkerSize', 8, 'MarkerFaceColor', 'r'); hold on;
plot(X_test, y_test, 'b.', 'MarkerSize', 10);
plot(X_test, mu_pred, 'k-', 'LineWidth', 2);
fill([X_test; flipud(X_test)], [mu_pred + 1.96*sigma_pred; flipud(mu_pred - 1.96*sigma_pred)], ...
'k', 'FaceAlpha', 0.2, 'EdgeColor', 'none');
legend('训练样本', '测试样本', 'GPR预测', '95%置信区间');
xlabel('输入X'); ylabel('输出y');
title('GPR回归结果');
grid on;
subplot(1,2,2);
stem(X_test, y_test - mu_pred, 'k.', 'MarkerSize', 10);
hold on;
yline(0, 'r--', 'LineWidth', 1);
xlabel('输入X'); ylabel('预测误差');
title('预测误差分布');
grid on;
sgtitle('高斯过程回归基础实现');
2.2 超参数自动优化(基于梯度下降)
matlab
%% GPR超参数自动优化(负对数似然最小化)
function [best_params, opt_history] = optimize_gpr_hyperparams(X_train, y_train)
% 优化目标:最小化负对数似然
function nll = neg_log_likelihood(params, X, y)
l = exp(params(1)); % 长度尺度,取指数避免负数
sigma_f = exp(params(2)); % 信号方差
sigma_n = exp(params(3)); % 噪声方差
K = sigma_f^2 * exp(-pdist2(X, X, 'sqeuclidean') / (2*l^2));
K_noisy = K + sigma_n^2 * eye(length(y));
% 负对数似然公式:-log p(y|X)
nll = 0.5 * (y' * (K_noisy \ y) + log(det(K_noisy)) + length(y)*log(2*pi));
end
% 初始超参数
initial_params = [log(1.5), log(1.0), log(0.3)];
% 梯度下降优化
options = optimoptions('fminunc', 'Algorithm', 'quasi-newton', 'Display', 'iter');
[best_params_log, ~] = fminunc(@(p) neg_log_likelihood(p, X_train, y_train), initial_params, options);
% 转换回原始尺度
best_params = [exp(best_params_log(1)), exp(best_params_log(2)), exp(best_params_log(3))];
end
% 调用示例
[opt_params, ~] = optimize_gpr_hyperparams(X_train, y_train);
fprintf('优化后超参数:l=%.4f, sigma_f=%.4f, sigma_n=%.4f\n', opt_params(1), opt_params(2), opt_params(3));
2.3 增量学习实现(适配流式数据)
matlab
%% 增量GPR:适配流式/时序数据
classdef IncrementalGPR < handle
% 增量高斯过程回归,支持在线更新
properties
X; % 已见样本特征
y; % 已见样本标签
l = 1.5; % 长度尺度
sigma_f = 1; % 信号方差
sigma_n = 0.3; % 噪声方差
max_buffer = 100; % 最大缓存样本数,避免矩阵过大
end
methods
function obj = IncrementalGPR(varargin)
% 构造函数
for i = 1:2:length(varargin)
obj.(varargin{i}) = varargin{i+1};
end
obj.X = []; obj.y = [];
end
function update(obj, x_new, y_new)
% 增量更新模型
obj.X = [obj.X; x_new];
obj.y = [obj.y; y_new];
% 超过缓存限制则保留最近的样本
if size(obj.X, 1) > obj.max_buffer
obj.X = obj.X(end-obj.max_buffer+1:end, :);
obj.y = obj.y(end-obj.max_buffer+1:end);
end
end
function [mu, sigma] = predict(obj, X_test)
% 预测新样本
K_star = obj.sigma_f^2 * exp(-pdist2(X_test, obj.X, 'sqeuclidean') / (2*obj.l^2));
K_self = obj.sigma_f^2 * exp(-pdist2(X_test, X_test, 'sqeuclidean') / (2*obj.l^2));
K_train = obj.sigma_f^2 * exp(-pdist2(obj.X, obj.X, 'sqeuclidean') / (2*obj.l^2)) + obj.sigma_n^2 * eye(length(obj.y));
% Cholesky分解求逆
L = chol(K_train, 'lower');
alpha = L' \ (L \ (obj.y - mean(obj.y)));
mu = mean(obj.y) + K_star * alpha;
sigma = sqrt(diag(K_self + obj.sigma_n^2 - K_star * (K_train \ K_star')));
end
end
end
% 调用示例
gpr_inc = IncrementalGPR('max_buffer', 200);
for i = 1:length(X_train)
gpr_inc.update(X_train(i), y_train(i));
end
[mu_inc, sigma_inc] = gpr_inc.predict(X_test);
参考代码 高斯过程回归 www.youwenfan.com/contentcsu/55207.html
三、典型应用场景
3.1 小样本预测
当样本量少于50时,GPR的预测精度比SVR、随机森林高20%-40%,典型场景:
- 新材料性能测试(实验成本高,样本少)
- 罕见故障预测(故障样本稀缺)
- 药物研发活性预测(实验批次有限)
3.2 不确定性量化需求场景
天然输出预测方差的特性使其适合:
- 自动驾驶感知不确定性评估
- 金融风险价值(Value at Risk)计算
- 工业设备剩余寿命预测(输出失效概率)
3.3 主动学习
通过选择不确定性最高的样本进行标注,可将标注成本降低50%以上:
matlab
%% 主动学习:选择不确定性最高的样本
function x_query = active_learning(gpr_model, unlabeled_pool)
% 预测未标注样本的不确定性
[~, sigma] = gpr_model.predict(unlabeled_pool);
% 选择不确定性最高的样本
[~, idx] = max(sigma);
x_query = unlabeled_pool(idx, :);
end
四、优化与建议
4.1 核函数选择指南
| 核函数类型 | 适用场景 | 特点 |
|---|---|---|
| RBF核(径向基) | 光滑、无限可微函数 | 最常用,默认选择 |
| Matern 5/2核 | 存在少量不连续的函数 | 比RBF更灵活,允许有限阶导数 |
| 周期性核 | 周期性数据(如气温、销量) | 捕捉周期规律 |
| 线性核 | 线性关系数据 | 等价于贝叶斯线性回归 |
4.2 常见问题解决
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 矩阵奇异 | 样本重复或超参数不合理 | 增加噪声方差σn\sigma_nσn,删除重复样本 |
| 计算速度慢 | 样本量超过1000 | 使用稀疏GPR(Sparse GPR),仅用一部分诱导点 |
| 过拟合 | 信号方差σf\sigma_fσf过大 | 优化超参数,增加正则化项 |
| 欠拟合 | 长度尺度lll过大 | 减小lll值,捕捉更细粒度的规律 |
4.3 稀疏GPR加速实现(大数据场景)
matlab
%% 稀疏GPR:将计算复杂度从O(N³)降低到O(M³),M<<N
classdef SparseGPR < handle
properties
inducing_points; % 诱导点,数量远小于训练样本
K_mm; % 诱导点间协方差
K_mn; % 诱导点与训练样本协方差
K_nn_diag; % 训练样本自协方差对角
end
methods
function obj = SparseGPR(inducing_points)
obj.inducing_points = inducing_points;
end
function train(obj, X_train, y_train, l, sigma_f, sigma_n)
% 计算各协方差矩阵
obj.K_mm = sigma_f^2 * exp(-pdist2(obj.inducing_points, obj.inducing_points, 'sqeuclidean') / (2*l^2)) + sigma_n^2 * eye(size(obj.inducing_points, 1));
obj.K_mn = sigma_f^2 * exp(-pdist2(obj.inducing_points, X_train, 'sqeuclidean') / (2*l^2));
obj.K_nn_diag = sigma_f^2 + sigma_n^2;
end
function mu = predict(obj, X_test)
% 简化预测公式
Lambda = diag(obj.K_nn_diag) - diag(obj.K_mn * (obj.K_mm \ obj.K_mn'));
Q_nn = obj.K_mn' * (obj.K_mm \ obj.K_mn);
K_star_m = sigma_f^2 * exp(-pdist2(X_test, obj.inducing_points, 'sqeuclidean') / (2*l^2));
mu = mean(y_train) + K_star_m * (obj.K_mm \ (obj.K_mn * ((Q_nn + diag(Lambda)) \ (y_train - mean(y_train))));
end
end
end
五、总结
核心优势
- 小样本友好:10-50个样本即可达到高精度,适合高成本数据采集场景
- 天然不确定性量化:输出预测方差,为决策提供风险依据
- 无需手动特征工程:自动捕捉非线性关系,降低建模门槛
- 可解释性强:通过核函数的选择明确模型的先验假设