使用StandardScaler的transform()处理训练测试集及运行警告求解
报错原因解析
RunTimeWarning: invalid value encountered in true_divide:StandardScaler的标准化规则为(特征值 - 对应特征均值) / 对应特征标准差,当训练集X_tr中存在取值完全相同的特征列时,该列标准差为0,计算过程出现除以0的情况,最终生成无效值nan,触发警告。RunTimeWarning: Degrees of Freedom <= 0 for slice:默认计算样本标准差采用无偏估计,自由度为样本数n - 1,当X_tr的样本量小于等于1时,自由度小于等于0,无法完成无偏标准差计算,触发警告。如果输入数据集的维度顺序异常(样本维度和特征维度颠倒),实际识别到的有效样本量不足,也会触发该问题。
代码修正方案
你原有代码调用fit_transform属于冗余操作,且没有适配异常数据场景,按照任务要求修正后的代码如下:
from sklearn.preprocessing import StandardScaler import numpy as np # 前置校验,避免异常数据导致警告 # 校验训练集样本量 if X_tr.shape[0] <= 1: raise ValueError("训练集样本量不可小于2,否则无法完成无偏标准差计算") # 校验是否存在标准差为0的常量特征列 train_std = np.std(X_tr, axis=0) constant_cols = train_std == 0 if np.any(constant_cols): # 过滤常量特征列 X_tr = X_tr[:, ~constant_cols] X_te = X_te[:, ~constant_cols] # 按任务要求执行拟合、标准化逻辑 scaler = StandardScaler() # 仅在训练集上拟合scaler scaler.fit(X_tr) # 分别对训练集、测试集做标准化 X_tr_scaled = scaler.transform(X_tr) X_te_scaled = scaler.transform(X_te)
如果场景允许使用有偏标准差,也可以初始化时添加ddof=0参数缓解自由度不足的警告:
scaler = StandardScaler(ddof=0)
核心逻辑说明
- Sklearn所有预处理工具的方法逻辑统一:
fit()仅从输入数据中统计所需参数(如StandardScaler的均值、标准差),不会修改输入数据;transform()用已统计完成的参数对输入数据做转换;fit_transform()是前两个方法的组合,仅可用于训练集。 - 测试集标准化必须使用训练集拟合得到的参数,不可单独对测试集执行
fit()或fit_transform(),否则会产生数据泄露,导致模型泛化能力评估结果失真。
内容的提问来源于stack exchange,提问作者swordlordswamplord
相关产品推荐
相关产品推荐

