PySpark实现SMOTE处理航班延误数据集时运行缓慢及磁盘溢出求助
问题原因定位
- 数据集本身无问题:1:7的正负样本比例属于轻度不平衡范畴,3400万行的量级在分布式场景下属于合理规模,不存在结构性异常。
- 操作存在明显不合理项:代码中
coalesce(1)会强制将所有分片数据合并到单个节点生成一个文件,单节点需要承载全量数据的写入压力,是直接触发No space left on device报错的核心诱因之一;此外Colab本地磁盘配额极小,写入临时文件再同步云盘的逻辑也会额外消耗存储空间。 - 所用SMOTE实现存在性能缺陷:该第三方实现基于LSH做近邻搜索,但未做shuffle优化,也未针对高基数离散特征做适配,随着数据量上升,shuffle过程产生的临时中间文件会指数级增长,就是10%数据耗时14小时、全量数据磁盘持续占满的根本原因,小样本场景下shuffle压力小所以未暴露问题。
解决思路
操作侧快速优化
- 移除
coalesce(1)操作,若确实需要单个输出文件,可待Spark任务全部完成后,用Shell命令合并多个输出分片,不要在计算环节做单分区合并。 - 调整写入路径直接指向挂载的云盘目录,不要写入Colab本地临时目录,避免额外占用本地磁盘配额。
- 调整SMOTE参数:当前
multiplier=2会将少数类样本扩增2倍,你当前的不平衡度仅需将少数类扩增3倍即可达到1:2的合理比例,完全满足训练需求;甚至针对1:7的轻度不平衡场景,可直接放弃SMOTE方案,改用模型内置的类别权重参数(如树模型的scale_pos_weight配置),效果不会劣于SMOTE,性能可提升数十倍。
代码层面优化
- 在
pre_smote_df_process处理完成后调用cache()或persist()方法,将预处理后的数据集缓存到内存+磁盘,避免重复计算消耗资源。 - 适当调大
bucketLength参数,减少LSH分桶数量,降低shuffle压力。 - 若优化后性能仍不达标,直接放弃第三方SMOTE实现,改用Spark原生的不平衡处理方案:对多数类做随机下采样,或直接使用类别权重,适配性和性能远优于未经过大规模验证的第三方实现。
环境侧调整
- 本地运行时修改Spark配置
spark.local.dir,将临时shuffle文件路径指向剩余空间充足的磁盘分区,避免临时文件占满系统盘。 - 不要使用Colab运行该量级的分布式任务,Colab为共享资源,磁盘、CPU配额极低,本地资源不足可改用云服务商的Spark托管服务。
内容的提问来源于stack exchange,提问作者Ahmad Rizal Alifio
相关产品推荐
相关产品推荐

