Boruta-机器学习特征筛选另一种思维
Boruta是一种特征筛选方法,其核心是基于两个思想:shadow features和binomial distribution,具体信息可参考论文 Feature Selection with the Boruta Package。
特征选择方法已经很多,包括iv,feature importance,shap为什么还需要Boruta?
不同变量筛选方法看问题角度不一样,有其优势和局限性。我不建议用一种方法去筛选变量,而是参考多种方法。机器学习得到的变量解释要和业务逻辑交叉验证。有的机器学习变量筛选方法不是100%准确,老狐狸还可以通过操作数据得到有利于自己观点的解释。
Boruta与已有方法在进行特征选择时的目标导向是有区别的。
a. Boruta进行特征选择的目标是: 筛选出所有与因变量具有相关性的特征集合。
b. 通常意义上在机器学习实践过程中进行特征选择的目标是: 筛选出可以使得当前模型cost function最小的特征集合。
通常我们进行特征选择的时候基于如下2个规则:
如果删掉某维特征,导致模型性能下降,则认为该特征很重要;
如果删掉某维特征,模型性能没有变化,则认为该特征不重要;
注意: 第1条规则显然是正确的,但是第2条规则并不一定正确。因为,如果删掉某维特征后模型性能没有发生变化,这并不能充分说明该特征与因变量不相关,只能说明该特征对于该模型减小cost function没有帮助。
Boruta的目标就是选择出所有与因变量相关的特征集合,而不是针对特定模型选择出可以使得模型cost function最小的特征集合。Boruta算法的意义在于可以帮助我们更全面的理解因变量的影响因素,从而更好、更高效地进行特征选择。
Boruta算法思想:
将原特征real features进行shuffle构造出shadow features,将real features与shadow features拼接作为特征矩阵进行训练,最后以shadow features的feature importance得分最为参考base, 从real features中选出与因变量真正相关的特征集合。
shadow features
在Boruta中,特征之间并不会相互竞争,相反地,它们会和他们的随机版本相互竞争。实践中,假设我们的特征是X,
我们对X中的每个特征进行随机shuffle,这些shuffle过后的特征被称为shadow features;
这个时候,我们将shadow dataframe附加到原始dataframe以获得一个新的dataframe(我们称之为X_boruta),它的特征列数是原先X的两倍。然后我们使用一个模型对其进行训练,得到每个特征的特征重要性。
一个特征如果是有用的话,那么它的特征重要性肯定要比它的随机版本要好。
这个时候我们只需要将原始特征中特征重要性高于随机版本中最高的特征重要性分数的那些原始特征进行保留即可。但这可能会存在一个问题,这个模型或许训练的不是很好,特征重要性不是很准,于是我们就需要第二个策略。
2、binomial distribution
这一步相信大家并不陌生,核心就是不断迭代,如果一次存在侥幸,那么我们就迭代多次,比如20次,100次,然后取特重要性的均值,在进行比较筛选。这是最基础的想法,在Boruta中,特征的最大不确定性水平以50%的概率表示,就像扔硬币一样。由于每个独立的实验可以给出一个二元结果(命中或不命中),一系列的n个试验遵循二项分布,在python中,二项式分布的概率mass函数可以通过下面方式计算得到:
于是我们得到:

其中:
红色区域是拒绝区域:这块区域的特征被认为是噪声,因此它们可以被直接丢弃;
蓝色区域是犹豫区域:Boruta对这个区域的特征难以抉择;
绿色区域是可接受区域:这里的特征被认为是预测性的,一般可以被保留。
Boruta算法流程:

注:

