feature_importance的特征重要性
There are indeed several ways to get feature "importances". As often, there is no strict consensus about what this word means.
In scikit-learn, we implement the importance as described in [1] (often cited, but unfortunately rarely read...). It is sometimes called "gini importance" or "mean decrease impurity" and is defined as the total decrease in node impurity (weighted by the probability of reaching that node (which is approximated by the proportion of samples reaching that node)) averaged over all trees of the ensemble.
In the literature or in some other packages, you can also find feature importances implemented as the "mean decrease accuracy".
Basically, the idea is to measure the decrease in accuracy on OOB data when you randomly permute the values for that feature. If the decrease is low, then the feature is not important, and vice-versa.
(Note that both algorithms are available in the randomForest R package.)
[1]: Breiman, Friedman, "Classification and regression trees", 1984.
其實sklearn的作者說並沒有給出feature importance的具體定義。
feature importance有兩種常用實現思路:
(1) mean decrease in node impurity:
feature importance is calculated by looking at the splits of each tree. The importance of the splitting variable is proportional to the improvement to the gini index given by that split and it is accumulated (for each variable) over all the trees in the forest.
就是計算每棵樹的每個划分特征在划分准則(gini或者entropy)上的提升,然后對聚合所有樹得到特征權重
(2) mean decrease in accuracy:
This method, proposed in the original paper, passes the OOB samples down the tree and records prediction accuracy.
A variable is then selected and its values in the OOB samples are randomly permuted. OOB samples are passed down the tree and accuracy is computed again.
A decrease in accuracy obtained by this permutation is averaged over all trees for each variable and it provides the importance of that variable (the higher the decreas the higher the importance).
簡單來說,如果該特征非常的重要,那么稍微改變一點它的值,就會對模型造成很大的影響。
自己造數據太麻煩,可以直接在OOB數據集對該維度的特征數據進行打亂,重新訓練測試,打亂前的准確率減去打亂后的准確率就是該特征的重要度。該方法又叫permute。
以random forest為例
以random forest為例,feature importance特性有助於模型的可解釋性。簡單考慮下,就算在解釋性很強的決策樹模型中,如果樹過於龐大,人類也很難解釋它做出的結果。
隨機森林通常會有上百棵樹組成,更加難以解釋。好在我們可以找到那些特征是更加重要的,從而輔助我們解釋模型。更加重要的是可以剔除一些不重要的特征,降低雜訊。比起pca降維后的結果,更具有人類的可理解性。
sklearn中實現的是第一種方法【mean decrease in node impurity】實現的。使用iris數據集我們來看下效果。
首先,對於單棵決策樹,權重是怎么計算的呢?
iris = load_iris() X = iris.data y = iris.target dt = DecisionTreeClassifier(criterion='entropy', max_leaf_nodes=3) dt.fit(X, y)
使用Graphviz畫出生成的決策樹
sklearn中tree的代碼是用Cython編寫的,具體這部分的源碼在compute_feature_importances方法中
根據上面生成的樹,我們計算特征2和特征3的權重
特征2: 1.585*150 - 0*50 - 1.0*100 = 137.35
特征3: 1.0*100 - 0.445*54 - 0.151*46 = 69.024
歸一化之后得到[0, 0, 0.665, 0.335] 我們算的結果和sklearn輸出的結果相同。
得到每課樹的特征重要度向量之后,就加和平均得到結果,具體代碼如下:

def feature_importances_(self): """Return the feature importances (the higher, the more important the feature). Returns ------- feature_importances_ : array, shape = [n_features] """ check_is_fitted(self, 'n_outputs_') if self.estimators_ is None or len(self.estimators_) == 0: raise ValueError("Estimator not fitted, " "call `fit` before `feature_importances_`.") all_importances = Parallel(n_jobs=self.n_jobs, backend="threading")( delayed(getattr)(tree, 'feature_importances_') for tree in self.estimators_) return sum(all_importances) / len(self.estimators_)
利用permutation importance挑選變量
為什么引入置換重要性:
決策樹適合於尋找也可以解釋的非線性預測規則,盡管它們的不穩定性和缺乏平滑性引起了人們的關注(Hastie 等,2001)。RandomForest(RF; Breiman,2001)分類器旨在克服這些問題,並且由於將決策樹的可解釋性與現代學習算法(例如人工神經網絡和SVM)的性能相結合而受到廣泛歡迎。RF的作者提出了兩種用於特征排名的度量,即變量重要性(VI)和基尼重要性(GI)。最近的一項研究表明,如果預測變量是分類的,則這兩種方法都偏向於采用更多類別的變量(Strobl 等,2007)。這篇文章的作者將偏愛歸因於使用bootstrap采樣和吉尼分裂准則來訓練分類樹和回歸樹(CART; Breiman 等,1984)。在文獻中,多年來已經報道了由基尼系數引起的偏差(Bourguignon,1979; Pyatt 等,1980)。),並且通常不僅會影響分類變量,還會影響分組變量(即,將變量聚類的值分成多個獨立的組,例如多峰高斯分布)。在生物學中,預測因子通常具有分類或分組的值(例如,微陣列和序列突變)。Strobl 等。(2007)提出了一種新的算法(cforest),用於基於條件推理樹構建RF模型(Hothorn 等,2006),並計算可校正偏差的VI值。
關於生物學數據的學習通常具有大量特征和少量可用樣本的特征。通常的做法是在模型擬合之前濾除不重要的特征,例如,通過拒絕與結果最少相關的特征。互信息(MI)是在這種情況下經常使用的一種關聯度量(Guyon和Elisseeff,2003年)。它與基尼指數密切相關,並且事實證明,它也偏向於具有更多類別的變量(Achard 等,2005)。
們在構建樹類模型(XGBoost、LightGBM等)時,如果想要知道哪些變量比較重要的話。可以通過模型的feature_importances_方法來獲取特征重要性。
例如LightGBM的feature_importances_可以通過特征的分裂次數或利用該特征分裂后的增益來衡量。一般情況下,不同的衡量准則得到的特征重要性順序會有差異。
一般是通過多種評價標准來交叉選擇特征,當一個特征在不同的評價標准下都是比較重要的,那么該特征對label有較好的預測能力。
為大家介紹一種評價特征重要性的方法:PermutationImportance。
文檔對該方法介紹如下:
eli5 provides a way to compute feature importances for any black-box estimator by measuring how score decreases when a feature is not available;
the method is also known as “permutation importance” or “Mean Decrease Accuracy (MDA)”.
若將一個特征置為隨機數,模型效果下降很多,說明該特征比較重要;反之則不是。
下面為大家舉一個簡單的例子,我們利用不同模型來挑選變量(RF、LightGBM、LR)。並挑選出來重要性排在前30的變量(總變量200+)進行建模。
參考博客:
1.特征選擇之tree的feature_importance的缺陷和處理方法 和 另一篇
2.月下之風