查看原文
其他

Python数据科学:全栈技术详解5-特征工程(下)

作者:Ben,多本数据科学畅销书作家,先后在亚信、德勤、百度等企业从事电信、金融行业数据挖掘工作。

配套学习教程:数据科学实战:Python篇 https://edu.hellobi.com/course/270


  前文传送门:

  Python数据科学:全栈技术详解1-个人贷款违约预测模型

  Python数据科学:全栈技术详解2-客户分群

  Python数据科学:全栈技术详解3-长尾理论

  Python数据科学:全栈技术详解4-推荐算法

  Python数据科学:全栈技术详解5-特征工程(上)


5.3 特征构造(Feature Construction)

特征构造指的是从原始数据构造新特征的处理过程,一般需要根据业务分析,生成能更好体现业务特性的新特征,这些新特征要与目标关系紧密,能提升模型表现或更好地解释模型。

特征构造需要花费大量的时间思考业务逻辑与探索业务数据,因此,往往需要手工创建。由于业务的多样性,以及人们认知业务逻辑的差异性,因此特征构造也相应地具备灵活性与艺术性的特点。如果说数据分析是科学与艺术的有机结合,那么其中的“艺术”便在特征构造上得以集中体现。

我们为上书中的用户账单构造新的特征,目的是为了预测用户是否会流失(churn),思路及需要生成的新特征如下:

(1)用户入网时长(duration):用户的入网时长(join_time)是时间类型的,在分类模型中无法直接使用,可以将它变换为入网时长。一般来说,入网时长越短的用户越有可能频繁换卡(即便换的是同一家服务商,服务商仍然要为此付出成本),流失可能性高。随着入网时长的增加,用户更换手机卡的成本越高(主要是社会成本),因此流失的可能性会越低。同时受到终端合约(指用户承诺在网一定时间,一般是两年,运营商对用户购买终端的费用进行补贴)的影响,入网两年左右的用户离网率会出现一个高峰。因此入网时长可能会在模型当中起到重要作用;

(2)实际流量单价(unit_price):由于套餐资费差异与消费行为的差异,实际上每个用户的实际流量单价是不同的。部分用户会将套餐内流量消费完,有些则用不完,所以套餐内标注的流量单价或超套餐后的流量单价不能代表用户消费的实际流量单价。实际流量单价高意味着用户超套餐消费很多(因为套餐外消费单价高)或者实际消费远低于套餐量(因为套餐本身与其消费习惯不符)。由此可见,实际流量单价高的用户更有理由转网或转套餐。事实上,完全可以将“实际流量单价”与“套餐内消费比(指用户消费量与套餐内给定量的比)”这两个特征都构造出来,并在后续的特征筛选中进行选择;

(3)TAC:手机串号IMEI的前6位被称为TAC号,指示了终端的品牌类型,可以通过连接外部数据将终端的价格、制式连接进来,这些指标对于用户的流失有可能具有一定的价值,因此需要进行一定的转换构造该特征。另外,IMEI本不在账单中,可以通过其他数据源引入。

根据上述分析,对数据集操作如下:


本例中计算是简化处理,鉴于0流量与0消费额的用户存在,应当定义更复杂的运算逻辑提升健壮性。

从处理方法上看,特征构造仍然是对数据的变换,其目的在于将业务专家的经验和智慧融入到分析中。而在数据预处理当中也需要做一些基本的数据变换,但预处理当中的数据变换更多是为了满足模型对训练数据类型、格式的基本要求。

特征工程的指导依据是本专业领域的方法论。比如构个人建信用评分,专家会关心个人基本信息、个人的社会经济状态、信用历史等信息,而业务人员也会关系客户的交易信息,因此这个模型的变量构造如下:

 

上图也只是对变量维度进行了示例,实际建模不会将这些变量直接放入模型,比如“账户余额”代表客户的负债能力,“贷款金额”代表其负债负担。将“账户余额除以贷款金额”放入模型比直接把两个原始变量放入模型的解释力要好。

特征构造没有一个统一的标准,要深入每个专业的业务领域。比如对公司盈利能力建模,可以借鉴杜邦分析、财务比率分析的已有模型;对个人进行精准营销建模,可以参考微观经济学和计量经济学中的效应模型。特征工程庞杂而艰难,非数据挖掘工程师的业务领域,要在这方面有所建树,需要把自己培养成业务专家。

5.4 特征抽取(Feature Extraction)

特征抽取指的是从原始数据抽取新特征,这种“抽取”可以使用一定的算法来自动执行,抽取的目的是将多维的或相关的特征降低到低维,以提取主要信息或生成与目标相关性更高的信息。

