数值型特征的处理——归一化和分桶
数值型特征需要处理特征的尺度以及特征的分布问题。
特征尺度通常采用归一化方法进行处理。
归一化虽然能够解决特征取值范围不统一的问题,但无法改变特征值的分布。通常可以采用分桶的方式来解决特征值分布极不均匀的问题。
所谓分桶(Bucketing)就是将样本按照某特征的值从高到低排序,然后按照桶的数量找到分位数,将样本分到各自的桶中,再用桶 ID 作为特征值。
在 Spark MLlib 中,分别提供了两个转换器 MinMaxScaler 和 QuantileDiscretizer,来进行归一化和分桶的特征处理。
对于数值型特征的处理方法远不止于此,在经典的 Youtube 深度推荐模型中,我们可以看到一些很有意思的处理方法。比如,在处理观看时间间隔(time since last watch)和视频曝光量(previous impressions)这两个特征时,Youtube 模型对它们进行归一化后,又将它们各自处理成了三个特征,分别是原特征值 x,特征值的平方 $x^2$ 以及特征值的开方,这是为什么呢?
其实无论是平方还是开方操作,改变的还是这个特征值的分布,这些操作与分桶操作一样,都是希望通过改变特征的分布,让模型能够更好地学习到特征内包含的有价值的信息。但是由于我们没法通过人工的经验判断到底哪种特征处理方式更好,所以索性把它们都输入模型,让模型自己来做选择。
这里想说的是:特征处理没有标准答案,不存在一种特征处理方式一定好于另外一种。在实践中,我们需要多进行一些尝试,找到那个最能够提升模型效果的一种或一组处理方式。
问题:
对训练数据进行平方或者开方操作,是为了改变训练数据的分布。训练数据的分布被改变以后,训练出来的模型岂不是不能正确拟合训练数据了吗?
答案:
这是个好问题,但不应该这样理解,本质上是改变了特征的分布,特征的分布和训练数据的分布没有本质的联系。只要你不改变训练数据 label 的分布,最终预测出来的结果都应该是符合数据本身分布的。因为你要预测的是 label,并不是特征本身。