特征工程是什么?首先我们来说一说特征。特征是数据中抽取出来的对结果预测有用的信息,可以是文本或是数据。特征工程是使用专业背景知识和技巧处理数据,使得特征能在机器学习算法上发挥更好的作用的过程。过程包含了特征提取、特征构建、特征选择等模块。特征工程的目的筛选出更好的特征,获取更好的训练数据。因为好多特征具有更强的灵活性,可以用简单的模型做训练,更可以得到优秀的结果。在互联网公司里,其实大部分复杂的模型是极少数的数据科学家在做,大多数工程师们做的事情基本上是从数据仓库里搬砖,不断进行数据清洗,不断寻找特征。总而言之,特征工程没有定式方法,它和现实场景非常贴近,在不同的场景中有不同的特征,抽取方式上可能有共性,在A场景中的特征可能有用但在B场景上可能没用。
下面我们分三个步骤进行介绍:
一、数据采集、数据清洗、数据采样
数据采集:数据采集要求知道哪些数据对最后的结果预测有帮助,某些数据是否能够采集得到,线上实时计算时是否能快捷获取等等。同时,基础的一步是将数据格式化,即确定存储格式,以便后续数据处理和使用。
数据清洗:数据清洗是很重要的一步,也是相对耗时的一步,数据是否处理得当对之后的预测有很大的影响,它需要我们对当前业务理解非常透彻。数据清洗树妖是去除脏数据(不符合常理的)、缺失数据的补齐等。丢掉不可信样本,缺失值较多的字段考虑不用。
数据采样:很多情况下,正负样本存在不均衡问题,大多数模型对正负样本比是敏感的,以及采样方式(随机采样和分层采样),这些对后期结果预测都是有影响的。
正负样本不平衡处理的办法主要分为两类:
(1)正样本远远大于负样本,且量都不大时,我们一般进行下采样;
(2)正样本远远大于负样本,量不大的时候,我们需要采集更多的数据,或进行上采样,或者修改损失函数。
二、特征处理:
(1)数值型
方法:幅度调整/归一化、Log等变化、统计值(max、min、mean、std)、离散化、Hash分桶、每个类别下对应的变量统计值histogram(分布),也可以将数值型转化为类别型。
幅度调整:
from sklearn import preprocessing
import numpy as np
X_train = np.array([[1.,-1.,2.],
[2.,0.,0.],
[0.,1.,-1.]])
min_max_scaler = preprocessing.MinMaxScaler()
X_train_minmax = min_max_scaler.fit_transform(X_train)
print X_train_minmax
结果:
[[ 0.5 0. 1. ]
[ 1. 0.5 0.33333333]
[ 0. 1. 0. ]]
归一化:
X_train = np.array([[1.,-1.,2.],
[2.,0.,0.],
[0.,1.,-1.]])
X_scaled = preprocessing.scale(X_train)
print X_scaled
结果:
[[ 0. -1.22474487 1.33630621]
[ 1.22474487 0. -0.26726124]
[-1.22474487 1.22474487 -1.06904497]]
统计值:
(2)类别型
方法:one-hot编码(可以把没有大小关系的变成多个字段)、哑变量、Hash与聚类处理、统计每个类别变量下各个target比例,转成数值型
(3)日期型
时间可以看做连续值,也可看做离散值。
(4)文本型
词袋:文本数据预处理后,去掉停用词,剩下的词组成的list在词库中的映射稀疏向量。也可将词袋中的词扩充到n-gram。一般使用的是TF-IDF特征。
(5)统计特征
一般会用到:加减平均、分位线、次序、比例
(6)组合特征
分简单组合特征(拼接型)和模型特征组合(用GBDT产生组合路径、组合特征和原始特征一起放进LR训练)
三、特征选择
需要进行特征选择的原因:特征存在冗余和噪声。部分特征的相关性太高,造成了特征冗余,消耗计算性能;部分特征对预测结果有副作用,即为噪声。
我们需要区别特征选择和降维的不同。特征选择只会去除掉原本特征里和结果预测关系不大的特征,降维做特征的计算组合构成新特征。SVD或PCA的降维能解决一定的高纬度的问题。
特征选择我们通常从三个方向出发:过滤型、包裹型、嵌入型
过滤型:
(1)评估单个特征和结果值之间的相关程度,排序留下Top相关的特征部分;
(2)Pearson相关系数,互信息,距离相关度
缺点:没有考虑到特征之间的关联作用,可能吧有用的关联特征误删了。
过滤型一般选择的Python包:SelectKBest、SelectPercentile、GenericUnivariateSelect。(sklearn.feature_selection)
包裹型:
(1)把特征看做一个特征子集搜索问题,筛选各种特征子集,用模型评估效果。典型的包裹型算法为“递归特征删除算法”(recursive feature elimination algorithm)
(2)比如用逻辑回归,怎么做这个事情呢?
1)用全量特征跑一个模型;
2)根据线性模型的系数(体现相关性),删掉5-10%的弱特征,观察准确率/auc的变化;
3)逐步进行,直至准确率/auc出现大的下滑停止。
Python包:sklearn.feature_selection.RFE
嵌入型:
(1)根据模型来分析特征的重要性;
(2)最常见的方式用正则化方式做特征选择。
Python包:feature_selection.SelectFromModel