一般的结构化商业数据已经可以包括成百上千个维度的特征,而对于图像、音频和文本这些非结构化数据,通过转换可以很轻易地包括数以百万计的属性,这会导致计算量大,训练时间长。另外,常用的模型不能接受如此之多的特征,尤其在大量特征互相关联的情况下,这会影响模型的泛化能力。因此,特征提取自动减少这些类型到一个更小的集,达到可以建模的维数。

对于结构化数据,常用的特征提取方法包括投影方法(如主成分分析法、线性判别分析等)、无监督聚类等。

(1)主成分分析法(PCA,即Principal Component Analysis)

当随机变量两两之间具有较强的线性相关时,它们包含了比较多的共同信息,如果将共有的信息提取出来,而不损失过多原变量的信息,则可以达到简化问题的目的。

主成分分析法认为,数据变异最大的方向上包含了最大的信息。基于这样的认识,主成分分析法寻找多维数据当中变异最大的且正交的几个方向(通常要小于原始特征的维数),将特征投影到这几个方向形成的空间当中,这样可以保留数据的多数变异,而将变异较小的剩余方向忽略,并以投影后的数据作为新特征,如图18-3所示。

 

图18-3

图中的二维数据在某个方向上有最大的变异,因此将其投影到该方向上,以投影的坐标点作为新特征的值,这样就将二维的数据降到了一维,同时忽略掉了数据剩余的变异,从而达到抽取共同信息的目的。

在多维数据当中也是如此,先寻找数据变异最大的方向,然后在该方向的所有正交方向上寻找剩余变异最大的方向,以此类推,这些“方向”被称为主成分,以向量的形式表示。然后按照各主成分方向可解释的数据变异的多少来决定要保留几个主成分,最后将数据投影到主成分上形成新的得分(坐标值),该值就是新的特征值。例如对于经过数据预处理后的消费额、通话时长、流量三个特征,使用主成分法提取三个主成分的示例如下:

 

PCA被初始化为保留两个主成分(n_components=2),然后用生成的训练器训练(fit)并转换(transform)数据集,最后得到两组新的主成分得分,就是降维后的新特征。其中用于训练的数据集和要转换的数据集是同一个集合时,可以使用fit_transform方法一次性进行变换。

每个主成分能解释的数据变异比率如下:

 

可见第一个主成分方向能解释原始数据85.8%的变异,第二个主成分能解释9.2%的变异,两个主成分共同解释了原始数据95%的变异,相当于仅丢弃了5%的“信息”就将数据从三维降到了两维。这可以看做是将三维空间中分布的数据,投影到二维平面当中形成的新特征。

选择保留多少个主成分取决于这些主成分能解释的数据变异比率是否达到设计标准(例如80%),并且任意一个单独主成分能解释的变异量不低于标准值1,当然这两个选择标准可以根据业务需要适度放宽松。查看主成分解释的变异量的示例如下:

 

可见第二个主成分能解释的变异量低于1,因此可以判断保留一个主成分就可以了(只保留第一个新特征,或者将n_components设为1重新进行计算),这样可以将数据降到一维,并且保留85.8%的数据变异。

用于投影的方向如下:

 

第一个主成分向量与记录行做点积(投影)就可以得到第一个主成分的得分(新特征当中的第一列),第二个主成分向量与记录行做点积(投影)可以得到第二个主成分得分(新特征当中的第二列)。更简便的方法是用模型的transform方法来转换,比如对于有两条记录的测试集进行pca转换如下:

 

此外,一个方向可以由无穷多个向量来表示(只是长度不同),因此不同工具采用不同算法得出来的主成分向量可能在长度上是有差异的,导致投影结果也有差异,它们之间其实仅相差一个伸缩的比例而已。

关于主成分分析的更多详细算法可见前面章节。

(2)线性判别分析(LDA,即Linear Discriminant Analysis)

线性判别分析也称Fisher线性判别(FLD,即Fisher Linear Discriminant),它通过将数据投影到具有最佳分类性能的方向,而达到降维的目的。线性判别分析是一类有监督的学习方法。

以图18-4为例,空心点代表正例,实心点代表负例,使正负例能够尽量分离的投影方向,就是线性判别分析要寻找的方向,在这个方向上的投影坐标就是实例的新特征。

 

图18-4

由图18-4可见,线性判别分析适用于数据(近似)线性可分的情况,如果数据不是线性可分的,则可以应用核方法(kernel)进行处理。

本节仅讨论数据是(近似)线性可分,且目标变量为二分类的情况。

