您应该根据对数据的意义来选择缩放方案。 There are different ways of scaling,您将使用哪一个取决于数据。每种方案都将不同特征的值带入可比较的范围内,但它们中的每一个都保留了不同类型的信息(并扭曲了其他信息)。尽管在为什么某些缩放方案更适合特定情况下有合理的解释,尝试这些不同的方案(就像您对标准缩放和标准化所做的那样)并使用效果更好的方案并没有错(只要您进行交叉验证或以其他方式确保您的绩效衡量是通用且准确的)。
StandardScaler
这就是sklearn.preprocessing.scale(X) 使用的。它假定您的特征是正态分布的(每个特征具有不同的均值和标准差),并对其进行缩放,使每个特征的高斯分布现在以 0 为中心,其标准差为 1。
它通过计算每个特征的平均值和标准差来做到这一点,然后将特征的每个实际值转换为z-score:这个值与平均值相差多少标准差? z=(value-mean)/stdev
这通常效果很好,但如果正态假设对您的情况完全错误,那么这可能不是您的最佳缩放方案。实际上,在正态假设不适用的许多情况下保持,但分布有点接近,这个方案仍然运作良好。但是,如果数据完全偏离正态分布,例如高度偏斜的肥尾分布(如幂律),则此方案不会产生良好的结果。
Normalizer
这就是sklearn.preprocessing.normalize(X, axis=0) 使用的。它将给定数据点的所有特征值视为一个向量,并通过将该向量除以其大小来规范化该向量。例如,假设您有 3 个功能。特定点的值为[x1, x2, x3]。如果您使用默认的'l2' 标准化,则将每个值除以sqrt(x1^2 + x2^2 + x3^2)。如果您使用'l1' 标准化,则将每个除以x1+x2+x3。这确保了每个特征的值在相似的范围内,因为每个特征向量都是一个单位向量。如果一个点的特征值很大,那么幅度也很大,你除以一个很大的数。如果它们很小,则将它们除以一个小数。
原因是您可以将数据视为 n 维空间中的点,其中 n 是特征的数量。每个特征都是一个轴。标准化将每个点拉回原点,使其距离原点仅 1 个单位。基本上,您将空间折叠到单位超立方体中。每个点的向量之间的角度(从原点到数据点)保持不变。
这在文本数据中被大量使用,因为它在此处具有很多直观意义:如果每个特征都是不同单词的计数,'l1' 归一化基本上将这些计数转换为频率(你除以总字数)。这是有道理的。如果您使用'l2' 归一化,当您对两者进行归一化时,两个向量之间的角度(这称为余弦距离或相似度)将保持不变,并且该距离更接近于含义距离因为它对应于单词之间的频率比率,并且不受每个向量代表的文本长度的影响。
如果保存点之间的余弦距离类型的关系对您的数据更有意义,或者如果归一化对应于自然缩放(例如采用频率而不是计数),那么这个更合适。
MinMaxScaler
你可以像sklearn.preprocessing.MinMaxScaler().fit_transform(X)一样使用这个。对于每个特征,这会查看最小值和最大值。这是此功能的范围。然后它会针对每个特征将其缩小或拉伸到相同的范围(默认为 0 到 1)。
它通过将每个值转换为(value-feature_min)/(feature_max - feature_min) 来实现这一点。基本上我在说谎范围的百分之几?请记住,范围仅由特征的最小值和最大值决定。对于所有这些问题,所有值可能都在 10、11 左右,并且有一个异常值是 900。没关系,您的范围是 10 到 900。您可以看到在某些情况下这是可取的,并且在其他情况下,这将是有问题的,具体取决于具体问题和数据。
此方案在 StandardScaler 可能无法正常工作的某些情况下效果更好。例如,如果特征的标准差非常小,StandardScaler 对不同特征的标准差之间的微小变化高度敏感,但MinMaxScaler 非常稳健。此外,对于具有高度偏态分布的特征,或每个特征都有很多零从而使分布偏离高斯分布的稀疏情况,MinMaxScaler 是更好的选择。