You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

训练大型数据集模型时出现MemoryError的解决方法咨询

解决高维数据集训练Ridge回归的内存不足问题

核心问题分析

你的数据集属于宽数据集(1217个样本,123万+特征),内存爆炸的核心原因是OneHotEncoder(sparse=False)强制生成了稠密矩阵——1217×1230748的稠密矩阵仅float64格式就占用11.2GB,即使转float32仍需5.6GB,再加上交叉验证的多份数据副本、并行训练的额外内存占用,直接超出了内存上限。

实用解决方案

1. 改用稀疏矩阵(最有效、最直接)

OneHotEncoder默认生成稀疏矩阵(sparse=True),仅存储非零值,能大幅降低内存占用(类别特征的one-hot编码中非零值占比极低)。修改代码如下:

# 去掉sparse=False,使用默认的稀疏矩阵输出
encoder = make_column_transformer(
    (OneHotEncoder(handle_unknown='ignore'), 
     ['remainder__ID_FINCA', 'remainder__ID_ZONA', 'remainder__ID_ESTACION', 'remainder__modeWinddirectiondiscrete', 'remainder__Phase'])
)

同时注意:Ridge的部分求解器不支持稀疏矩阵,需在参数中过滤掉svd和cholesky:

parameters = {
    'modelo__alpha': np.logspace(-4, 4, 9, endpoint=True),
    'modelo__max_iter': [1000, 3000, 5000, 10000, 15000],
    'modelo__solver': ['lsqr', 'sparse_cg', 'sag', 'saga']  # 仅保留支持稀疏矩阵的求解器
}

2. 特征降维(适配宽数据集)

由于特征数远大于样本数(123万 vs 1217),可以在预处理流程中加入降维步骤,用TruncatedSVD将高维特征压缩到低维(比如200-500维),大幅减少内存占用:

from sklearn.decomposition import TruncatedSVD

# 修改预处理Pipeline,加入降维步骤
preprocessing = make_pipeline(drop, encoder, TruncatedSVD(n_components=500, random_state=0))

注:TruncatedSVD支持稀疏矩阵输入,可与稀疏矩阵方案兼容。

3. 优化交叉验证与并行配置

  • 降低并行数:n_jobs=4会复制4份数据集到内存,可改为n_jobs=1,以训练速度换取内存空间;
  • 减少交叉验证强度:将RepeatedKFold(n_splits=5, n_repeats=5)改为n_repeats=2,减少训练轮次;
  • 缩减参数搜索次数:n_iter=20改为n_iter=10,减少模型训练的总次数。

4. 增量训练(分块处理数据)

如果上述方法仍无法解决,可使用SGDRegressor替代Ridge——SGD支持增量训练(partial_fit),可以分块加载数据训练,等价于带L2正则的线性回归(即Ridge):

from sklearn.linear_model import SGDRegressor

# 替换Ridge为SGDRegressor,配置参数模拟Ridge
pipe = Pipeline([
    ('preprocessing', preprocessing),
    ('modelo', SGDRegressor(loss='squared_error', penalty='l2', random_state=0))
])

# 调整参数搜索范围(SGD的alpha与Ridge的alpha含义不同,需按1/n_samples缩放)
parameters = {
    'modelo__alpha': np.logspace(-7, 1, 9, endpoint=True),
    'modelo__max_iter': [1000, 3000, 5000],
    'modelo__learning_rate': ['constant', 'optimal', 'invscaling']
}

# 示例:手动分块加载数据并增量训练
def chunk_generator(X, y, chunk_size=200):
    for i in range(0, len(X), chunk_size):
        yield X[i:i+chunk_size], y[i:i+chunk_size]

for chunk_X, chunk_y in chunk_generator(X_Train, y_Train):
    pipe.named_steps['modelo'].partial_fit(chunk_X, chunk_y)

5. 进一步压缩数据类型

若已使用稀疏矩阵,还可尝试将特征矩阵的 dtype 设为float32(稀疏矩阵支持指定数据类型):

encoder = make_column_transformer(
    (OneHotEncoder(handle_unknown='ignore', dtype=np.float32), 
     ['remainder__ID_FINCA', 'remainder__ID_ZONA', 'remainder__ID_ESTACION', 'remainder__modeWinddirectiondiscrete', 'remainder__Phase'])
)

内容的提问来源于stack exchange,提问作者Pablo Moreira Garcia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 09:53:13