假设原始的多维特征用向量表示,目标变量是二分类的,每类的样本量分别是N1和N2,具有最佳分类性能的投影方向为,投影后的特征是y,则每个分类下的原始特征的中心分别为:


投影后各类的中心分别为:


投影后各类的方差分别为


为了使得投影后的特征具有最佳分类性能,需要使投影后的样本在新的子空间有尽量大的类间差异和尽可能小的类内差异,也就是要尽可能最大化目标函数,能够使该函数达到最大值的就是我们要求的投影方向。

线性判别分析的特点在于计算简便,适用多分类,在实践中被证明是有效的,而且没有超参(这里超参是指未知参数的参数)。当目标变量为二分类时,线性判别分析一般将数据投影到一维,示例如下:

 

目标变量设定为用户是否流失"churn",原始特征是之前经过变换了的消费额、通话时长、流量,数据被降到了一维。如果要预测分类结果,只需对新特征设定一个阈值,阈值两边的数据点分别为正例和负例就可以了。

用于投影的方向WT如下:

 

对于新的测试集,可以使用WT与其进行点积就可求得新特征值。更简便的方法是使用模型直接进行转换,例如:

 

这个结果与使用WT进行点积运算的结果相差一个缩放的系数而已。

从LDA的原来来看,显然除了降维,它也可以直接用于预测,例如:

 

由结果可见,预测的正确率为78.8%。

从计算公式来看,线性判别分析是强依赖于均值的,如果分类间的均值相差不大,或者均值不能很好地代表各类的概率分布,则效果一般。因此线性判别分析比较适合高斯分布的分类。

线性判别分析和主成分分析有很多的相似点,其本质是要将原始的样本映射到维度更低的样本空间中,但是线性判别分析和主成分分析的映射目标不一样:主成分分析是为了让映射后的数据具有最大的发散性,而线性判别分析是为了让映射后的数据有最好的分类性能;主成分分析是一种无监督的降维方法,而线性判别分析是一种有监督的降维方法。

5.5 特征选择(Feature Selection)

数据集当中的特征并不都是“平等”的,许多与问题无关的特征需要被移除掉,而有些特征则对模型表现影响很大,应当被保留,因此需要对特征进行一定的选择。

特征选择方法可以分为过滤法、包装法和集成法。

5.5.1过滤法(Filter)

过滤法是比较简单的特征选择方法,根据每个特征的统计特性,或者特征与目标值的关联程度进行排序,去掉那些未达到设定阈值的特征。常用的过滤法包括方差过滤、基于统计相关性的过滤,以及基于互信息的过滤等。

(1)方差过滤

方差过滤认为,数据的信息取决于其变异程度的大小。例如对于“太阳是否从东方升起”这一字段,其所有的取值为“是”,数据无任何变异(对应变量值的方差为0),这样的数据是没有信息量的;而对于“太阳黑子活动强度”这样的字段,其数据变异相对较大,这其中可能包含了人们想了解的信息,而且数据变异越大,其包含的信息越多,越应当被保留下来。

对于只有两个分类水平的伯努利(Bernoulli)变量,如果其中一类非常少(对应概率P较大),则该变量几乎全为另一类值,那么这个变量所包含的信息量就比较低。例如“vip”字段,因为几乎全部为0,vip用户对于模型几乎没有影响,因此不应入选。

假如设定概率的阈值为10%,(两个分类水平都要超过10%)才达到入选模型的要求,则对应的方差为p(1-p)=0.09,可以使用下面的示例进行筛选:

 

可见"vip"这一字段被筛掉,保留了"has_IMEI"。计算出的各变量方差为:

 

(2)基于统计相关性的过滤

当关注目标变量时,特征筛选会更有目的性,因此可以通过观察各个特征与目标变量的关联程度来进行特征选择,根据不同的目标变量与待选特征(连续变量或者离散变量),会用到不同的相关性分析方法,因此,先将待选特征与目标变量按照类型进行划分,示例如下:

 

其中后缀categorical代表这是离散变量,continuous代表连续变量。

①卡方检验

xy均为离散变量时,可以使用卡方检验判断它们的关联性。例如要对数据集做分类预测,y为离散变量,则可以进行如下操作:

 

返回的列表表示x的每个离散变量与y离散变量卡方检验得到的卡方值和P值。

在选择的"vip","state","has_IMEI"三个特征当中,"vip"的卡方检验统计量为8.15,对应p值为0.0043,其它两个变量的P值更小,几乎可以排除每一个特征“与目标变量互相独立”的这种可能性,因此可以全部予以保留。如果非要在当中筛掉一个“最不独立”的,也可以使用feature_selection模块当中的SelectKBest,示例如下:

 

