4万行多语言艺术家名称列用OneHotEncoder编码出现MemoryError如何解决
问题根因
你触发内存错误的核心原因是sparse=False参数将独热编码生成的稀疏矩阵强制转换为稠密矩阵存储,当艺术家列的唯一值数量较多时,生成的编码列数会远高于原始数据列数,4万行的稠密矩阵会占用大量内存,合并时就会触发内存溢出。
多语言艺术家名预处理建议
因为是多语言名称,首先要做归一化处理,避免同一个艺术家的不同写法被判定为不同分类,从源头降低编码维度:
- 统一Unicode标准化,处理不同编码的重音、变体字符
- 统一大小写、去掉多余的空格、特殊符号
- 必要时可以做跨语言转写,把非拉丁语种的名称统一转成拉丁字母写法,进一步减少重复分类
优化方案
方案1:保留稀疏格式做后续处理
如果你的后续建模工具(比如scikit-learn的大部分模型)支持稀疏矩阵输入,完全不需要转成稠密DataFrame:
# 直接保留稀疏矩阵格式,不转成稠密DataFrame # scikit-learn 1.2以下版本用sparse=True,1.2+版本参数更名为sparse_output=True enc = OneHotEncoder(sparse_output=True) artists_encode_sparse = enc.fit_transform(artists_df[artists_cat]) # 后续如果需要和其他数值特征合并,可以用scipy的稀疏矩阵拼接方法 from scipy.sparse import hstack other_features = artists_df.drop(artists_cat, axis=1).values all_features = hstack([other_features, artists_encode_sparse])
这种方式内存占用会降到原来的几十分之一,完全不会触发内存错误。
方案2:进一步降低编码维度
如果必须用稠密格式存储,可以从维度层面优化:
- 低频艺术家合并:把出现次数低于阈值(比如出现少于5次)的艺术家统一归类为
其他分类,大幅减少唯一值数量,从而减少编码列数
# 示例:合并出现次数少于3次的艺术家 counts = artists_df['artist_name'].value_counts() artists_df['artist_name_processed'] = artists_df['artist_name'].apply(lambda x: x if counts[x] >=3 else '其他')
- 改用低维编码方式:独热编码是高维稀疏编码,你可以改用目标编码、均值编码或者基于预训练模型的文本嵌入编码,比如多语言BERT生成768维的固定维度向量,不管有多少个唯一艺术家,编码维度都是固定的,不会随基数增长。
方案3:用Pandas原生的稀疏数据结构
如果一定要把编码结果存为DataFrame格式,可以用Pandas的SparseDtype存储稀疏列,不用转成稠密格式:
enc = OneHotEncoder(sparse_output=True) artists_encode_sparse = enc.fit_transform(artists_df[artists_cat]) # 转成稀疏DataFrame,内存占用极低 artists_encode_df = pd.DataFrame.sparse.from_spmatrix( artists_encode_sparse, columns=enc.get_feature_names_out(artists_cat) ) # 合并的时候也会保留稀疏格式,不会爆内存 merged_df = pd.concat([artists_df.drop(artists_cat, axis=1), artists_encode_df], axis=1)
内容的提问来源于stack exchange,提问作者Homa Almasieh
相关产品推荐
相关产品推荐

