一、基本介绍
Boruta 算法是一种特征筛选方法,其核心是基于两个思想:shadow features和binomial distribution。 该算法可以自动在数据集上执行特征选择。作为 R 的一个包而诞生。目前 Python 的 Boruta 版本是 BorutaPy。
二、基本原理
2.1 算法原理
2.1.1 前言 假设检验原理:https://blog.csdn.net/andy_shenzl/article/details/81453509
2.1.2 算法步骤
-
创建阴影特征 (shadow feature) 。从X开始,对每个真实特征R,随机打乱顺序,这些被打乱顺序的原始特征称为阴影特征(shadow features)。此时,阴影数据帧将附加到原始数据帧以获得新的数据帧,该数据帧的列数是X的列数的两倍。 在Boruta中,原始特征之间不会相互竞争。相反,原始特征与shuffle后的特征(shadow features)竞争 -
获取重要性。用新的特征矩阵N作为输入,训练模型,能输出feature_importances_的模型,如RandomForest, lightgbm,xgboost都可以,得到真实特征和阴影特征的feature importances -
设置阈值。取阴影特征feature importance的百分位数作为阈值(原始版本为最大值S_max),真实特征中feature importance大于阈值的,记录一次命中。 -
特征筛选。累计各特征命中数,结合命中数和迭代次数做假设检验。根据不同检验统计指标值和显著性水平的对比(大于alpha)得到接受的重要特征和拒绝的不重要特征,删除不重要的特征。假设检验保留的则是boruta认为和标签值之间存在着较好的关联的可接受的特征。 -
迭代。重复上述步骤,知道每个特征都被标记过或达到迭代次数。
2.1.3 boruta假设检验
- 拒绝区域(红色区域):此处结束的要素被视为噪音,因此将其丢弃;
- 一个无法解决的区域(蓝色区域):Boruta对于该区域中的特征犹豫不决;
- 可接受区域(绿色区域):此处的特征被认为是可预测的,因此将其保留。
上述步骤中的假设检验都是针对单次的迭代进行的,实际上boruta内部一共迭代n次,n由用户来指定,如果迭代n次则我们必须做n次的假设检验,而进行n次的假设检验的问题在于我们无法保证这n次假设检验的通过与否不受随机性的干扰,每一次假设检验也有通过与不通过两种状态,所以我们在这个层面上也要考虑进行一定的处理。
- Bonferroni校正。boruta R包的原生解决方案,Bonferroni校正,使用了更加严格的显著性水平。比如我们原始设置的显著性水平为0.05,进行了10次的独立的假设检验,那么我们每次检验的显著性水平应该变成0.05/10=0.005,显然这样对于单次假设检验来说,这么低的显著性水平的要求是非常苛刻的,这样的处理方案很多时候太过严格,导致太多弱关联性的特征被删除。
- 两步校正。BorutaPy采用的是BH检验。
2.1.4 注意 对于相关性问题,boruta是比较敏感的,因为保留的是重要性高于随机生成特征重要性的特征。显然,所有相关属性的集合可能包含相互之间相关性特别强的特征(boruta对特征共线性问题并没有做出处理),所以还是要先做相关性分析与处理之后再做分析比较稳妥。另外小样本可能也是一个影响的因素。
2.2 BorutaPy包
2.2.1参数详解 2.2.2属性详解
2.2.3 案例
import pandas as pd
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
from boruta import BorutaPy
import numpy as np
def boruta_test2():
X = pd.read_csv(r'G:\\Algorithm\\practice\\csv_data\\test_X.csv', index_col=0)
y = pd.read_csv(r'G:\\Algorithm\\practice\\csv_data\\test_y.csv', header=None, index_col=0).values
y = y.ravel()
rf = RandomForestRegressor(n_jobs=-1, max_depth=5)
boruta_model = BorutaPy(
estimator=rf,
n_estimators='auto',
max_iter=100 # number of trials to perform
)
# 模型训练
boruta_model.fit(np.array(X), np.array(y))
# 输出结果
boruta_model.support_ #筛选后的特征,False代表滤除掉此特征
boruta_model.ranking_ #1为选定的特征,2为暂定特征
green_area = X.columns[boruta_model.support_].to_list()
blue_area = X.columns[boruta_model.support_weak_].to_list()
print('features in the green area:', green_area)
print('features in the blue area:', blue_area)
if __name__ == "__main__":
boruta_test2()
三、参考文献 假设检验:https://blog.csdn.net/andy_shenzl/article/details/81453509 boruta中的假设检验:https://zhuanlan.zhihu.com/p/83550478 boruta介绍:https://blog.csdn.net/weixin_39653948/article/details/109995763
|