特征衍生基本概念
特征衍生主要指的是通过既有数据进行新特征的创建。总体来说,特征衍生有两类方法,其一是通过深入的数据背景和业务背景分析,进行人工字段合成,这种方法创建的字段往往具有较强的业务背景与可解释性,同时也会更加精准、有效的提升模型效果,但缺点是效率较慢,需要人工进行分析和筛选,称为手工特征衍生。其二则是抛开业务背景,直接通过一些简单暴力的工程化手段批量创建特征,然后从海量特征池中挑选有用的特征带入进行建模,这种方法简单高效,但存在衍生字段过多,有效特征没有衍生的问题,称为批量特征衍生。
特征衍生的相关方法更像是人们在长期实践过程中总结出来的方法论,这些方法切实有效,但没有一套能够完整统一的理论体系来“框住”这些方法。此外由于模型场景的复杂多变,特征衍生需要结合综合数据体量、数据规律、现有算力等因素进行考虑,所以这边主要介绍特征衍生的一些方法。
特征衍生的本质
所谓特征衍生,其本质指的是对既有数据信息的重新排布,手工特征衍生会先从思路出发、再分析数据集当前的业务背景或数据分布规律、最后再进行特征衍生。批量特征衍生优先考虑从方法出发,直接考虑单个列、不同的列之间有哪些可以衍生出新特征的方法,然后尽可能去衍生出更多的特征。
特征衍生方法汇总
批量特征创建的会先考虑如何把特征“做多”,然后再考虑如何把特征“做精”。总的来说,批量特征衍生有如下方法划分:单变量特征衍生、双变量特征衍生、关键特征衍生和多变量特征衍生。
特征衍生准则
通过上述特征衍生方式,只要将这些方法稍作组合,就可以衍生出无限个特征,但因为算力有限、时间有限,我们不可能进行无止尽的尝试。因此,在实际模型训练过程中,也并非无节制的朝向无限特征的方向进行特征衍生,往往我们需要有些判断,即哪些情况下朝什么方向进行特征衍生是最有效的。
单变量特征衍生
数据重编码特征衍生
连续变量数据重编码方法
- 归一化:0-1归一化、Z-Score标准化
- 离散化:等距分箱/等频分箱/聚类分箱
离散变量数据重编码方法
- 字典编码
- one-hot编码
Embedding编码
如何需要对id这种多类型的特征进行编码时,采用one-hot、字典编码会存在极其稀疏的特征矩阵,不利于后续训练处理,针对这类特征可以采用embedding方式进行编码,能够用低维向量对物体进行编码还能保留其含义。
graph Embedding
将id特征采用grap构建,如图b所示,在图b中使用随机游走算法生成一系列的id特征序列,然后运用skip-gram算法生成对应的Embedding的向量表征形式。
高阶多项式特征衍生
对于单独的变量来说,除了可以通过重编码进行特征衍生外,还可以通过多项式进行特征衍生,即创建一些自身数据的二次方、三次方数据等。
双变量特征衍生
在大多数情况下,多个变量的交叉组合往往都比单变量特征衍生更有价值。一般来说,双变量特征衍生是目前常见特征衍生方法中最常见、同样也是效果最好的一类方法,而多变量特征衍生,除了四则运算(尤其以加法居多)的组合方法外,其他衍生方法随着组合的字段增加往往会伴随非常严重的信息衰减,因此该类方法除特定场合外一般不会优先考虑使用。
四则运算特征衍生
该过程非常简单,就是单纯的选取两列进行四则运算,基本过程如下:
该过程并不复杂,实际代码执行过程也只需要单独索引出两列然后进行四则运算即可。一般来说,四则运算特征衍生的使用场景较为固定,主要有以下三个:
- 用于创建业务补充字段:例如用户当天总消费金额,我们甚至可以将其视作原始字段。
- 往往在特征衍生的所有工作结束后,我们会就这一系列衍生出来的新字段进行四则运算特征衍生,作为数据信息的一种补充。
- 在某些极为特殊的字段创建过程中使用,例如竞赛中常用的黄金组合特征、流量平滑特征等,需要使用四则运算进行特征衍生。
交叉组合特征衍生
交叉组合特征衍生,指的是不同分类变量不同取值水平之间进行交叉组合。交叉组合后衍生的特征个数是参数交叉组合的特征的取值水平之积。
在使用时需注意越多的分类特征进行交叉组合、或者参与交叉组合的特征本身分类水平更多,衍生的特征数量也将指数级上涨,无论如何进行衍生,首先我们需要对衍生后的特征规模有基本判断。
分组统计特征衍生
分组统计就是A特征根据B特征的不同取值进行分组统计,统计量可以是均值、方差等针对连续变量的统计指标,也可以是众数、分位数等针对离散变量的统计指标,例如我们可以计算不同时间段用户的平均打车金额、金额最大值、最小值等。
分组统计的注意点:
- 分组统计的字段可以是离散变量也可以为连续变量,进行聚合的字段最好选择离散变量,且最好取值较多。
- 分组统计也不局限于单表,可以通过多表连接后,再进行统计汇总。
- 分组统计完之后,可以将原始特征与衍生特征再进行一次四则运算特征衍生,例如当前打车金额减去平均打车金额,比较当前订单与当前时段平均订单金额差异。
多项式特征衍生
双变量的多项式特征衍生与单变量的多项式特征衍生类似,增加了交叉项的计算,如下图所示:
多项式特征衍生的注意点:
- 双变量多项式衍生只适用于两个连续变量之间,一个连续变量一个离散变量或者两个离散变量进行多项式衍生意义不大。
- 一般来说伴随着多项式阶数的增加,各列数值也会呈现指数级递增(或递减),因此往往我们只会衍生3阶左右,极少数情况会衍生5-10阶。需要配合一些手段来消除数值绝对值爆炸或者衰减所造成的影响,例如对数据进行归一化处理等;
统计演变特征
根据衍生特征再进行进一步的特征衍生,这也是为何会出现无限特征的根本原因之一。不过在大多数情况下,二阶或者是更高阶的特征衍生往往伴随着严重的信息衰减,且计算过程往往需要消耗巨大的计算量。因此,高阶衍生往往性价比较低,除非特殊情况,否则并不建议在广泛特征基础上进行大量高阶特征衍生的尝试。
原始特征与分组汇总特征交叉衍生
最常用的特征衍生方法就是利用原始统计字段和分组统计衍生特征进行交叉衍生,例如之前分组统计得到的不同时间段打车金额,依此为依据,可以进一步构建下列统计演变特征:
- 流量平滑特征
该特征通过原始统计字段除以分组汇总均值后的特征计算而来,因为是进行除法运算,为了避免分母为零的情况,我们可以在分母位上加上一个很小的数,具体计算过程如下:
df['cost'] / (df['mean'] + 1e-5)
- 黄金组合特征
所谓黄金组合特征,就是简单的利用原始特征减去mean计算得出:
df['cost'] - df['mean']
- 组内归一化特征
内归一化特征,指的是用cost减去mean,再除以std,其计算过程非常类似于归一化过程,即某列数据减去该列的均值再除以该列的标准差,这也是组内归一化名称的由来。具体计算过程如下:
(df['cost'] - df['mean']) / (np.sqrt(df['var']) + 1e-5)
分组汇总特征彼此交叉衍生
基于分组汇总统计后的信息再次进行交叉衍生得到的新特征,这类特征往往具有较强的统计背景,能够更好的衡量原始特征的基本分布情况。
- Gap特征
Gap特征通过分组汇总后的上四分位数-下四分位数计算得出。
def q1(x):
"""
下四分位数
"""
return x.quantile(0.25)
def q2(x):
"""
上四分位数
"""
return x.quantile(0.75)
d1 = pd.DataFrame({'x1':[3, 2, 4, 4, 2, 2], 'x2':[0, 1, 1, 0, 0, 0]})
aggs = {'x1': [q1, q2]}
d2 = d1.groupby('x2').agg(aggs).reset_index()
- 数据倾斜
通过中位数和均值的比较来计算组内的数据倾斜情况:当均值大于中位数时,数据呈现正倾斜,均值小于中位数时,数据负倾斜。当然衡量倾斜的方法有两种,其一是计算差值,其二则是计算比值。 - 变异系数
变异系数是通过分组统计的标准差除以均值,变异系数计算的是离中趋势,变异系数越大、说明数据离散程度越高,相关计算过程如下:
np.sqrt(df['var']) / (df['mean'] + 1e-10)
多变量特征衍生
多变量的交叉组合特征衍生
多变量的交叉组合和双变量的交叉组合类似,基本过程如下:
伴随着交叉组合特征数量的增加、以及每个特征取值水平增加,衍生出来的特征数量将呈指数级上涨趋势,例如3个包含两个分类水平的离散变量进行交叉组合时,将衍生出2^3=8个特征。特征矩阵会存在过于稀疏的问题,将极大程度影响后续建模过程。
所以只有在人工判断是极为重要的特征情况下,才会考虑对其进行三个甚至更多的特征进行交叉组合衍生。
多变量的分组统计特征衍生
在双变量分组特征衍生时,我们是选择某个特征为KeyCol(关键特征),然后以KeyCol的不同取值为作为分组依据,计算其他特征的统计量。而在多变量分组特征衍生的过程中,将考虑采用不同离散变量的交叉组合后的取值分组依据,再进行分组统计量的计算。
从直观的结果上来看,多变量分组统计特征衍生能够更细粒度的呈现数据集信息。但这种“细粒度”的呈现并不是越细粒度越好,在相同数据集下,分组越多、每一组的组内样本数量就越少,而在进行组内统计量计算时,如果组内样本数量太少,统计量往往就不具备代表性。
多变量的多项式特征衍生
与双变量的多项式特征衍生类似,具体如下所示:
特征组合自动化能力
DFS
DFS主要处理关系型数据,能够从中自动生成特征。本质上该算法遵循数据中基本字段的关系链路,然后沿该路径依次应用数学函数以创建最终特征。
目前FeatureTools采用该方式来进行自动化特征衍生,featureTools将对应表转化为entity的方式,定义entity之间的关联性,并通过DFS的方式来进行特征生成。
DFS将跨表之间的关联特征称为Ralated feature,将一对一关联的称为forward relation,一对多关联的称为backward relation,如下图如何将order表作为parent表,orders与user之间为forward relation,可直接进行关联;而order与 order products为backward relation,需选择聚合函数进行关联。
通过不同关联方式关联得到parent表后,再对parent表进行单表特征衍生。featuretools递归实现这些操作,也就是自底向上累积计算特征。伪代码如下:
FeatureTool特征构建都是通过人工设计的数据的转换和聚合函数实现的,生成的特征具有更好的可解释性,但是也存在特征维度过多的情况,需要做一些特征筛选的动作。
Beam Search
这个算法的主要思路是先生成一部分二阶组合特征,然后用效果好的二阶组合特征去衍生三阶组合特征,并非生成所有的三阶组合特征。相当于一种贪心的搜索方法。
AutoCross算法应用Beam Search来进行特征衍生:
AutoCross采用多粒度离散化方法来离散化同一个特征,比如特征“年龄”,我们按照年龄间隔为5的离散化一次,年龄间隔为10的离散化一次,年龄间隔为20的再离散化一次,同时生成多个不同的离散化特征,让模型自动去选择最适合它的特征,再采用beam search进行多阶特征衍生。
虽然采用beam search生产特征,但是对应得到的特征还是很多,AutoCross采用逐域对数几率回归(Field-wise LR)算法、连续小批量梯度下降等方式来进行特征筛选。
关键特征衍生策略
在大多数情况下,我们只需要合理使用上述双变量和多变量特征衍生方法,就能快速构建海量新特征,并且通过上述方法构建的特征池往往也都包含了绝大多数的潜在有效特征。对于某些特殊的特征,是无法通过上述自动化特征衍生方法进行更深入的有效信息挖掘,主要包括时序特征和文本特征。
时序特征衍生方法
时序字段分析
所谓的时序特征,其实就是指记录了时间的特征,例如交易发生时间、用户注册时间等,在很多场景下数据集的标签都会具有季节性波动规律,对应到数据集就是用户流失很有可能与季节、月份相关。时序特征衍生的主要方法有两种,详细信息衍生和基于自然周期划分衍生。
时序特征的衍生其本质上就是对特征进行了更多不同维度的分组,而对特征进行分组之所以能够帮助模型进行建模与训练,其根本原因也是因为有的时候,同一组内(或者是多组交叉)的用户会表现出相类似的特性(或者规律),从而能够让模型更快速的对标签进行更准确的预测。
- 时间信息的更细粒度周期划分
假设time是以月为时间跨度进行的记录,则time的取值范围[0, 72]就表示过去6年的时间记录结果,对应的特征衍生方式如下:
- 时序字段的二阶特征衍生
当我们更细粒度的对时序特征进行划分后,接下来我们也可以进一步围绕衍生时序特征和原始特征进行双变量或多变量特征衍生,这也是所谓的时序字段的二阶特征衍生。
时序字段基本特征衍生方法
针对Datetime类型的字段,提取对应的年、月、日、小时、分钟、秒等。
除了提取年月日等字段信息外,还有一些自然周期也会对结果预测有较大影响,如日期所在季度。这里需要注意的是,对于时序字段,往往我们会尽可能的对其进行自然周期的划分,然后在后续进行特征筛选时再对这些衍生字段进行筛选,而很多时候,除了季度,诸如全年的第几周、一周的第几天,甚至是日期是否在周末,具体事件的时间是在上午、下午还是在晚上等,都会对预测造成影响。
衍生是否为周末特征字段:
(t['dayofweek'] > 5).astype(int)
衍生当时时间所属周期:凌晨、上午、下午、晚上,以6个小时作为划分依据:
(t['hour'] // 6).astype(int)
关键时间点的时间差值衍生:
需设置关键时间点,再计算每条记录与关键时间点之间的时间差值,以天、月等维度来衡量。类似数据集记录的起始时间、结束时间、距今时间。
文本特征衍生方法
词向量转化
在NLP领域中,有一个极为普遍的建模分析场景——语言分析,例如分析一条评论的情感倾向,有文本数据如下:
最常见的方法就是词袋法,用一个词向量来表示一条文本。通过对每段文本进行不同单词的计数,然后用这些计数的结果来构成一个词向量,并借此来表示一个文本。词向量转化过程如下:
自动化特征衍生步骤
特征衍生通用流程分为四步,包括数据重编码、单变量特征衍生、交叉组合特征衍生和分组数据特征衍生。
(本文作者:吕盛泽)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。