正如本章引言中提到的,你输入机器学习算法的数据常常需要一些调整。设想一个包含房屋信息的数据集:一个特征可能是卧室数量(通常范围为1到5间),而另一个可能是房屋价格(范围从$50,000到$1,000,000或更高)。这些特征在尺度上差异很大。为何要对特征进行缩放?许多机器学习算法,特别是那些依赖计算数据点之间距离的算法(例如K近邻算法)或使用梯度下降进行优化的算法(例如线性回归、逻辑回归和神经网络),在数值输入特征处于相似尺度时,表现会好得多,或者收敛更快。设想使用上述原始特征来计算两套房屋之间的距离。2间卧室的差异对总距离计算的贡献,与$100,000的价格差异相比,显得微不足道。价格特征,仅仅因为其数值更大,就会在距离计算中占据主导地位。这可能导致算法错误地认为价格比卧室数量重要得多,仅仅因为尺度不同。特征缩放是将数值特征转换到共同尺度的过程,同时不过分改变数据的基本分布或内部关联。它确保所有特征对学习过程的贡献更为均衡。特征缩放有两种非常普遍的方法:归一化和标准化。归一化(最小-最大缩放)归一化将特征的值重新调整到固定范围,通常在0到1之间。其计算方式是,从每个数据点中减去该特征的最小值,然后除以范围(最大值减去最小值)。公式如下: $$ x' = \frac{x - \min(x)}{\max(x) - \min(x)} $$ 这里:$x$ 是原始值。$\min(x)$ 是数据集中该特征的最小值。$\max(x)$ 是数据集中该特征的最大值。$x'$ 是归一化后的值。归一化后,特征的最小值变为0,最大值变为1。所有其他值按比例落在这个范围内。例子: 考虑一个值为 [20, 25, 40, 60] 的“年龄”特征。$\min(\text{年龄}) = 20$$\max(\text{年龄}) = 60$范围 = $60 - 20 = 40$应用公式:对于年龄 20: $(20 - 20) / 40 = 0.0$对于年龄 25: $(25 - 20) / 40 = 5 / 40 = 0.125$对于年龄 40: $(40 - 20) / 40 = 20 / 40 = 0.5$对于年龄 60: $(60 - 20) / 40 = 40 / 40 = 1.0$ 归一化后的“年龄”值是 [0.0, 0.125, 0.5, 1.0]。优点: 确保特征值将在 [0, 1] 范围内。这对于某些算法很有用,特别是在图像处理或神经网络中,它们需要此范围内的输入。缺点: 归一化对异常值相当敏感。如果存在单个非常高或非常低的值,它可能会将大多数其他数据点压缩到 [0, 1] 范围的非常小的一部分,可能因此丢失它们相对差异的一些信息。标准化(Z分数缩放)标准化重新调整特征,使其平均值 ($\mu$) 为 0,标准差 ($\sigma$) 为 1。它从每个数据点中减去特征的平均值,然后除以标准差。公式如下: $$ x' = \frac{x - \mu}{\sigma} $$ 这里:$x$ 是原始值。$\mu$ (mu) 是特征值的平均值。$\sigma$ (sigma) 是特征值的标准差。$x'$ 是标准化后的值。生成的标准化值(常被称为Z分数)表示原始值与平均值相差多少个标准差。与归一化不同,标准化不将值限制在特定范围(例如 [0, 1]),不过,如果原始数据大致遵循正态分布,则远离0的值将不那么常见。例子: 使用相同的“年龄”特征 [20, 25, 40, 60]。平均值 $\mu = (20 + 25 + 40 + 60) / 4 = 145 / 4 = 36.25$标准差 $\sigma \approx 16.52$ (计算涉及方差,即与平均值之差的平方的平均值)应用公式:对于年龄 20: $(20 - 36.25) / 16.52 \approx -0.98$对于年龄 25: $(25 - 36.25) / 16.52 \approx -0.68$对于年龄 40: $(40 - 36.25) / 16.52 \approx 0.23$对于年龄 60: $(60 - 36.25) / 16.52 \approx 1.44$ 标准化后的“年龄”值约为 [-0.98, -0.68, 0.23, 1.44]。优点: 标准化受异常值的影响远小于归一化。如果存在异常值,标准化通常表现更好,因为与最小值和最大值相比,平均值和标准差受极端值的影响较小。假设数据以零为中心的算法也偏好使用标准化。缺点: 结果值不限于特定范围,这可能是某些特定算法的要求(尽管这种情况较少见)。{"layout": {"title": "缩放对“年龄”特征的影响", "yaxis": {"title": "缩放类型", "tickvals": [1, 2, 3], "ticktext": ["原始", "归一化", "标准化"], "range": [0.5, 3.5]}, "xaxis": {"title": "值", "zeroline": false}, "height": 250, "width": 600, "margin": {"l": 100, "r": 20, "t": 50, "b": 40}}, "data": [{"name": "原始", "x": [20, 25, 40, 60], "y": [1, 1, 1, 1], "mode": "markers", "marker": {"color": "#4263eb", "size": 10}, "showlegend": false}, {"name": "归一化", "x": [0, 0.125, 0.5, 1.0], "y": [2, 2, 2, 2], "mode": "markers", "marker": {"color": "#12b886", "size": 10}, "showlegend": false}, {"name": "标准化", "x": [-0.98, -0.68, 0.23, 1.44], "y": [3, 3, 3, 3], "mode": "markers", "marker": {"color": "#f76707", "size": 10}, "showlegend": false}]}该图对比了原始的“年龄”值,以及它们如何通过归一化(映射到 [0, 1])和标准化(以0为中心,单位标准差)进行转换。应选择哪种方法?没有唯一的最佳答案,选择通常取决于你计划使用的算法和数据的性质:归一化(最小-最大) 当你需要数据处于有界区间(例如,[0, 1])时,或者当数据分布不是高斯分布(非钟形)时,这种方法很有用。K近邻等算法有时会从归一化数据中受益。标准化(Z分数) 通常在数据遵循高斯分布(或接近高斯分布)时更受偏爱。它对异常值不那么敏感,并且是支持向量机(SVM)、逻辑回归、线性回归和主成分分析(PCA)等算法所要求或推荐的。在实际应用中,除非你有特定理由使用归一化,否则标准化通常是默认的选择。还值得注意的是,一些算法,特别是基于树的方法,如决策树和随机森林,本身对特征的尺度不敏感,因此不严格要求进行缩放,不过应用缩放通常也不会损害性能。当你开始使用机器学习库(如Python中的Scikit-learn)构建模型时,你会找到便捷的工具,可以轻松地将这些缩放方法应用于你的数据集。请记住,仅在训练数据上拟合缩放器(计算最小值/最大值或平均值/标准差),然后使用这个拟合好的缩放器来转换你的训练和测试数据,以避免数据泄露(在预处理阶段从测试集学习信息)。特征缩放是准备数据中一个简单而重要的步骤,它能帮助许多算法更有效地学习,并防止值较大的特征过度影响结果。