数据科学领域从业者普遍认为:数据和特征决定了机器学习效果的上限,而模型和算法只是逼近这个上限。而特征工程就是逼近这个上限的极速器。特征工程处理后的特征越好,模型的可选择性和灵活性越强,同时也降低了模型的复杂度,提升模型的效果,执行的效率及模型的可解释性。特征工程的最终目的就是提升模型的性能。
特征工程
特征工程是将原始数据进行转换、加工成模型算法所能直接使用的特征数据,更好提取数据所蕴含的规律信息,还可以对特征进行降维和非线性化,使模型泛化能力增强,减少过拟合问题。
特征工程一般开始于数据清洗后,结束于模型训练前,这阶段是对原始数据的"精雕细琢"达到算法模型所要求的样子,让数据可以更好地与算法结合,生成较好的结果。特征工程是能够将数据像艺术一样展现的技术。因为好的特征工程混合了专业领域知识、直觉和基本的数学能力。其实是将数据属性转换为数据特征的过程,对数据特征进行学习,减少模型所受噪声的影响,较准确地找到数据的潜在趋势,能够实现使用简单的模型也能达到很好效果的目标。
该部分是建模前的关键步骤,也是耗时最长的部分,模型的效果好坏绝对大部分取决于数据加工(特征工程)的情况。尤其是回归式分类模型,比如逻辑回归。
特征工程的工作有特征抽象、特征缩放、特征衍生、特征选择等。
- 特征抽象(把数据转成算法可以理解的数据(数值),比如有序特征的数值映射和无序特征的独热编码)
- 特征衍生(数据组合构造)
- 特征缩放(把数据限制到一定的取值范围,消除不同数据量级的干扰,比如归一化和标准化)
- 特征选择
核心是特征衍生,它是将处理后的格式化数据,从业务构造和技术加工的角度构造新的对目标特征更有影响的数据特征,主要方法有:
- 业务衍生
- 特征交叉组合
- 多项式化
- 树模型构造等等。
特征选择主要是通过统计学的方法,筛选出对预测变量影响最显著的指标。主要有单变量特征选择方法和基于机器学习模型的方法。
特征缩放
这一步是对数值型特征取值进行处理,将不同特征的取值范围缩放到同一级别上。特使不同规格的数据转换到同一规格。常见方法有归一化和标准化。归一化利用了边界值信息,将特征的取值区间缩放到某个特点的范围,如[0, 1]等。标准化的前提是特征值服从正态分布,标准化后,其转换成标准正态分布。
1、目的:通过把数据取值限定在一定范围内,避免不同量纲对特征权重系数的影响;加快算法收敛速度。
2、手段:归一化( [0,1] ,MinMaxScaler)/标准化(均值为0,标准差为1,保留了异常值的有用信息,StandardScaler )
归一化(MinMaxScaler)
归一化将原始数据中特征的取值区间转换到[0,1]范围,归一化公式如下:
python中使用preproccessing库的MinMaxScaler类对数据进行缩放:
from sklearn.preprocessing import MinMaxScaler #归一化,返回值为缩放到[0, 1]区间的数据 MinMaxScaler().fit_transform(data)
标准化(standardization)
该方法将原始数据归一化成均值为0、方差1的数据,标准化公式如下:
该种缩放方式要求原始数据的分布可以近似为高斯分布,否则缩放的效果会变得很差。
python中使用preproccessing库的StandardScaler类对数据标准化:
rom sklearn.preprocessing import StandardScaler
#标准化,返回值为标准化后的数据
StandardScaler().fit_transform(data)
特征选择
特征选择,是从特征集中找出与目标变量有影响且具有较高区分性特征去训练模型,获得预测性能更好的模型。特征选择的主要作用:减少特征数量、降维,使模型泛化能力更强,减少过拟合;增强对特征和特征值之间的理解。
选择特征首先是考虑特征的发散性和相关性两方面:
特征是否发散:如果一个特征不发散,例如方差接近于0,也就是说样本在这个特征上基本上没有差异,这个特征对于样本的区分并没有什么用。
特征与目标的相关性:优先选择与目标相关性高的特征。从特征的方差和相关性考虑。
根据特征选择的思路分为3种方法:嵌入方法、过滤方法、包装方法。python中使用sklearn中的feature_selection库来进行特征选择。
过滤法(filter): 通过自变量之间或自变量与目标变量之间的相关关系进行评分,设定选择阈值或个数来选择特征。比如Pearson coef、Variance 、Chi-squared test 、information gain等。
包装法(wrapper): 通过目标函数(AUC/MSE)来决定是否加入一个变量。比如RFE 、LVW 。
嵌入法(embedded): 先使用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据系数从大到小选择特征。比如SelectFromModel模块、随机森林/XGBoost、正则化L1/L2(LASSO/RIDGE)。
1. 过滤法Filter
1.1 思路:计算单个特征的统计信息或与预测结果值之间的相关程度,留下排名靠前的特征
1.2 特点:没有考虑到特征之间关联效应,有可能误删除重要特征
1.3 方法:方差、相关系数、卡方值、互信息法等
1.3.1 方差过滤法
方差过滤法计算每个特征的方差并设定阈值,选择方差值大于阈值的特征。它会删除所有零差异特征,即所有样本中具有相同值的特征,也就是除去常变量特征。只能用于筛选离散特征,连续取值的特征需要将连续值离散化之后才能用。若某个特征的90%左右的特征值偏向某一个,这个特征取值就没有区分性,相应的方差值也较小,会被过滤掉。
python中使用feature_selection库的VarianceThreshold类来选择特征的代码如下:
from sklearn.feature_selection import VarianceThreshold ##方差选择法,返回值为特征选择后的数据 #参数threshold为方差的阈值 VarianceThreshold(threshold=3).fit_transform(data) #使用get_support方法,得到选择特征列的序号 VarianceThreshold(threshold=3).get_support()
1.3.2 相关系数过滤法
皮尔森相关系数(Pearson Correlation)能帮助理解特征和目标变量之间关系的方法,该统计指标表示了变量之间的线性相关性,结果的取值区间为[-1,1]。使用相关系数法,要计算各个特征对目标值的相关系数以及相关系数的P值。
python中使用feature_selection库的SelectKBest类结合相关系数来选择特征的代码如下:
from sklearn.feature_selection import SelectKBest from scipy.stats import pearsonr #选择K个最好的特征,返回选择特征后的数据 #第一个参数为计算评估特征是否好的函数,该函数输入特征矩阵和目标向量,输出二元组(评分,P值)的数组,数组第i项为第i个特征的评分和P值。在此定义为计算相关系数 #参数k为选择的特征个数 SelectKBest(lambda X, Y: array(map(lambda x:pearsonr(x, Y), X.T)).T, k=2).fit_transform(data,target)
1.3.3 卡方值过滤法
卡方检验用于衡量离散特征对离散目标变量的相关性,通过设定卡方阈值来选择优秀的特征,构建卡方统计量:
其中,AiAi为特征A第i个取值的观察频数,EiEi为特征A第i个取值的期望频数,n为总频数,pipi为第i个取值的期望频率。
python中使用feature_selection库的SelectKBest类结合卡方检验来
选择特征的代码如下:
from sklearn.feature_selection import SelectKBest from sklearn.feature_selection import chi2 #选择K个最好的特征,返回选择特征后的数据 SelectKBest(chi2,k=2).fit_transform(data,target)
1.3.4 互信息过滤法
互信息(Mutual information)用于评价离散特征对离散目标变量的相关性的统计指标,在不同数据集上的结果无法做比较;对于连续特征需要离散化后使用,而且离散化方式对互信息法选择特征的结果有较大的影响,互信息计算公式如下:
为了处理定量数据,最大信息系数法被提出,最大信息系数(Maximal Information Coefficient, MIC)克服了这两个问题。它首先寻找一种最优的离散化方式,然后把互信息取值转换成一种度量方式,取值区间在[0,1]。
python中使用feature_selection库的SelectKBest类结合最大信息系数法来选择特征的代码如下:
from sklearn.feature_selection import SelectKBest from minepy import MINE #由于MINE的设计不是函数式的,定义mic方法将其为函数式的,返回一个二元组的第二项设置成固定的P值为0.5 def mic(x,y): m = MINE()x = np.random.uniform(-1, 1, 10000) m.compute_score(x, x**2) printm.mic() #选择k个最好的特征,返回特征选择后的数据 SelectKBest(lamda X,Y:array(map(lamda x:mic(x,y),X.T)).T,k=2).fit_transform(data,target)
2. Wrapper
2.1 思路:通过反复构建模型(如SVM或者回归模型),然后选择最好的(或者最差的)特征(可以根据系数来选),把选出来的特征选出来,然后在剩余的特征上重复这个过程,直到所有的特征都遍历过。是一种寻找最优特征子集的贪心算法。该方法直接把最终将要使用的学习器的性能作为特征子集的评价准则,这是与过滤法特征选择方法最大的区别。
2.2 特点:包装式特征选择使用学习器的性能作为评价函数,其性能要优于过滤式特征选择,但是包装式特征选择的时间开销较大且泛化能力较差。在数据集很大,特征维度高情况下,特征选择的时间和资源成本较大。
2.3 方法:递归特征消除法RFE、Las Vegas Wrapper(LVW)等
2.3.1 递归特征消除法RFE
递归消除特征法使用一个基模型来进行多轮训练,每轮训练后,消除若干权值系数的特征,再基于新的特征集进行下一轮训练。比如,用logistic回归模型对全部特征进行训练得到每个特征的权重。然后,将最小权重的特征从特征集合中去除。循环执行以上两个过程,直到特征数满足要求。RFECV在交叉验证循环中执行RFE以找到最佳数量的特征。
python中使用feature_selection库的RFE类来选择特征的代码如下:
from sklearn.feature_selection import RFE from sklearn.linear_model import LogisticRegression #递归特征消除法,返回特征选择后的数据 #参数n_features_to_select为选择的特征个数 #参数estimator为基模型 RFE(estimator=LogisticRegression(),n_features_to_select=2).fit_transform(data, target)
2.3.2 Las Vegas Wrapper(LVW)
LVW是典型的包装式特征选择方法,该算法将最终要使用的学习器的性能作为特征子集的评价标准,然后针对特征空间中的不同子集,计算每个子集的预测效果。选择效果最好的那个子集作为最终被挑选出来的特征子集。
3. Embedded
3.1 思路:根据模型来分析特征的重要程度,了解每个特征对目标的影响程度,在特定的业务场景下,不同的特征权重对业务的决策带来不同的影响。需要对特征的权重有一个正确的评判和排序,就可以通过特征重要性排序来挖掘哪些变量是比较重要的,降低学习难度,最终达到优化模型计算的目的。比如随机森林算法判定特征的重要性。
在feature_selection模块中集成的模型SelectFromModel实现了嵌入式特征选择,SelectFromModel模型通过sklearn内置的机器学习模型提供的特征重要性指标coef_或feature_importance对特征进行选择,即如果特征的coef_或feature_importance的值低于预设的阈值,则移除低于阈值的特征。其中阈值的设定可以指定,也可以通过启发式方法选择合适的阈值。启发式的方法通常有mean、median等。
3.2 特点:特征选择过程与学习器训练过程融为一体,两者在同一个优化过程中完成,即在学习器训练过程中自动完成了特征选择。
3.3 方法:基于惩罚项、基于树模型
3.3.1 基于惩罚项的特征选择法
用L1范数惩罚的线性模型会产生大量的稀疏解,使得许多特征的权重系数为零。当目标是降低数据维度而与另一个分类器一起使用,它们可以与feature_selection.SelectFromModel一起使用以选择非零系数特征。特别地,SelectFromModel与linear_model.Lasso一起使用用于解决回归问题,与LogisticRegression和LinearSVC一起使用解决分类问题。
python中使用feature_selection库的SelectFromModel类来选择特征的代码如下:
from sklearn.feature_selection import SelectFromModel from sklearn.svm import LinearSVC #利用L1正则项,LinerSVC选择特征 #参数C控制特征稀疏程度 #SVM,logistic-regression,参数c控制稀疏程度,参数c越小,越少的特征被选中。 Lasso中,参数alpha越大越少的特征被选中。 lsvc = LinearSVC(C=0.01, penalty="l1", dual=False).fit(X, y) model = SelectFromModel(lsvc, prefit=True) X_new = model.transform(X)
使用带惩罚项的基模型,除了筛选出特征外,同时也进行了降维。实际上,L1惩罚项降维的原理是从对目标重要性(相关性)相同的特征中去选取其一,未被选中的特征并不是不重要,故可以考虑同时带有L1和L2正则项的基模型做特征选择。
python使用feature_selection库的SelectFromModel类结合带L1惩罚项的逻辑回归模型来选择特征的代码如下:
from sklearn.feature_selection import SelectFromModel from sklearn.linear_model import LogisticRegression #利用L1正则项,LogisticRegression选择特征 #参数C控制特征稀疏程度 SelectFromModel(LogisticRegression(penalty="l1", C=0.1)).fit_transform(x,y)
3.3.2 基于树模型的特征选择法
基于树模型的特征选择,是利用随机森林、GBDT等模型获取特征的重要性,根据重要性进行特征选择。
python中使用feature_selection库的SelectFromModel类结合GBDT模型来选择特征的代码如下:
from sklearn.feature_selection import SelectFromModel from sklearn.ensemble import GradientBoostingClassifier #GBDT作为基模型的特征选择 SelectFromModel(GradientBoostingClassifier()).fit_transform(x,y)
在实际工作中,一般会根据特征的发散性和相关性进行初步的选择。首先,采用过滤式特征选择方法,剔除掉差异性较小,与目标值相关性弱的特征;然后再用包装式方法确定要选择的特征的最佳数量,最后结合嵌入式方法获得最佳的特征子集用于模型训练。
来源:https://mp.weixin.qq.com/s?__biz=MzU1NTMyOTI4Mw==&mid=2247488030&idx=2&sn=7b300303690b7e5fab057a1145bfd768&chksm=fbd4a072cca329644f77330c364ebe33b3afc5c528b7144aaf279d58c834e70b817eef48b808&scene=0&pass_ticket=qb6Jz76Swyd7zhXrIBT9p2Dy8uqv5q5m%2FJBaJr0GuXQDNo4k4MUQF5L%2FiW5HYmPI#rd