想要了解删除的特征是什么,可以如下操作:

 

返回的数组对应特征的掩码,即删除了第一个特征(对应False),保留了后两个特征(对应True)

②ANOVA

当目标变量是离散的,而自变量是连续变量时,可以使用t检验或ANOVA方差分析进行变量筛选,例如对于分类问题,示例如下:

 

代码返回了二维数组,第一行代表t统计量,第二行代表对应的p值。

可以发现最后一个变量"duration"的p值只有0.0077,因此它与目标变量不独立,而其它变量的p值更小,因此可以判断它们与目标变量是各自都是相关的。

如果非要选择p值最低的变量保留下来,可以如下操作:

 

③相关系数

对于x和y均为连续变量的,可以使用相关系数来判断它们之间关联程度的大小,例如我们对数据做回归分析,使用消费量和在网时长估计消费额,则可以用如下方式进行变量筛选:

 

返回的二维数组中,第一行是用于检验相关系数的统计量(非相关系数本身),第二行是对应的P值。

因为在自变量中保留了消费额,它与自己毫无疑问是完全相关的,相关系数显著性检验P值最大,为1,其余都很小。这里面虽然x中包括了消费额,但并不影响方法的使用,因为利用统计相关性进行筛选是针对一个个自变量单独进行的。

同样的,删选变量可以使用SelectKbest:

 

如果要查看保留的是哪些特征,可以使用get_support(与①卡方检验一样)。 

5.5.2包装法(Wrapper)

包装法与过滤法不同,过滤法通过一个个的判断x的统计特性,或者与y的关联性进行筛选,这样做可能会错过那些多个变量在一起才能显出与目标相关性的特征。比如,用户的通话时长与消费额可能没有显著关联,流量消耗也可能与消费额没有显著关联,但它们合起来能很好地将消费额预测出来。

因此,包装法不单看x与y的直接关联,而是从添加这个特征后模型的最终表现好坏来判断添加是否合适。这个方法可以包括前向或后向的特征选择,例如前向法的基本逻辑是这样的:先初始化进入模型的特征为空,然后一次向模型当中添加一个特征,并判断模型效果的提升程度,选择最能提升效果的特征进入模型;依此往复,直到所有剩余特征进入模型都无法带来效果提升为止。后向法则相反,先将特征一次性全部进入模型,再一个一个删去,通过判断哪个特征对模型效果的降低影响最小,则删去;依此往复,直到达到停止条件为止。前向后向法(逐步法)则是对前两种方法的融合,先逐个添加特征直到停止条件,再从中逐个删除达到停止条件,反复应用前向法与后向法,以达到对特征选择的尽可能优化。另外,可以对所有特征取其全部子集,每个子集都进入模型去判断哪个组合效果最佳。但这样的穷举开销很大,虽然它能产生最优的组合,但只能在特征较少时使用。

在feature_selection中,使用RFE(recursive feature elimination)可以用于“迭代的特征消除”,即后向法筛选特征。方法示意如下:

 

其中,需要指定特征进入的模型(本例中是逻辑回归),还需要指定要保留的特征数"n_features_to_select",该参数默认为None,使用默认值时会保留一半的特征。其它可调参数可参见文档。

同理,要获得删除特征的掩码,可以如下操作:


5.5.3集成法(Embedded)

有一些模型算法天然就具备判断一个特征对于模型的效果影响程度,例如决策树类的模型,在模型训练过程中就需要融合特征选择的功能,因此,如果能通过这类模型计算出一个综合的特征重要性排序,则可以用于特征的选择。这样的方法被称为集成法。

例如使用随机森林进行建模,模型会通过计算,返回一个代表特征重要性的数组,示例如下:

 

在结果中,选择重要性高的的特征进入模型就可以了。当然,如果特征比较多,可以采用一些方便手段,例如使用SelectFromModel,示例如下:

 

SelectFromModel需要传入一个可以产生特征重要性的模型,以及特征筛选的阈值,同样也能够产生特征选择的掩码,示例如下:

 

使用随机森林这类树模型,计算效率较高,可以在建模初期对变量进行初步筛选,之后往往还需要手动进一步的细筛特征,因此可以适当多保留一些特征,集成法的主要作用就是为了在初期减少人工工作量。

老师的文章配套免费课程

立刻扫码或点击阅读原文学习吧~

两个是不一样的课程哦~


点击
阅读原文即可免费学习本文配套的Python数据科学实战课程!

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存