Fancy Tricks with Simple Numbers
先看数值数据,比如:
- 个人的定位
- 交易价格
- 一个传感器的数据
- 等等
虽然数值数据本身已经对模型很友好,但是仍然需要特征工程。
好的特征不仅要反映数据的重要方面,还要和模型的假设一致。
数值数据的特征工程是基础,其他原始数据被转换为数值数据后,就可以利用数值数据的特征工程技术。
量纲Magnitude
我有必要知道数据的正负吗?
也许我们只需要知道比较粗粒度的大小?
对于自动累计的数值数据,这一检查很重要:
比如:
- 计数
- 网站每天的访问量
尺度Scale
最大最小的数是多少?
它们跨过很多个数量级吗?
平滑函数模型的输入特征对输入的尺度很敏感。
比如:
- 3 x + 1 3x + 1 3x+1是一个简单的线性模型,输出的尺度直接由输入决定
- k-means clustering
- nearest neighbors methods
- RBF kernels
- 以及任何使用欧几里得距离的模型
对于这些模型或者模型组件,最好对输入特征进行归一化。
- 逻辑函数:0|1
- 依赖space-partitioning trees的模型,包括:decision trees, gradient boosted machines, random for‐
ests;唯一的例外是,当输入随时间增长而增长时,比如累计的计数等
这几个对尺度不敏感
分布
对于某些模型,对于输入特征的分布很敏感。
比如:
- 一个线性回归模型,假定模型输出的误差服从高斯分布;
- 有一个例外,当输出跨过多个数量级的时候,误差将不再服从高斯分布,此时可以将输出进行log变换(这严格意义上属于目标工程的范畴)
多重特征组成复杂特征
将多个特征组合成复杂的特征,有时能够使模型更简单。
比如:
- 最简单的,interaction features
- 为了降低计算成本,用feature selection
Scalars,Vectors,and Spaces
一个单一的数值特征,就是一个标量Scalar;
一个有序的标量列表,就是一个向量;
向量存在于向量空间。
对于大部分机器学习问题,模型的输入都表示为一个数值向量。本书将讨论的就是将原始数据转换为数值向量的最佳实践策略。
对于真实世界的数据,抽象的向量的特征的维度代表了真实的含义;
可以将数据放在特征空间内,相反地,也可以将特征放在数据空间内:
比如:
几个人对几首歌的偏好:其中,1代表点赞,-1代表点👎
Dealing with Counts
在大数据时代,计数可能会累加得非常快,快到没有边界。
数据很有可能包含少数极端的值。
所以很有必要检查数据的尺度,来决定是否保留原始数据,还是说:
- 将数据转换为二值数,来指示是或者不是
- 白原始数据分成更粗的粒度
下面举例说明。
Binarization 二值化
这个数据集
包含了Echo Nest的百万用户收听历史的数据。
- 包括48millions的(user id, song id, listen count)数据
假设我们的任务是构建一个推荐系统来向用户推荐歌曲。
推荐系统的一个组件可能是预测一个用户对特定的一首歌的喜好程度。
也许可以通过listen count来确定,用户喜不喜欢某一首歌:计数越大,则说明用户越喜欢该首歌;反之,计数越小,说明用户对该首歌不感兴趣?
但是,从数据集的情况来看,尽管99%的计数都不大于24,仍然有一些计数以数千记,最大的计数达到了9667。
这些异常大的值,会让模型很迷惑。
每个人的听歌习惯不一样,有些人喜欢随机播放,有些人喜欢单曲循环,有些人喜欢在特定场合下听特定的歌。很难说听了某一首歌24次的用户没有听了1000次的用户喜欢这首歌。
处理的方法就是二值化Binarization:所有listen count>1的用户都标记为1,1就是喜欢。
二值化
特征工程 二值化 Binarization
https://www.deeplearn.me/1389.html
Quantization or Binning 量化或分箱
Yelp数据集包含北美和欧洲10个城市的用户对企业的评论。每个企业都被标记为零或多个类别。
- 有782个商业类别。
- 1.6M的评论和61K的商业
- 餐厅和夜生活从评论计数看是最受欢迎的类别
- 没有一家企业既是餐厅又是夜生活场所。因此,两组评论之间没有重叠。
假设我们的任务是使用协同过滤来预测用户可能给企业的评级。
评论数可能是一个有用的输入特征,因为流行和好的评价之间通常有很强的相关性。
此数据集和前面的听歌数据集类似,跨越了多个数量级。
对于使用欧几里得距离度量相似性的模型,过大的计数会使其他数据的相似度遗失。
一种解决方案是通过量化计数来包含标量。
换句话说,我们将计数分组到容器中,并且去掉实际的计数值。
量化将连续数映射成离散数。我们可以把离散化的数字看作是代表强度度量的容器的有序的序列。
举个直观的例子,好比有一组连续数据,好比为25,14,68,43,63。假设数据的分箱逻辑是大于50为0,小于50为1,那么最终数据会变成1,1,0,1,0,数据就离散化了。
参考
https://www.shangmayuan.com/a/ed9a3119c0614e7d9a54d25b.html
为了量化数据,我们必须决定每一个箱子应该有多宽。解决方案分为固定宽度或自适应两种类型:
固定宽度分箱(等距分箱)
对于固定宽度装箱, 每个 bin 都包含一个特定的数值范围。范围可以是定制设计或自动分割, 它们可以线性缩放或指数缩放。
计数映射到箱子,计数除以箱子宽度取整即可。
当数字跨越多个数量级时,最好用10个幂(或任何常数的幂)来分组:0-9、10-99、100-999、100-9999等。
容器宽度呈指数增长,从O(10)、O(100)到O(1000)和以上。
要从计数映射到bin,取计数的log值。
分位数装箱(等频分箱)
对于固定宽度分箱,如果计数相差很大,就会有很多箱子是空的。
**等频分箱:**保证每一个箱子里的数据个数相同。
- 中位数:将数据分为两份
- 十分位数:将数据分为十份.
分位数
https://baike.baidu.com/item/%E5%88%86%E4%BD%8D%E6%95%B0
为了计算分位数和映射数据到分位数箱,我们可以使用 Pandas 库。 pandas.DataFrame.quantile
和 pandas.Series.quantile
用于计算分位数。pandas.qcut
将数据映射到所需数量的分位数。
Log Transformation
重尾分布
https://blog.csdn.net/dymodi/article/details/54231728
https://www.jianshu.com/p/e498a7151312
log变换处理重尾分布的数据很有效:
功率变换:log变换的的一般化推广
box cox 变换
略
特征缩放或归一化
Min-max缩放
就是归一化
标准化(方差缩放)standardization
缩放后的特征的平均值为0,方差为1。
ps:不要中心化稀疏数据,以上两个缩放,都可以将稀疏特征(大部分值为0)的向量转换为一个稠密的向量。
l2标准化
通过l2范数标准化原始特征:
x ′ = x / ∣ ∣ x ∣ ∣ 2 x'=x/||x||_2 x′=x/∣∣x∣∣2
Interaction Features 交互特征
略
特征选择
- Filtering(过滤)
- Wrapper methods(包装方法)
- Embedded methods(嵌入式方法)
有兴趣的读者可以参考 Isabelle Guyon 和 André Elisseeff 撰写的调查报告“变量和特征选择介绍”(“An Introduction to Variable and Feature Selection”)。