为您的数值特征选择合适的缩放或转换方法是特征工程流程中的一个重要环节。正如我们所见,不同的方法应对不同的问题,例如量纲不同、分布偏斜或存在异常值。没有唯一的“最佳”方法;最优选择很大程度上取决于您的数据特点以及您打算使用的机器学习算法的要求。让我们分析一下需要考虑的因素。算法对特征量纲的敏感度缩放的主要原因通常是算法本身。敏感算法: 许多算法对输入特征的量纲敏感。基于距离的算法: K-近邻 (KNN)、带有某些核函数(如 RBF)的支持向量机 (SVM) 和聚类算法(例如 K-Means)等方法依赖于计算数据点之间的距离。值和范围较大的特征可能会不成比例地影响这些距离计算,可能导致范围较小的特征实际上被忽略。标准化 (StandardScaler) 或归一化 (MinMaxScaler) 在此处通常是不错的选择。如果异常值很明显,通常优选鲁棒缩放 (RobustScaler),因为它使用的统计量对极端值(中位数和四分位距)不那么敏感。基于梯度下降的算法: 使用梯度下降优化的算法,包括线性回归、逻辑回归、神经网络,依赖于根据误差梯度迭代更新权重。量纲显著不同的特征可能导致收敛慢或更新不稳定,因为与不同特征关联的权重所需的学习率可能显著不同。标准化是常见且有效的选择,因为它将数据中心化到零并缩放到单位方差,通常能带来更平滑、更快的收敛。归一化也可以使用。不那么敏感的算法:基于树的算法: 决策树、随机森林和梯度提升机(如 XGBoost、LightGBM)通常对特征的量纲不敏感。它们通过基于单个特征的阈值来划分特征空间。无论特征范围是 0 到 1 还是 0 到 1,000,000,树都能找到一个最优分割点。因此,对于这些模型来说,缩放并不是绝对必要的,它们也能正常运行。然而,应用缩放通常不会损害性能,有时会带来少量益处,尤其是在某些梯度提升实现中进行正则化时。如果处理偏斜的转换有助于创建更平衡的分割,那么这些转换可能仍然有益。数据分布和模型假设缩放和转换旨在重塑特征的分布,这对于某些模型或分析有益。处理偏斜: 线性模型(如线性/逻辑回归)在输入特征(以及回归中的目标变量)的分布更接近高斯(正态)时通常表现更好。高度偏斜的特征可能违反线性度和同方差性(误差方差恒定)的假设。对于正偏斜数据(右侧长尾),对数转换 (np.log 或 np.log1p,用于包含零值的数据)是减少偏斜的简单且通常有效的方法。对于更复杂的偏斜或目标是接近正态分布的情况,可以应用 Box-Cox 转换 (scipy.stats.boxcox 或 PowerTransformer(method='box-cox')),但这要求数据必须严格为正。Yeo-Johnson 转换 (PowerTransformer(method='yeo-johnson')) 更灵活,因为它支持正值、零值和负值,也旨在使分布更对称、更接近高斯。非参数转换: 如果您希望数据服从特定分布,例如均匀分布或正态分布,而不论其原始形状如何,那么分位数转换 (QuantileTransformer) 是有用的。它根据分位数映射数据,有效地分散最频繁的值并压缩稀疏的值。这对于具有复杂、多峰分布的特征或处理异常值时特别有效。异常值的存在异常值,即极端值,会显著扭曲某些缩放方法的结果。标准化: 标准化中使用的均值 ($\mu$) 和标准差 ($\sigma$) ($Z = \frac{x - \mu}{\sigma}$) 对异常值高度敏感。少数极端值可以大幅改变均值并夸大标准差,导致大部分数据被压缩到很窄的范围。归一化: 最小-最大缩放 ($X_{norm} = \frac{x - min(x)}{max(x) - min(x)}$) 甚至更敏感,因为最小值和最大值直接定义了输出范围 [0, 1]。异常值将决定边界,可能将大部分非异常值数据点压缩到一个非常小的区间内。鲁棒缩放: 这种方法使用中位数和四分位距 (IQR) 来缩放数据,它们受异常值的影响小得多。如果您的数据包含显著异常值且您不想移除它们,RobustScaler 通常是最适合的缩放方法。转换: 像对数转换这样的方法有时可以通过压缩较大的值来减轻异常值的影响。将 output_distribution='normal' 的分位数转换也可以将异常值映射到标准正态分布的尾部,减少它们的极端影响。可解释性需求有时,保持特征的可解释性很重要。缩放: 标准化和归一化改变了量纲,但保留了相对关系和分布形状。在线性模型中,对缩放数据训练的系数仍然表示缩放特征单位变化时目标的变化,这可能更难与原始单位关联,但保留了方向性意义。转换: 对数、Box-Cox、Yeo-Johnson 和分位数转换从根本上改变了特征的值和分布。解释与这些转换后的特征相关的模型系数需要仔细考虑(例如,对数转换特征的单位变化对应于原始特征的乘法变化)。这会使直接解释更复杂。实际工作流程和实验仅在训练数据上拟合: 这极为重要。始终只使用训练数据来拟合您的缩放器或转换器。然后,使用已拟合的对象来转换训练集、验证集和测试集。这可以防止验证/测试集的信息泄露到训练过程。# StandardScaler 示例 from sklearn.preprocessing import StandardScaler import numpy as np # 假设 X_train, X_val, X_test 是 numpy 数组或 pandas DataFrame scaler = StandardScaler() # 仅在训练数据上拟合 X_train_scaled = scaler.fit_transform(X_train) # 将相同的已拟合缩放器应用于验证和测试数据 X_val_scaled = scaler.transform(X_val) X_test_scaled = scaler.transform(X_test)谨慎结合技术: 您有时可能会先应用转换(例如,对数转换),然后缩放结果(例如,标准化)。这可以使用 Scikit-learn 的 Pipeline 或 ColumnTransformer 实现。实验: 通常,最佳选择方法是经验性的。根据您的数据分析和算法选择,尝试几种合理的缩放/转换方法。使用交叉验证评估您的机器学习模型在训练集上每种方法的性能,并选择根据您选择的指标获得最佳结果的方法。决策指导流程图这是一个简化的流程图来指导您的决策过程:digraph G { rankdir=TB; node [shape=box, style="rounded,filled", fillcolor="#e9ecef", fontname="sans-serif"]; edge [fontname="sans-serif", fontsize=10]; start [label="开始:选择特征"]; q_outliers [label="是否存在显著且有影响的异常值?", shape=diamond, fillcolor="#ffec99"]; q_skewed [label="特征分布是否高度偏斜?", shape=diamond, fillcolor="#ffec99"]; q_algo [label="算法对量纲是否敏感?\n(例如:KNN, SVM, 线性模型,\n神经网络)", shape=diamond, fillcolor="#ffec99"]; q_gauss [label="算法是否受益于高斯型分布?\n(例如:某些线性模型)", shape=diamond, fillcolor="#ffec99"]; use_robust [label="考虑 RobustScaler", shape=box, fillcolor="#a5d8ff"]; use_transform_outlier [label="考虑对数、Yeo-Johnson,\n或分位数转换\n(也可能减轻异常值影响)", shape=box, fillcolor="#a5d8ff"]; use_transform_skew [label="考虑对数(如果 > 0),\nBox-Cox(如果 > 0),\nYeo-Johnson,\n或分位数转换", shape=box, fillcolor="#a5d8ff"]; use_scale [label="考虑 StandardScaler\n或 MinMaxScaler", shape=box, fillcolor="#a5d8ff"]; no_action [label="缩放/转换\n可能并非绝对必要\n(例如:树模型)。\n考虑其是否有益。", shape=box, fillcolor="#dee2e6"]; experiment [label="实验与交叉验证评估", shape=box, style="rounded,filled", fillcolor="#b2f2bb"]; start -> q_outliers; q_outliers -> use_robust [label="是"]; q_outliers -> q_skewed [label="否/不确定"]; use_robust -> q_skewed; # 缩放后可能仍需转换 q_skewed -> use_transform_skew [label="是"]; q_skewed -> q_algo [label="否"]; use_transform_skew -> q_algo [label="应用转换,\n然后考虑缩放"]; q_algo -> use_scale [label="是"]; q_algo -> no_action [label="否 (例如:树模型)"]; use_scale -> experiment; no_action -> q_gauss # 即使对量纲不敏感,也要检查分布需求 q_gauss -> use_transform_skew [label="是"]; q_gauss -> experiment [label="否"]; # 添加最终通往实验的路径边 use_robust -> experiment [style=dotted] use_transform_skew -> experiment [style=dotted] use_transform_outlier -> experiment [style=dotted] # 隐含在偏斜检查中,但可能从异常值路径明确添加?为简单起见,我们通过偏斜路径路由。 # 异常值转换路径路由 q_outliers -> use_transform_outlier [label="也许\n(RobustScaler 的替代方案)"]; use_transform_outlier -> q_algo; }一个流程图,概述了根据数据特征(异常值、偏斜)和算法敏感性选择缩放或转换方法的一个可能的决策流程。注意,通常需要进行实验。通过考虑这些因素、算法要求、数据分布、异常值和可解释性,并通过实验验证您的选择,您可以有效应用缩放和转换技术来提升机器学习模型的性能。