其中: oob_acc_after_perputation是指将该维特征进行shuffle之后再用out_of_bag的样本在单棵数上的accuracy。
BorutaPy
borutapy是用 Python 重新编码的原始 R 包,增加了一些额外的功能。一些改进包括:
更快的运行时间,感谢 scikit-learn
类似 Scikit-learn 的界面
与 scikit-learn 的任何集成方法兼容
自动 n_estimator 选择
特征排名
特征重要性来自 Gini 杂质而不是 RandomForest R 包的 MDA。
我们强烈建议使用深度在 3-7 之间的修剪树。
此外,在大量使用原始代码后,我确定了一些可以改进/更改核心算法的领域,以使其不那么严格并且更适用于生物数据,其中 Bonferroni 校正可能过于苛刻。
百分位数作为阈值
原始方法使用阴影特征的最大值作为阈值,以确定哪个真实特征比阴影特征做得更好。这可能过于苛刻。
为了控制这一点,我添加了 perc 参数,该参数设置阴影特征重要性的百分位数,算法将其用作阈值。默认值为 100,这相当于像 Boruta 的 R 版本那样取最大值,但可以放宽。请注意,由于这是百分位数,它会随着数据集的大小而变化。拥有数千个功能,它不像在 Boruta 运行结束时有几十个功能那么严格。
多重测试的两步校正 多重测试
的校正通过将其设为两步过程来放松,而不是严格的一步 Bonferroni 校正。
我们首先需要纠正,因为在每次迭代中,我们都会针对零假设测试一些特征(一个特征的性能是否比随机预期的要好)。为此,Bonferroni 校正用于原始代码中,已知在这种情况下过于严格(至少对于生物数据),并且原始代码也校正 n 个特征,即使我们在第 50 次迭代中我们只剩下 k<<n 个特征。出于这个原因,校正的第一步是广泛使用的 Benjamini Hochberg FDR。
然而,在此之后,我们还需要考虑这样一个事实,即我们在每次迭代中使用相同的测试一遍又一遍地测试相同的特性。对于这种情况,Bonferroni 是完美的,因此通过将 p 值阈值与当前迭代指数相除来应用它。
如果不需要这两个步骤校正,则必须将 two_step 参数设置为 False,然后(perc=100)BorutaPy 的行为与 R 版本完全相同。
borutapy算法的参数
estimator : object
A supervised learning estimator, with a 'fit' method that returns the feature_importances_ attribute. Important features must correspond to high absolute values in the feature_importances_.
n_estimators : int or string, default = 1000
If int sets the number of estimators in the chosen ensemble method. If 'auto' this is determined automatically based on the size of the dataset. The other parameters of the used estimators need to be set with initialisation.
perc : int, default = 100
Instead of the max we use the percentile defined by the user, to pick our threshold for comparison between shadow and real features. The max tend to be too stringent. This provides a finer control over this. The lower perc is the more false positives will be picked as relevant but also the less relevant features will be left out. The usual trade-off. The default is essentially the vanilla Boruta corresponding to the max.
alpha : float, default = 0.05
Level at which the corrected p-values will get rejected in both correction steps.
two_step : Boolean, default = True
If you want to use the original implementation of Boruta with Bonferroni correction only set this to False.
max_iter : int, default = 100
The number of maximum iterations to perform.
verbose : int, default=0
Controls verbosity of output.
borutapy算法的属性
n_features_ : int
The number of selected features.
support_ : array of shape [n_features]
The mask of selected features - only confirmed ones are True.
support_weak_ : array of shape [n_features]
The mask of selected tentative features, which haven't gained enough support during the max_iter number of iterations..
ranking_ : array of shape [n_features]
The feature ranking, such that
ranking_[i]
corresponds to the ranking position of the i-th feature. Selected (i.e., estimated best) features are assigned rank 1 and tentative features are assigned rank 2.
boruta算法结肠癌基因特征筛选
实战案例中,用boruta算法结肠癌基因特征筛选,下图是筛选出重要性比较高的基因。boruta算法和其他变量筛选算法筛选结果差异比较大,也有共同点。这算法能否大规模应用还需要进一步测试。


欢迎各位学习《python机器学习生物信息学》:https://ke.qq.com/course/package/31252,学习更多相关知识,加QQ群:1026993837,免费领取100G的python学习资料。

版权声明:文章来自公众号(python风控模型),未经许可,不得抄袭。遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。