谁动了我的特征

发布网友 发布时间:2022-04-24 09:17

我来回答

1个回答

热心网友 时间:2022-06-18 11:16

谁动了我的特征
1 为什么要记录特征转换行为?
使用机器学习算法和模型进行数据挖掘,有时难免事与愿违:我们依仗对业务的理解,对数据的分析,以及工作经验提出了一些特征,但是在模型训练完成后,某些特征可能“身微言轻”——我们认为相关性高的特征并不重要,这时我们便要反思这样的特征提出是否合理;某些特征甚至“南辕北辙”——我们认为正相关的特征结果变成了负相关,造成这种情况很有可能是抽样与整体不相符,模型过于复杂,导致了过拟合。然而,我们怎么判断先前的假设和最后的结果之间的差异呢?

线性模型通常有含有属性coef_,当系数值大于0时为正相关,当系数值小于0时为负相关;另外一些模型含有属性feature_importances_,顾名思义,表示特征的重要性。根据以上两个属性,便可以与先前假设中的特征的相关性(或重要性)进行对比了。但是,理想是丰满的,现实是骨感的。经过复杂的特征转换之后,特征矩阵X已不再是原来的样子:哑变量使特征变多了,特征选择使特征变少了,降维使特征映射到另一个维度中。

累觉不爱了吗?如果,我们能够将最后的特征与原特征对应起来,那么分析特征的系数和重要性又有了意义了。所以,在训练过程(或者转换过程)中,记录下所有特征转换行为是一个有意义的工作。可惜,sklearn暂时并没有提供这样的功能。在这篇博文中,我们尝试对一些常见的转换功能进行行为记录,读者可以在此基础进行进一步的拓展。

2 有哪些特征转换的方式?
《使用sklearn做单机特征工程》一文概括了若干常见的转换功能:

类名功能说明
StandardScaler数据预处理(无量纲化)标准化,基于特征矩阵的列,将特征值转换至服从标准正态分布
MinMaxScaler数据预处理(无量纲化)区间缩放,基于最大最小值,将特征值转换到[0, 1]区间上
Normalizer数据预处理(归一化)基于特征矩阵的行,将样本向量转换为“单位向量”
Binarizer数据预处理(二值化)基于给定阈值,将定量特征按阈值划分
OneHotEncoder数据预处理(哑编码)将定性数据编码为定量数据
Imputer数据预处理(缺失值计算)计算缺失值,缺失值可填充为均值等
PolynomialFeatures数据预处理(多项式数据转换)多项式数据转换
FunctionTransformer数据预处理(自定义单元数据转换)使用单变元的函数来转换数据
VarianceThreshold特征选择(Filter)方差选择法
SelectKBest特征选择(Filter)可选关联系数、卡方校验、最大信息系数作为得分计算的方法
RFE特征选择(Wrapper)递归地训练基模型,将权值系数较小的特征从特征集合中消除
SelectFromModel特征选择(Embedded)训练基模型,选择权值系数较高的特征
PCA降维(无监督)主成分分析法
LDA降维(有监督)线性判别分析法
按照特征数量是否发生变化,这些转换类可分为:

无变化:StandardScaler,MinMaxScaler,Normalizer,Binarizer,Imputer,FunctionTransformer*
有变化:OneHotEncoder,PolynomialFeatures,VarianceThreshold,SelectKBest,RFE,SelectFromModel,PCA,LDA
FunctionTransformer*:自定义的转换函数通常不会使特征数量发生变化
对于不造成特征数量变化的转换类,我们只需要保持特征不变即可。在此,我们主要研究那些有变化的转换类,其他转换类都默认为无变化。按照映射的形式,可将以上有变化的转换类可分为:

一对一:VarianceThreshold,SelectKBest,RFE,SelectFromModel
一对多:OneHotEncoder
多对多:PolynomialFeatures,PCA,LDA
原特征与新特征为一对一映射通常发生在特征选择时,若原特征被选择则直接变成新特征,否则抛弃。哑编码为典型的一对多映射,需要哑编码的原特征将会转换为多个新特征。多对多的映射中PolynomialFeatures并不要求每一个新特征都与原特征建立映射关系,例如阶为2的多项式转换,第一个新特征只由第一个原特征生成(平方)。降维的本质在于将原特征矩阵X映射到维度更低的空间中,使用的技术通常是矩阵乘法,所以它既要求每一个原特征映射到所有新特征,同时也要求每一个新特征被所有原特征映射。

3 特征转换的组合
在《使用sklearn优雅地进行数据挖掘》一文中,我们看到一个基本的数据挖掘场景:

特征转换行为通常是流水线型和并行型结合的。所以,我们考虑重新设计流水线处理类Pipeline和并行处理类FeatureUnion,使其能够根据不同的特征转换类,记录下转换行为“日志”。“日志”的表示形式也是重要的,由上图可知,集成后的特征转换过程呈现无环网状,故使用网络来描述“日志”是合适的。在网络中,节点表示特征,有向连线表示特征转换。

为此,我们新增两个类型Feature和Transfrom来构造网络结构,Feature类型表示网络中的节点,Transform表示网络中的有向边。python的networkx库可以很好地表述网络和操作网络,我这是要重新造轮子吗?其实并不是,现在考虑代表新特征的节点怎么命名的问题,显然,不能与网络中任意节点同名,否则会发生混淆。然而,由于sklearn的训练过程存在并行过程(线程),直接使用network来构造网络的话,将难以处理节点重复命名的问题。所以,我才新增两个新的类型来描述网络结构,这时网络中的节点名是可以重复的。最后,对这网络进行广度遍历,生成基于networkx库的网络,因为这个过程是串行的,故可以使用“当前节点数”作为新增节点的序号了。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com