Scikit-learn高斯过程回归器返回二维向量而非协方差矩阵问题
问题
我正在将二维输入、二维输出的数据拟合到Scikit-learn的GaussianProcessRegressor中,但获取协方差矩阵时得到的是二维向量而非矩阵。部分示例可正常返回二维矩阵,但我不清楚自身案例的问题所在,是否应将返回的两个值视为对角矩阵的对角线值?
以下是复现该问题的简单示例:
import numpy as np from sklearn.gaussian_process import GaussianProcessRegressor from sklearn.gaussian_process.kernels import RationalQuadratic # 简单数据集 X = np.array([[0,1], [1,0]]) y = np.array([np.sin(12 * X[:, 0]).ravel(), np.cos(12 * X[:, 1]).ravel()]) kernel = RationalQuadratic() gpr = GaussianProcessRegressor(kernel=kernel, random_state=0) gpr.fit(X, y) new_x = np.array([[0.1, 0.5]]) y_pred, y_cov = gpr.predict(new_x, return_cov=True) print("y_pred:", y_pred) print("y_cov:", y_cov)
运行后输出:
y_pred: [[ 1.71640581e-05 -2.47700145e-03]] y_cov: [[[0.99997834 0.99997834]]]
若改为返回标准差(不确定其对二维目标的意义):
y_pred, y_std = gpr.predict(np.array([[0.1, 0.5]]), return_std=True) print("y_pred:", y_pred) print("y_std:", y_std)
输出:
y_pred: [[ 1.71640581e-05 -2.47700145e-03]] y_std: [[0.99998917 0.99998917]]
注意维度差异:
y_cov.shape
输出:(1, 1, 2)
y_std.shape
输出:(1, 2)
解答
核心原因:样本量不足导致核矩阵不可逆
你遇到的问题本质是训练样本数量过少(仅2个样本),Scikit-learn的GPR在这种情况下无法正确估计多输出维度之间的协方差,只能退化为输出各维度的独立方差(也就是对角矩阵的对角线值)。
具体解释
- 多输出GPR的协方差计算逻辑:拟合多输出数据时,GPR默认通过核函数和样本数据共同估计不同输出维度间的协方差。但如果训练样本数≤输出维度数(你的案例中样本数2,输出维度2),核矩阵会出现秩亏,无法完成逆运算,导致无法计算维度间的交叉协方差项。
- 返回结果的含义:
y_cov的形状(1,1,2):第一个维度对应预测样本数,第二个维度本应对应协方差矩阵的维度,但因为无法计算交叉协方差,所以只返回了每个输出维度的方差值,等价于对角矩阵的对角线元素。y_std的形状(1,2):就是每个输出维度标准差的直接结果,对应方差的平方根。
验证与解决方法
增加训练样本数量(至少3个以上),就能得到完整的二维协方差矩阵。例如修改数据集:
# 增加训练样本 X = np.array([[0,1], [1,0], [0.5, 0.5], [0.2, 0.8]]) y = np.array([np.sin(12 * X[:, 0]).ravel(), np.cos(12 * X[:, 1]).ravel()]) # 重新训练并预测 gpr.fit(X, y) y_pred, y_cov = gpr.predict(new_x, return_cov=True) print(y_cov.shape) # 输出 (1, 2, 2),即每个预测样本对应的2x2协方差矩阵
此时y_cov会是形状为(1,2,2)的数组,其中y_cov[0]就是完整的2x2协方差矩阵,包含不同输出维度之间的协方差项。
内容的提问来源于stack exchange,提问作者JackS
相关产品推荐
相关产品推荐

