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

如何基于1000个Parquet文件训练二分类模型并规避内存不足?

解决Parquet大内存二分类训练的内存不足问题

你的代码核心问题是调用了df.compute(),把整个Dask DataFrame转换成了Pandas DataFrame,强制将所有数据载入内存,直接导致内存溢出。以下是几种可行的优化方案:

方案1:基于Dask的全流程分块处理

保留Dask的分块特性,全程不触发全量计算,用Dask ML适配的模型或Scikit-learn模型做增量训练:

修正原有Dask代码(避免全量compute)

import dask.dataframe as dd
from dask_ml.model_selection import train_test_split
from dask_ml.linear_model import LogisticRegression  # Dask适配的模型

# 直接用Dask读取Parquet,无需手动写delayed(Dask原生支持Parquet分块读取)
df = dd.read_parquet('data/*.parquet')

# 分块拆分训练集测试集,无需全量载入
X = df.drop(['label'], axis=1)
y = df['label']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# 用Dask ML的模型训练,全程分块处理
model = LogisticRegression()
model.fit(X_train, y_train)

# 分块评估
accuracy = model.score(X_test, y_test)
print(f"测试集准确率: {accuracy.compute()}")

如果想用Scikit-learn的原生模型,可结合dask_ml.wrappers.Incremental做增量训练:

from sklearn.linear_model import SGDClassifier
from dask_ml.wrappers import Incremental

sgd = SGDClassifier(loss='log_loss')  # 逻辑回归的SGD版本,支持增量训练
model = Incremental(sgd)
model.fit(X_train, y_train, classes=[0, 1])  # 指定分类类别

方案2:Pandas分块读取+增量训练

如果不想用Dask,可直接用Pandas分块读取Parquet文件,配合支持partial_fit的模型(如SGD系列、朴素贝叶斯等):

import pandas as pd
from sklearn.linear_model import SGDClassifier
from sklearn.metrics import accuracy_score
import glob

files = sorted(glob.glob('data/*.parquet'))
model = SGDClassifier(loss='log_loss')
classes = [0, 1]

# 先遍历一次所有块,训练模型
for file in files:
    chunk = pd.read_parquet(file)
    X_chunk = chunk.drop(['label'], axis=1)
    y_chunk = chunk['label']
    model.partial_fit(X_chunk, y_chunk, classes=classes)

# 单独用测试集块评估(可拆分部分文件作为测试集)
test_files = files[-2:]  # 取最后2个文件做测试
y_true = []
y_pred = []
for file in test_files:
    chunk = pd.read_parquet(file)
    X_chunk = chunk.drop(['label'], axis=1)
    y_chunk = chunk['label']
    y_pred.extend(model.predict(X_chunk))
    y_true.extend(y_chunk)

print(f"测试集准确率: {accuracy_score(y_true, y_pred)}")

方案3:深度学习框架流式加载(适用于深度模型)

如果用TensorFlow或PyTorch,可直接构建流式数据集,无需全量载入:

TensorFlow示例

import tensorflow as tf
import pyarrow.parquet as pq

def parse_parquet(file_path):
    # 读取单块Parquet并转换为TensorFlow格式
    table = pq.read_table(file_path)
    df = table.to_pandas()
    X = df.drop(['label'], axis=1).values
    y = df['label'].values
    return tf.data.Dataset.from_tensor_slices((X, y))

# 构建流式数据集
file_dataset = tf.data.Dataset.list_files('data/*.parquet')
dataset = file_dataset.interleave(
    parse_parquet,
    num_parallel_calls=tf.data.AUTOTUNE
).shuffle(1000).batch(32)  # 按需设置batch size

# 定义并训练模型
model = tf.keras.Sequential([
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(dataset, epochs=5)

额外注意点

  • 原代码中[load_chunk(f) for f in chunk]是笔误,应该是[load_chunk(f) for f in files]
  • 优先选择Dask方案,因为它自动处理分块、并行计算,代码改动最小
  • 若用传统机器学习模型,优先选支持partial_fit的模型,避免全量数据依赖

内容的提问来源于stack exchange,提问作者Mason

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 12:30:10