使用Scikit-learn GaussianProcessClassifier的fit()时出现内存错误
解决GaussianProcessClassifier拟合大样本时的内存错误问题
兄弟,你碰到的这个内存报错其实是高斯过程模型的固有特性导致的——GaussianProcessClassifier在拟合阶段需要计算n×n的核矩阵(n是样本数),32561个样本的话,这个矩阵按64位浮点数算,得占8GB以上的内存,普通机器根本顶不住。下面给你几个靠谱的解决思路:
1. 用诱导点做近似计算(最推荐)
scikit-learn本身就支持基于诱导点的近似高斯过程,能把核矩阵的规模从n×n降到m×m(m是诱导点数量,比如选1000个就行),内存占用直接砍一大截。代码这么写:
from sklearn.gaussian_process.kernels import RBF, InducingPointKernel import numpy as np # 随机挑1000个样本当诱导点(数量可以自己调) n_inducing = 1000 inducing_points = X_train[np.random.choice(X_train.shape[0], n_inducing, replace=False)] # 构建带诱导点的核函数 kernel = InducingPointKernel(RBF(length_scale=1.0), inducing_points=inducing_points) gp_opt = GaussianProcessClassifier(kernel=kernel, random_state=42) gp_opt.fit(X_train, y_train)
2. 先给特征降维
你的特征有108维,先做个降维处理,比如用PCA把维度压到20左右,既减少计算量,还能顺便缓解过拟合:
from sklearn.decomposition import PCA # 把特征降到20维(维度可以根据模型效果调整) pca = PCA(n_components=20, random_state=42) X_train_reduced = pca.fit_transform(X_train) # 用降维后的特征训练模型 gp_opt = GaussianProcessClassifier(kernel=RBF(), random_state=42) gp_opt.fit(X_train_reduced, y_train)
3. 缩减训练样本量
如果数据集有冗余,或者能接受一点精度损失,可以随机抽一部分样本训练,比如抽10000个:
# 随机采样10000个样本 sample_size = 10000 sample_indices = np.random.choice(X_train.shape[0], sample_size, replace=False) X_train_sample = X_train[sample_indices] y_train_sample = y_train[sample_indices] gp_opt = GaussianProcessClassifier(kernel=RBF(), random_state=42) gp_opt.fit(X_train_sample, y_train_sample)
这个方法最简单,但缺点是会丢数据,可能影响模型性能。
4. 换用更高效的专用库
要是scikit-learn的GPC还是不够用,可以试试GPyTorch或者PyMC3这类专门优化大规模高斯过程的库,它们支持批处理和GPU加速,应付大样本更轻松。比如用GPyTorch的示例代码:
import torch import gpytorch # 把numpy数组转成PyTorch张量 X_train_tensor = torch.tensor(X_train, dtype=torch.float32) y_train_tensor = torch.tensor(y_train, dtype=torch.int64) # 定义变分高斯过程分类模型 class GPClassificationModel(gpytorch.models.ApproximateGP): def __init__(self, inducing_points): variational_distribution = gpytorch.variational.CholeskyVariationalDistribution(inducing_points.size(0)) variational_strategy = gpytorch.variational.VariationalStrategy( self, inducing_points, variational_distribution, learn_inducing_locations=True ) super().__init__(variational_strategy) self.mean_module = gpytorch.means.ConstantMean() self.covar_module = gpytorch.kernels.ScaleKernel(gpytorch.kernels.RBFKernel()) def forward(self, x): mean_x = self.mean_module(x) covar_x = self.covar_module(x) return gpytorch.distributions.MultivariateNormal(mean_x, covar_x) # 初始化模型和诱导点 inducing_points = X_train_tensor[:1000, :] model = GPClassificationModel(inducing_points) likelihood = gpytorch.likelihoods.SoftmaxLikelihood(num_features=1, num_classes=2) # 开始训练 model.train() likelihood.train() optimizer = torch.optim.Adam(model.parameters(), lr=0.01) mll = gpytorch.mlls.VariationalELBO(likelihood, model, num_data=y_train_tensor.size(0)) for i in range(100): optimizer.zero_grad() output = model(X_train_tensor) loss = -mll(output, y_train_tensor) loss.backward() optimizer.step()
内容的提问来源于stack exchange,提问作者yalpsid eman
相关产品推荐
相关产品推荐

