Python+Sklearn聚类时特征缩放报稀疏矩阵无法居中错误咨询
问题根源
你触发报错的核心原因是:OneHotEncoder默认输出稀疏矩阵,而StandardScaler默认开启均值中心化操作,该操作会破坏稀疏矩阵的存储结构,Scikit-Learn为了避免内存溢出直接禁止了该操作,所以抛出对应报错。
ValueError: Cannot center sparse matrices: pass
with_mean=Falseinstead. See docstring for motivation and alternatives.
具体原因拆解
- 你通过
ColumnTransformer搭配多列独热编码后,输出的features是稀疏矩阵格式,可通过print(type(features))验证,结果为稀疏矩阵类(如scipy.sparse.csr_matrix)。你当前编码后特征维度高达29800,40万行的对应稠密矩阵内存占用会超过普通设备阈值。 StandardScaler默认执行(特征值 - 特征均值)/特征标准差的计算,减去均值的操作会让原本大部分为0的稀疏矩阵转为稠密矩阵,因此Scikit-Learn直接拦截了该操作。
可行解决方案
方案1:最小改动修复报错
直接修改StandardScaler的初始化参数,关闭均值中心化即可,修改后缩放操作不会破坏稀疏矩阵结构:
# 把原来的scaler = StandardScaler()改成下面的代码 scaler = StandardScaler(with_mean=False) features = scaler.fit_transform(features)
方案2:更合理的预处理逻辑(推荐)
独热编码生成的0/1特征本身不需要做标准化,只有原本的连续值特征(Quantity、UnitPrice、CustomerID、Total Price)需要缩放,你可以直接把缩放逻辑整合到ColumnTransformer中,既避免稀疏矩阵报错,也符合特征处理的规范:
transformerVectoriser = ColumnTransformer(transformers=[ ('Encoding Invoice number', OneHotEncoder(handle_unknown = "ignore"), ['InvoiceNo']), ('Encoding StockCode', OneHotEncoder(handle_unknown = "ignore"), ['StockCode']), ('Encoding Description', OneHotEncoder(handle_unknown = "ignore"), ['Description']), ('Encoding Country', OneHotEncoder(handle_unknown = "ignore"), ['Country']), ('Scaling numeric features', StandardScaler(), ['Quantity', 'UnitPrice', 'CustomerID', 'Total Price']) ], remainder='drop') features = transformerVectoriser.fit_transform(df) # 后续无需再单独执行scaler.fit_transform操作
额外代码Bug修复
你当前肘部法计算的代码存在逻辑错误,inertia_是KMeans训练后的模型属性,不是数据集的属性,需要修改:
# 把原来的sum_of_squared_distances.append(features.inertia_)改成下面的代码 sum_of_squared_distances.append(kmeans.inertia_)
内容的提问来源于stack exchange,提问作者taga
相关产品推荐
相关产品推荐

