机器学习之特征工程

做了一段机器学的东西,一直对特征这块很模糊,有时候凭感觉在找特征,然后做一些简单的变换。这篇文章的目的是系统的讲解特征的获取过程,因为在机器学习的过程中,其实数据特征才是限制模型效果的东西,很重要。
特征是数据中抽取出来的对结果预测有用的信息,可以是文本或者数据。特征工程是使用专业背景知识和技巧处理数据,使得特征能在机器学习算法上发挥更好的作用的过程。过程包含了特征提取、特征构建、特征选择等模块

机器学习之特征工程

一、数据的准备过程: 包括数据采集、清洗、采样
1,数据采集:数据采集前需要明确采集哪些数据,一般的思路为:
- 哪些数据对最后的结果预测有帮助?
- 数据我们能够采集到吗?
- 线上实时计算的时候获取是否快捷?

2,数据清洗: 数据清洗就是要去除脏数据,就是对有问题的数据进行预处理。(在特征处理的时候会对空值等进行处理,这里主要是对一些不合理的数据先处理掉,比如一个有33天),* 常用的异常点检测算法包括*
- 偏差检测:聚类、最近邻等
- 基于统计的异常点检测:例如极差,四分位数间距,均差,标准差等,这种方法适合于挖掘单变量的数值型数据。全距(Range),又称极差,是用来表示统计资料中的变异量数(measures of variation) ,其最大值与最小值之间的差距;四分位距通常是用来构建箱形图,以及对概率分布的简要图表概述。
- 基于距离的异常点检测:主要通过距离方法来检测异常点,将数据集中与大多数点之间距离大于某个阈值的点视为异常点,主要使用的距离度量方法有绝对距离 ( 曼哈顿距离 ) 、欧氏距离和马氏距离等方法。
- 基于密度的异常点检测:考察当前点周围密度,可以发现局部异常点,例如LOF算法

3,数据采样:采集、清洗过数据以后,正负样本是不均衡的,要进行数据采样。采样的方法有随机采样和分层抽样。但是随机采样会有隐患,因为可能某次随机采样得到的数据很不均匀,更多的是根据特征采用分层抽样。

二、特征构造:就是从原始的数据中构造特征集,原始数据可能是时间戳、文本、图片、音频等。我们需要从这些数据中构建特征集。下面介绍主要的特征构建方法。

1,对数值型数据:
(1)无量纲化:在对于非tree base 的模型,对数据的规格要求其实是很高的,这就需要无量纲化各个维度的数据。常用方法:归一化(StandardScaler类,本文所用到方法全是sklearn中的)、最大最小区间缩放(MinMaxScaler类)、正则归一化(Normalizer类)
(2)统计值:包括max, min, mean, std等。对数据计算的统计值也可以作为特征,只要与问题有关。
(3)离散化: 也就是分箱/分区操作,把连续值转成非线性数据,比如成绩可以分为A、B、C三等,也可以理解为把数据分成类别。常用对定量特征二值化(Binarizer类)。

2,对类别型数据: 对于类别型数据不能用数值表示。(比如颜色{红、绿、蓝},数字1、2、3可以表示,但是颜色本身没有数学关系,这会误导我们的数学模型)。常用的方法是热编码-(one-hot方法)(OneHotEncoder类)

3,对时间戳数据: 很多任务与时间维度有关系,比如用电量等,此时要将时间戳数据转换为时间特征。常见的转换有:
(1)day of weak(一周的星期几)、day of month、day of year、week of year、month of year、hour of day、minute of day 、哪个季度。
(2)t_m24(前一天的数值)、t_m48(前两天的数值)等。
(3)tdif(与亲一天的数值的差值)等。

4,对文本数据:
(1)词袋:本数据预处理后,去掉停用词,剩下的词组成的list,在词库中的映射稀疏向量。Python中用CountVectorizer处理词袋。 也就是考虑某个词在当前训练样本中出现的频率
(2)使用TF-IDF特征:TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。TF(t) = (词t在当前文中出现次数) / (t在全部文档中出现次数),IDF(t) = ln(总文档数/ 含t的文档数),TF-IDF权重 = TF(t) * IDF(t)。自然语言处理中经常会用到。(考虑到了这个词语是不是在大部分文件都出现了,即包含这个词语的文本条数的倒数,这种词语一般没有什么作用,排除掉常用词语的干扰)

5,计算统计特征: 很多时候统计特征对问题很有帮助,统计的内容包括加减平均、分位线、次序型、比例类等。

6,组合特征:
(1)拼接型:简单的组合特征。就是把多个特征组合成一个(男人喜欢打篮球:就是把男人,喜欢打篮球和在一起了)
  - user_id&&category: 10001&&女裙 10002&&男士牛仔
  - user_id&&style: 10001&&蕾丝 10002&&全棉  
(2) 模型特征组合:
  - 用GBDT产出特征组合路径
  - 组合特征和原始特征一起放进LR训练

