嵌入法
过程:将所有特征都放入一个循环。这个循环会选出特征子集投入算法进行模型评估。如此反复
嵌入法的结果会更加精确到模型的效用本身,对于提高模型效力有更好的效果。
但他也有缺点:
嵌入法使用的权值系数没有像p值这样能够界定范围的。大量特征对模型有贡献且贡献不一,就很难界定有效的临界值。
计算速度依赖于算法模型的数据。
- 元变换器,可以与任何在拟合后具有coef_,feature_importances_或者参数中可选惩罚项的评估其一起使用(随机森林和树模型就有feature_importances_;逻辑回归有L1,L2惩罚项,线性支持向量机支持L2惩罚项)
- 对于有feature_importances_ 的取值范围是[0, 1],如果设置阈值很小,比如0.0001就能删除那些对标签预测完全没有贡献的特征。如果很接近1,可能就只能剩下少部分特征。
代码:
from sklearn.feature_selection import SelectFromModel
SelectFromModel(estimator, *, threshold=None, prefit=False, norm_order=1, max_features=None)
参数 | 说明 |
---|---|
estimator | 使用的模型评估器,只要是待feature_importances_或者coef_或者参数带有惩罚项的模型都可以使用 |
threshold | 特征重要性的阈值,低于这个值的都将被删除 |
prefit | 默认False,判断是否将实例化后的模型直接传递给构造函数。如果为True,则必须直接调用fit和transform,不能使用fit_transform,并且SelectFromModel不能与cross_val_score,GridSearchCV和克隆估计器的类似实用程序一起使用 |
norm_order | k可输入非零整数,正无穷,负无穷,默认值1;在评估器的coef_属性高于一维的情况下,用于过滤低于阈值的系数的向量的范数的阶数 |
max_features | 在阈值设定下,要选择的最大特征数。要禁用阈值并仅根据max_features选择,请设置threshold=-np.inf |
from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import RandomForestClassifier as RFC
RFC_ = RFC(n_estimators=10, random_state=0)
X_embedded = SelectFromModel(RFC_, threshold=0.005).fit_transform(x, y)
# 这个阈值的大小可以通过 1/特征数 得到平均阈值来感觉的所设阈值的大小
通过学习曲线进行选择阈值(代码模板)
from sklearn.feature_selection import SelectFromModel
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier as RFC
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import cross_val_score
RFC_ = RFC(n_estimators=10, random_state=0) # 实例化
X_embedded = SelectFromModel(RFC_, threshold=0.005).fit_transform(x, y) # 选取出符合阈值的特征
RFC_.fit(x, y).feature_importances_ # 利用随机森林得到特征重要性
threshold = np.linspace(0, (RFC_.fit(x, y).feature_importances_).max(), 20) # 建立出20个一维数组,从0到重要程度最大的那个值
score = list()
for i in threshold:
X_embedded = SelectFromModel(RFC_, threshold=i).fit_transform(x, y) # 阈值似乎就能看做重要程度
once = cross_val_score(RFC_, X_embedded, y, cs=5).mean() # 利用选取的特征进行交叉验证得到Accuracy的均值
score.append(once) # 记录
plt.plot(threshold, score) # 画图
plt.show()