1、介绍
集成树(tree-based ensemble learning)中,最有名的就是随机森林树(Random Forest,简称RF)与梯度提升树(Gradient Boosting Trees,简称GBM)。而近年在Kaggle 竞赛平台中最火红的XGBoost 也是基于GBM 所延伸出来的演算法。在解释集成树有三个非常好用的方法:
特征重要度(Feature Importance)
部分相依图(Partial Dependence Plot,简称PDP)
个体条件期望图(Individual Conditional Expectation Plot,简称ICE Plot)
这三个方法属于「事后可解释性(post hoc)」并且「通用于任何一种演算法模型(model-agnostic)」。
2、资料说明
本篇文章将以新生儿的资料进行举例说明。目的是为了解特征与预测新生儿的体重(目标变数y)之间的关系。
资料下载||新生儿资料.csv列名说明
1\. Baby_weight:新生儿体重 2\. Mother_age:妈妈年龄 3\. Mother_BMI:妈妈BMI 4\. Baby_hc:新生儿头围
下面提供了R与Python的程式码让大家练习与参考:
💻 R code:Google Colab R code
💻 Python code:Google Colab Python code
3、特征重要度
特征重要度(Feature Importance)指的是特征在模型中的重要程度,若一个特征非常重要,它对模型预测的表现影响就会很大。特征重要度的计算方式有很多,例如: Gain、Split count、mean(|Tree SHAP|) 等等。本篇则会介绍「置换重要度(Permutation Importance)」的计算原理。
3.1 计算原理
排列重要度的计算一定要在模型训练完后才能计算。而他的原理基本上就是将某一特征栏位的数据重新随机排列(其目的是为了维持分布不变),再跟据指标(例如:MSE)计算特征重要度。详细的步骤与说明如下:
- 训练好一个模型f(假设特征矩阵为X、目标变数为y、误差衡量指标L(y, f))
- 通过损失函数计算出原始模型误差ɛᵒʳⁱᵍ= L( y, f(X))(例如:MSE)
- 将某一特征栏位(例如:妈妈年龄)的数据随机排列,再丢入回之前训练好的模型f计算计算模型的误差ɛᵖᵉʳᵐ = L( y, f(X ᵖᵉʳᵐ ) )。
- 计算此因子的重要程度importance = ɛᵖᵉʳᵐ-ɛᵒʳⁱᵍ。
- 把第4 个步骤中打乱的特征还原,换下一个特征并且重复3~4 的步骤,直到所有特征都计算完重要程度为止。
特征重要度可以让资料科学家了解那些特征是重要的或不重要的!
在此资料中新生儿头围为最重要的因子,重要度(importance)大约为60左右,代表的是若将新生儿头围的数据随意排列在带入模型会使得MSE 上升60 左右,而误差上升越多代表此特征在模型中的重要度越高。
.优缺点汇整 优点: 1.计算速度快不需要重新训练模型 2.直观好理解 3.提供与模型一致性的全域性解释。 缺点: 1.如果特征之间有高度相关时,置换重要度的方法会产生偏差。
3.2 决策树实例
import pandas as pd import numpy as np import matplotlib.pyplot as plt %matplotlib inline # https://www.kaggle.com/kumargh/pimaindiansdiabetescsv #diabetes = pd.read_csv('pima-indians-diabetes.csv') filename = 'data/pima-indians-diabetes.csv' names = ['preg', 'gluc', 'dbp', 'skin', 'insul', 'bmi', 'pedi', 'age', 'class'] diabetes = pd.read_csv(filename, names=names) print(diabetes.columns) diabetes.head() from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(diabetes.loc[:, diabetes.columns != 'class'], diabetes['class'], stratify=diabetes['class'], random_state=66) from sklearn.tree import DecisionTreeClassifier tree = DecisionTreeClassifier(random_state=0) tree.fit(X_train, y_train) print("Accuracy on training set: {:.3f}".format(tree.score(X_train, y_train))) print("Accuracy on test set: {:.3f}".format(tree.score(X_test, y_test))) tree = DecisionTreeClassifier(max_depth=3, random_state=0) tree.fit(X_train, y_train) print("Accuracy on training set: {:.3f}".format(tree.score(X_train, y_train))) print("Accuracy on test set: {:.3f}".format(tree.score(X_test, y_test))) diabetes_features = [x for i,x in enumerate(diabetes.columns) if i!=8] print("") print("Decision Tree Feature importances:\n{}".format(tree.feature_importances_)) def plot_feature_importances_diabetes(model): plt.figure(figsize=(8,6)) n_features = 8 plt.barh(range(n_features), model.feature_importances_, align='center') plt.yticks(np.arange(n_features), diabetes_features) plt.xlabel("Feature importance") plt.ylabel("Feature") plt.ylim(-1, n_features) plot_feature_importances_diabetes(tree) plt.savefig('Decision Tree feature_importance')
输出
Index(['preg', 'gluc', 'dbp', 'skin', 'insul', 'bmi', 'pedi', 'age', 'class'], dtype='object') Accuracy on training set: 1.000 Accuracy on test set: 0.714 Accuracy on training set: 0.773 Accuracy on test set: 0.740 Decision Tree Feature importances: [0.04554275 0.6830362 0. 0. 0. 0.27142106 0. 0. ]
3.3 随机森林实例
# Random Forest from sklearn.ensemble import RandomForestClassifier rf = RandomForestClassifier(n_estimators=100, random_state=0) rf.fit(X_train, y_train) print("") print('Random Forest') print("Accuracy on training set: {:.3f}".format(rf.score(X_train, y_train))) print("Accuracy on test set: {:.3f}".format(rf.score(X_test, y_test))) rf1 = RandomForestClassifier(max_depth=3, n_estimators=100, random_state=0) rf1.fit(X_train, y_train) print("") print('Random Forest - Max Depth = 3') print("Accuracy on training set: {:.3f}".format(rf1.score(X_train, y_train))) print("Accuracy on test set: {:.3f}".format(rf1.score(X_test, y_test))) print("") print('Random Forest Feature Importance') plot_feature_importances_diabetes(rf)
Random Forest Accuracy on training set: 1.000 Accuracy on test set: 0.786 Random Forest - Max Depth = 3 Accuracy on training set: 0.800 Accuracy on test set: 0.755 Random Forest Feature Importance