7,缺失特征处理: 对于缺失特征可以修改成新的特征,也可以删除,常用有:
(1)删除:最简单的方法是删除,删除属性或者删除样本。如果大部分样本该属性都缺失,这个属性能提供的信息有限,可以选择放弃使用该维属性;如果一个样本大部分属性缺失,可以选择放弃该样本。虽然这种方法简单,但只适用于数据集中缺失较少的情况。
(2) 统计填充:对于缺失值的属性,尤其是数值类型的属性,根据所有样本关于这维属性的统计值对其进行填充,如使用平均数、中位数、众数、最大值、最小值等,具体选择哪种统计值需要具体问题具体分析。另外,如果有可用类别信息,还可以进行类内统计,比如身高,男性和女性的统计填充应该是不同的。
(3) 统一填充:对于含缺失值的属性,把所有缺失值统一填充为自定义值,如何选择自定义值也需要具体问题具体分析。当然,如果有可用类别信息,也可以为不同类别分别进行统一填充。常用的统一填充值有:“空”、“0”、“正无穷”、“负无穷”等。
(4) 预测填充:我们可以通过预测模型利用不存在缺失值的属性来预测缺失值,也就是先用预测模型把数据填充后再做进一步的工作,如统计、学习等。虽然这种方法比较复杂,但是最后得到的结果比较好。

8,特征转换: 对已有的特征做变换,产生新的特征。常见的数据变换有基于多项式的、基于指数函数的、基于对数函数的。4个特征,度为2的多项式转换公式如下:
机器学习之特征工程

三、特征选择:
当数据预处理完成后,我们需要选择有意义的特征输入机器学习的算法和模型进行训练。原始的特征可能有冗余(两个特征说的是一个问题,相关性太强)、噪声(会影响问题的效果)。通常来说,从两个方面考虑来选择特征:

特征是否发散:如果一个特征不发散,例如方差接近于0,也就是说样本在这个特征上基本上没有差异,这个特征对于样本的区分并没有什么用。
特征与目标的相关性:这点比较显见,与目标相关性高的特征,应当优选选择。除方差法外,本文介绍的其他方法均从相关性考虑。

1,filter(过滤法)方法:评估单个特征和结果值之间的相关程度, 排序留下Top相关的特征部分。 评价方式: Pearson相关系数, 互信息, 距离相关度。 缺点:只评估了单个特征对结果的影响,没有考虑到特征之间的关联作用, 可能把有用的关联特征误踢掉。因此工业界使用比较少。

(1)方差选择:计算各个特征的方差,然后根据阈值,选择方差大于阈值的特征。使用feature_selection库的VarianceThreshold类。
(2)相关系数法:计算各个特征对目标值的相关系数以及相关系数的P值。用feature_selection库的SelectKBest类结合相关系数来选择。
(卡方检验是检验定性自变量对定性因变量的相关性,互信息是评价定性自变量对定性因变量的相关性,可以用这两个值和SelectKBest类来选择)

2,wrapper(包裹法): 方法:把特征选择看做一个特征子集搜索问题, 筛选各种特 征子集, 用模型评估子集特征的效果。 典型算法:“递归特征删除算法”,应用在逻辑回归的过程:
a.用全量特征跑一个模型;
b.根据线性模型的系数(体现相关性),删掉5-10%的弱特征,观察准确率/auc的变化;
c.逐步进行, 直至准确率/auc出现大的下滑停止。
(python中是RFE类)

3,嵌入法: 方法:根据模型来分析特征的重要性,最常见的方式为用正则化方式来做特征选择。(这种方式在工业界很常用)
(1)基于惩罚项的方法:就是用L1,L2正则化来做特征选择。L1正则有截断效应:不重要的特征的参数权重为0,L1正则方法具有稀疏解的特性,因此天然具备特征选择的特性,但是要注意,L1没有选到的特征不代表不重要,原因是两个具有高相关性的特征可能只保留了一个,如果要确定哪个特征重要应再通过L2正则方法交叉检验;;L2正则有缩放效应:拿到手的特征都比较小。SelectFromModel类来解决。

(2)基于树模型的特征选择法:树模型中GBDT也可用来作为基模型进行特征选择,使用feature_selection库的SelectFromModel类结合GBDT模型。

四、特征降维: 当特征选择完成后,可以直接训练模型了,但是可能由于特征矩阵过大,导致计算量大,训练时间长的问题,因此降低特征矩阵维度也是必不可少的。常见的降维方法除了以上提到的基于L1惩罚项的模型以外,另外还有主成分分析法(PCA)和线性判别分析(LDA),线性判别分析本身也是一个分类模型。PCA和LDA有很多的相似点,其本质是要将原始的样本映射到维度更低的样本空间中,但是PCA和LDA的映射目标不一样: PCA是为了让映射后的样本具有最大的发散性;而LDA是为了让映射后的样本有最好的分类性能。所以说PCA是一种无监督的降维方法,而LDA是一种有监督的降维方法。(这在python都有相应的方法)
(降维是进行特征的变换和映射产生了不同的维度更小的特征,二特征选择是在原始的特征中选择有意义的特征,并没有产生新的特征)

备注:
1,特征处理完后,就应该进行模型训练和模型选择,模型的训练可以用sklearn或者很多其他机器学习的包做,模型的选择可以参考:
sklearn超参数选择:
http://blog.csdn.net/u014248127/article/details/78938561
sklearn中的交叉验证与参数选择:
http://blog.csdn.net/u014248127/article/details/78899195

2,本篇文章中的代码实现可以参考:使用sklearn做单机特征工程
http://www.cnblogs.com/jasonfreak/p/5448385.html