原理
给定一个外部的估计器,可以对特征赋予一定的权重(比如,线性模型的相关系数),recursive feature elimination ( RFE ) 通过考虑越来越小的特征集合来递归的选择特征。 首先,评估器在初始的特征集合上面训练并且每一个特征的重要程度是通过一个 coef_ 属性 或者 feature_importances_ 属性来获得。 然后,从当前的特征集合中移除最不重要的特征。在特征集合上不断的重复递归这个步骤,直到最终达到所需要的特征数量为止。 RFECV 在一个交叉验证的循环中执行 RFE 来找到最优的特征数量
用法
这里我们选择外部估计器为线性内核的SVM,求出各个特征的权重系数之后放到高斯内核的SVM中来对样本进行分类。
from sklearn.svm import SVC
from sklearn.model_selection import StratifiedKFold
from sklearn.feature_selection import RFECV
svc = SVC(kernel="linear")
rfecv = RFECV(estimator=svc, # 学习器
step=1, # 移除特征个数
cv=StratifiedKFold(2), # 交叉验证次数
scoring='accuracy', # 学习器的评价标准
verbose = 1,
n_jobs = 1
).fit(X, y)
X_RFECV = rfecv.transform(X)
clf = svm.SVC(gamma="auto", C=0.8) # C:惩罚系数,值在0-1之间,C越大泛化能力越差
scores = (cross_val_score(clf, X_RFECV, label_data, cv=5))
print(scores)
print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std()*2))
误区
这段说明是在svm文件里面的classes.py中得到的,里面讲的是coef_是一个大小为类别数乘以特征数(n_classes*n_features)的矩阵,里面存放着分配给各个特征的权重,如果是二分类则shape = [n_features]。下面讲了只有在线性内核里面才有:
Attributes
----------
coef_ : array, shape = [n_features] if n_classes == 2 else [n_classes, n_features]
Weights assigned to the features (coefficients in the primal
problem). This is only available in the case of a linear kernel.
``coef_`` is a readonly property derived from ``raw_coef_`` that
follows the internal memory layout of liblinear.
intercept_ : array, shape = [1] if n_classes == 2 else [n_classes]
Constants in decision function.
下面是rfe.py里面的一段代码,这一段是想要得到coefs,但前提是我们选择的内核要有coef_。而上面说了只有在线性内核里面才有coef_,所以rfe只对线性内核起作用。其中hasattr()函数是用来判断对象是否包含对应的属性,比如hasattr(estimator,‘coef_’)就是用来判断对象estimator里是否含有coef_,如果有的话返回1,没有的话返回0 。
说明一下这里的coef_的作用,coef_是特征系数矩阵,某个特征的系数越大说明其重要性越大,所以这里通过coef_来对特征的重要性排序。
getattr(object, name[, default]) #函数用于返回一个对象属性值
object – 对象。
name – 字符串,对象属性。
default – 默认返回值,如果不提供该参数,在没有对应属性时,将触发 AttributeError
而在svm里面并没有feature_importances这个对象。
# Get coefs
if hasattr(estimator, 'coef_'):
coefs = estimator.coef_
else:
coefs = getattr(estimator, 'feature_importances_', None)
if coefs is None:
raise RuntimeError('The classifier does not expose '
'"coef_" or "feature_importances_" '
'attributes')