Feature importance sklearn что показывает
Перейти к содержимому

Feature importance sklearn что показывает

  • автор:

4.2. Permutation feature importance¶

Permutation feature importance is a model inspection technique that can be used for any fitted estimator when the data is tabular. This is especially useful for non-linear or opaque estimators . The permutation feature importance is defined to be the decrease in a model score when a single feature value is randomly shuffled [ 1 ] . This procedure breaks the relationship between the feature and the target, thus the drop in the model score is indicative of how much the model depends on the feature. This technique benefits from being model agnostic and can be calculated many times with different permutations of the feature.

Features that are deemed of low importance for a bad model (low cross-validation score) could be very important for a good model. Therefore it is always important to evaluate the predictive power of a model using a held-out set (or better with cross-validation) prior to computing importances. Permutation importance does not reflect to the intrinsic predictive value of a feature by itself but how important this feature is for a particular model.

The permutation_importance function calculates the feature importance of estimators for a given dataset. The n_repeats parameter sets the number of times a feature is randomly shuffled and returns a sample of feature importances.

Let’s consider the following trained regression model:

>>> from sklearn.datasets import load_diabetes >>> from sklearn.model_selection import train_test_split >>> from sklearn.linear_model import Ridge >>> diabetes = load_diabetes() >>> X_train, X_val, y_train, y_val = train_test_split( . diabetes.data, diabetes.target, random_state=0) . >>> model = Ridge(alpha=1e-2).fit(X_train, y_train) >>> model.score(X_val, y_val) 0.356. 

Its validation performance, measured via the \(R^2\) score, is significantly larger than the chance level. This makes it possible to use the permutation_importance function to probe which features are most predictive:

>>> from sklearn.inspection import permutation_importance >>> r = permutation_importance(model, X_val, y_val, . n_repeats=30, . random_state=0) . >>> for i in r.importances_mean.argsort()[::-1]: . if r.importances_mean[i] - 2 * r.importances_std[i] > 0: . print(f"diabetes.feature_names[i]:>" . f"r.importances_mean[i]:.3f>" . f" +/- r.importances_std[i]:.3f>") . s5 0.204 +/- 0.050 bmi 0.176 +/- 0.048 bp 0.088 +/- 0.033 sex 0.056 +/- 0.023 

Note that the importance values for the top features represent a large fraction of the reference score of 0.356.

Permutation importances can be computed either on the training set or on a held-out testing or validation set. Using a held-out set makes it possible to highlight which features contribute the most to the generalization power of the inspected model. Features that are important on the training set but not on the held-out set might cause the model to overfit.

The permutation feature importance is the decrease in a model score when a single feature value is randomly shuffled. The score function to be used for the computation of importances can be specified with the scoring argument, which also accepts multiple scorers. Using multiple scorers is more computationally efficient than sequentially calling permutation_importance several times with a different scorer, as it reuses model predictions.

An example of using multiple scorers is shown below, employing a list of metrics, but more input formats are possible, as documented in Using multiple metric evaluation .

>>> scoring = ['r2', 'neg_mean_absolute_percentage_error', 'neg_mean_squared_error'] >>> r_multi = permutation_importance( . model, X_val, y_val, n_repeats=30, random_state=0, scoring=scoring) . >>> for metric in r_multi: . print(f"metric>") . r = r_multi[metric] . for i in r.importances_mean.argsort()[::-1]: . if r.importances_mean[i] - 2 * r.importances_std[i] > 0: . print(f" diabetes.feature_names[i]:>" . f"r.importances_mean[i]:.3f>" . f" +/- r.importances_std[i]:.3f>") . r2 s5 0.204 +/- 0.050 bmi 0.176 +/- 0.048 bp 0.088 +/- 0.033 sex 0.056 +/- 0.023 neg_mean_absolute_percentage_error s5 0.081 +/- 0.020 bmi 0.064 +/- 0.015 bp 0.029 +/- 0.010 neg_mean_squared_error s5 1013.866 +/- 246.445 bmi 872.726 +/- 240.298 bp 438.663 +/- 163.022 sex 277.376 +/- 115.123 

The ranking of the features is approximately the same for different metrics even if the scales of the importance values are very different. However, this is not guaranteed and different metrics might lead to significantly different feature importances, in particular for models trained for imbalanced classification problems, for which the choice of the classification metric can be critical.

4.2.1. Outline of the permutation importance algorithm¶

  • Inputs: fitted predictive model \(m\) , tabular dataset (training or validation) \(D\) .
  • Compute the reference score \(s\) of the model \(m\) on data \(D\) (for instance the accuracy for a classifier or the \(R^2\) for a regressor).
  • For each feature \(j\) (column of \(D\) ):
    • For each repetition \(k\) in \(\) :
      • Randomly shuffle column \(j\) of dataset \(D\) to generate a corrupted version of the data named \(\tilde_\) .
      • Compute the score \(s_\) of model \(m\) on corrupted data \(\tilde_\) .

      \[i_j = s — \frac<1> \sum_^ s_\]

      4.2.2. Relation to impurity-based importance in trees¶

      Tree-based models provide an alternative measure of feature importances based on the mean decrease in impurity (MDI). Impurity is quantified by the splitting criterion of the decision trees (Gini, Log Loss or Mean Squared Error). However, this method can give high importance to features that may not be predictive on unseen data when the model is overfitting. Permutation-based feature importance, on the other hand, avoids this issue, since it can be computed on unseen data.

      Furthermore, impurity-based feature importance for trees are strongly biased and favor high cardinality features (typically numerical features) over low cardinality features such as binary features or categorical variables with a small number of possible categories.

      Permutation-based feature importances do not exhibit such a bias. Additionally, the permutation feature importance may be computed performance metric on the model predictions and can be used to analyze any model class (not just tree-based models).

      The following example highlights the limitations of impurity-based feature importance in contrast to permutation-based feature importance: Permutation Importance vs Random Forest Feature Importance (MDI) .

      4.2.3. Misleading values on strongly correlated features¶

      When two features are correlated and one of the features is permuted, the model will still have access to the feature through its correlated feature. This will result in a lower importance value for both features, where they might actually be important.

      One way to handle this is to cluster features that are correlated and only keep one feature from each cluster. This strategy is explored in the following example: Permutation Importance with Multicollinear or Correlated Features .

      • Permutation Importance vs Random Forest Feature Importance (MDI)
      • Permutation Importance with Multicollinear or Correlated Features

      L. Breiman, “Random Forests”, Machine Learning, 45(1), 5-32, 2001.

      Feature importances with a forest of trees¶

      This example shows the use of a forest of trees to evaluate the importance of features on an artificial classification task. The blue bars are the feature importances of the forest, along with their inter-trees variability represented by the error bars.

      As expected, the plot suggests that 3 features are informative, while the remaining are not.

      import matplotlib.pyplot as plt 

      Data generation and model fitting¶

      We generate a synthetic dataset with only 3 informative features. We will explicitly not shuffle the dataset to ensure that the informative features will correspond to the three first columns of X. In addition, we will split our dataset into training and testing subsets.

      from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split X, y = make_classification( n_samples=1000, n_features=10, n_informative=3, n_redundant=0, n_repeated=0, n_classes=2, random_state=0, shuffle=False, ) X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=42) 

      A random forest classifier will be fitted to compute the feature importances.

      from sklearn.ensemble import RandomForestClassifier feature_names = [f"feature i>" for i in range(X.shape[1])] forest = RandomForestClassifier(random_state=0) forest.fit(X_train, y_train) 
      RandomForestClassifier(random_state=0)

      In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
      On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.

      RandomForestClassifier

      RandomForestClassifier(random_state=0)

      Feature importance based on mean decrease in impurity¶

      Feature importances are provided by the fitted attribute feature_importances_ and they are computed as the mean and standard deviation of accumulation of the impurity decrease within each tree.

      Impurity-based feature importances can be misleading for high cardinality features (many unique values). See Permutation feature importance as an alternative below.

      import time import numpy as np start_time = time.time() importances = forest.feature_importances_ std = np.std([tree.feature_importances_ for tree in forest.estimators_], axis=0) elapsed_time = time.time() - start_time print(f"Elapsed time to compute the importances: elapsed_time:.3f> seconds") 
      Elapsed time to compute the importances: 0.005 seconds

      Let’s plot the impurity-based importance.

      import pandas as pd forest_importances = pd.Series(importances, index=feature_names) fig, ax = plt.subplots() forest_importances.plot.bar(yerr=std, ax=ax) ax.set_title("Feature importances using MDI") ax.set_ylabel("Mean decrease in impurity") fig.tight_layout() 

      Feature importances using MDI

      We observe that, as expected, the three first features are found important.

      Feature importance based on feature permutation¶

      Permutation feature importance overcomes limitations of the impurity-based feature importance: they do not have a bias toward high-cardinality features and can be computed on a left-out test set.

      from sklearn.inspection import permutation_importance start_time = time.time() result = permutation_importance( forest, X_test, y_test, n_repeats=10, random_state=42, n_jobs=2 ) elapsed_time = time.time() - start_time print(f"Elapsed time to compute the importances: elapsed_time:.3f> seconds") forest_importances = pd.Series(result.importances_mean, index=feature_names) 
      Elapsed time to compute the importances: 0.492 seconds

      The computation for full permutation importance is more costly. Features are shuffled n times and the model refitted to estimate the importance of it. Please see Permutation feature importance for more details. We can now plot the importance ranking.

      fig, ax = plt.subplots() forest_importances.plot.bar(yerr=result.importances_std, ax=ax) ax.set_title("Feature importances using permutation on full model") ax.set_ylabel("Mean accuracy decrease") fig.tight_layout() plt.show() 

      Feature importances using permutation on full model

      The same features are detected as most important using both methods. Although the relative importances vary. As seen on the plots, MDI is less likely than permutation importance to fully omit a feature.

      Total running time of the script: (0 minutes 0.998 seconds)

      Как интерпретировать предсказания моделей в SHAP

      Одной из важнейших задач в сфере data science является не только построение модели, способной делать качественные предсказания, но и умение интерпретировать такие предсказания.

      Если мы не просто знаем, что клиент склонен купить товар, но так же понимаем, что влияет на его покупку, мы сможем в будущем выстраивать стратегию компанию, направленную на повышение эффективности продаж.

      Или модель предсказала, что пациент скоро заболеет. Точность таких предсказаний не бывает очень высокой, т.к. много скрытых от модели факторов, но объяснение причин, почему модель сделала такое предсказание, может помочь доктору обратить внимание на новые симптомы. Таким образом, можно расширить границы применения модели, если её точность сама по себе не слишком высока.

      В этом посте я хочу рассказать о технике SHAP, которая позволяет заглянуть под капот самых разных моделей.

      Если с линейными моделями всё более менее понятно, чем больше абсолютное значение коэффициента при предикторе, тем данный предиктор важнее, то объяснить важность фичей того же градиентного бустинга заметно сложнее.

      Почему возникла необходимости в такой библиотеке

      image

      В стеке sklearn, в пакетах xgboost, lightGBM были встроенные методы оценки важности фичей (feature importance) для «деревянных моделей»:

      1. Gain
        Эта мера показывает относительный вклад каждой фичи в модель. для расчета мы идем по каждому дереву, смотрим в каждом узле дерева какая фича приводит к разбиению узла и насколько снижаетcя неопределенность модели согласно метрике (Gini impurity, information gain).
        Для каждой фичи суммируется её вклад по всем деревьям.
      2. Cover
        Показывает количество наблюдений для каждой фичи. Например, у вас 4 фичи, 3 дерева. Предположим, фича 1 в узлах дерева содержит 10, 5 и 2 наблюдения в деревьях 1, 2 и 3 соответственно Тогда для данной фичи важность будет равна 17 (10 + 5 + 2).
      3. Frequency
        Показывает, как часто данная фича встречается в узлах дерева, то есть считается суммарное количество разбиений дерева на узлы для каждой фичи в каждом дереве.

      Мы, конечно, можем сделать несколько предсказаний, меняя уровень дохода. Но что делать с другими фичами? Ведь мы попадаем в ситуацию, что надо получить понимание влияние дохода независимо от других фичей, при их некотором среднем значении.

      Есть этакий среднестатистический клиент банка «в вакууме». Как будут меняться предсказания модели в зависимости от изменения дохода?

      Тут-то на помощь и приходит библиотека SHAP.

      Рассчитываем важность фичей с помощью SHAP

      В библиотеке SHAP для оценки важности фичей рассчитываются значения Шэпли (по имени американского математика и названа библиотека).

      Для оценки важности фичи происходит оценка предсказаний модели с и без данной фичи.

      Немного предистории

      image

      Значения Шэпли идут из теории игр.

      Рассмотрим сценарий: группа людей играет в карты. Как распределить призовой фонд между ними в соответствие с их вкладом?

      Делается ряд допущений:

      • Сумма вознаграждения каждого игрока равна общей сумме призового фонда
      • Если два игрока сделали равный вклад в игру, они получают равную награду
      • Если игрок не внес никакого вклада, он не получает вознаграждения
      • Если игрок провел две игры, то его суммарное вознаграждение состоит из сумма вознаграждений за каждую из игр
      Рассмотрим пример

      Формула для расчета значения Шэпли для i-той фичи:

      — это предсказание модели с i-той фичей,
      — это предсказание модели без i-той фичи,
      — количество фичей,
      — произвольный набор фичей без i-той фичи

      Значение Шэпли для i-той фичи рассчитывается для каждого сэмпла данных (например, для каждого клиента в выборке) на всех возможных комбинациях фичей (включая отсутствие всех фичей), затем полученные значения суммируются по модулю и получается итоговая важность i-той фичи.

      Данные вычисления чрезвычайно затратны, поэтому под капотом используются различные алгоритмы оптимизации вычислений, подробнее можно посмотреть по ссылке выше на гитхабе.

      Возьмём ванильный пример из документации xgboost.

      image

      Мы хотим оценить важность фичей для предсказания, нравятся ли человеку компьютерные игры.

      В этом примере для простоты у нас есть две фичи: age (возраст) и gender (пол). Gender (пол) принимает значения 0 и 1.

      Возьмём Bobby (маленький мальчик в самом левом узле дерева) и посчитаем значение Шэпли для фичи age (возраст).

      У нас есть два набора фичей S:

      — нет фичей,
      — есть только фича пол.

      Ситуация, когда нет значений фичей

      Разные модели по-разному работают с ситуациями, когда для сэмпла данных нет фичей, то есть для всех фичей значения равны NULL.

      Будет считать в данному случае, что модель усредняет предсказания по веткам дерева, то есть предсказание без фичей будет .

      Если же мы добавим знание возраста, то предсказание модели будет .

      В итоге значение Шэпли для случая отсутствия фичей:

      Ситуация, когда знаем пол

      Для Bobby для предсказание без фичи возраст, только с фичей пол, равно . Если же мы знаем возраст, то предсказание — это самое левое дерево, то есть 2.

      В итоге значение Шэпли для этого случая:

      Суммируем

      Итогое значение Шэпли для фичи age (возраст):

      Реальный пример из бизнеса

      Библиотека SHAP обладает богатым функционалом визуализации, который помогает легко и просто объяснить модель как для бизнеса, так и для самого аналитика, чтобы оценить адекватность модели.

      На одном из проектов я анализировал отток сотрудников из компании. В качестве модели использовался xgboost.

      import shap shap_test = shap.TreeExplainer(best_model).shap_values(df) shap.summary_plot(shap_test, df, max_display=25, auto_size_plot=True) 

      Получившийся график важности фичей:

      image

      • значения слева от центральной вертикальной линии — это negative класс (0), справа — positive (1)
      • чем толще линия на графике, тем больше таких точек наблюдения
      • чем краснее точки на графике, тем выше значения фичи в ней
      • чем меньше сотруднику повышают зарплату, тем выше вероятность его ухода
      • есть регионы офисов, где отток выше
      • чем моложе сотрудник, тем выше вероятность его ухода
      • .

      Просто и удобно!

      Можно объяснить предсказание для конкретного сотрудника:

      image

      Или посмотреть зависимость предсказаний от конкретной фичи в виде 2D графика:

      image

      Можно визуализировать даже предсказания нейронных сетей на картинках:

      image

      Заключение

      Я сам узнал о SHAP значениях около полугода назад и это полностью заменило другие методы оценки важности фичей.

      • удобные визуализация и интерпретация
      • честный расчет важности фичей
      • возможность оценить фичи для конкретной подвыборки данных (например, чем отличаются наши покупатели от других клиентов в выборке), делается простым фильтром датасета в pandas и его анализом в shap, буквально пара строчек кода
      • data science
      • machine learning
      • feature importance
      • shap
      • Big Data
      • Машинное обучение

      Feature importance в sklearn и catboost на примере классических датасетов

      В данной статье будет рассмотрен пример вычисления и визуализации feature importance на классических датасетах iris и wine. Используемые ml-библиотеки: sklearn и catboost. Для визуализации будет использоваться matplotlib.

      Создание классификатора на основе имеющихся данных – частая задача в практике DS-специалиста. Все помнят один из основных минусов моделей на нейронных сетях – они плохо поддаются интерпретации. При этом, чем сложнее архитектура, тем более неожиданно могут выбираться признаки для решения задачи. Однако, классические методы машинного обучения, такие как, например, деревья решений поддаются интерпретации относительно хорошо и понять, почему модель показала такой результат, а не другой — довольно просто. Более того, можно даже узнать насколько важны те или иные параметры! Это и есть feature importance. Принцип вычисления значений для признака F следующий:

      Сравниваемые пары листьев имеют разные значения разделения в узле на пути к этим листьям. Если условие разделения выполнено (это условие зависит от функции F), объект переходит в левое поддерево, в противном случае он переходит в правое. Таким образом,

      где с1 и с2 и представляют общий вес объектов в левом и правом листьях соответственно. Этот вес равен количеству объектов в каждом листе, если веса не указаны для набора данных.

      v1 и v2 и представляет значение формулы в левом и правом листьях соответственно.

      В данной статье будет рассмотрен пример вычисления и визуализации feature importance на классических датасетах iris и wine. Используемые ml-библиотеки: sklearn и catboost. Для визуализации будет использоваться matplotlib.

      Импорт необходимых библиотек:

      from sklearn.ensemble import RandomForestClassifier import matplotlib.pyplot as plt from sklearn import datasets import pandas as pd from catboost import CatBoostClassifier, cv 

      Загрузка датасета iris:

      iris = datasets.load_iris() df_iris = pd.DataFrame(data=iris['data'], columns=iris['feature_names']) df_iris['target'] = iris['target'] df_iris.head() 

      Обучение sklearn RandomForest и построение гистограммы для визуализации важности признаков:

      model_skl_iris = RandomForestClassifier() model_skl_iris.fit(X = df_iris.drop(['target'], axis=1), y = df_iris['target']) skl_iris_imp = pd.Series(model_skl_iris.feature_importances_, df_iris.drop(['target'], axis=1).columns) fig, ax = plt.subplots(figsize=(16,14)) skl_iris_imp.plot.bar(ax=ax) ax.set_title("Важность признаков") ax.set_ylabel('Важность') fig.tight_layout() 

      Обучение catboost Classifier и построение гистограммы для визуализации важности признаков:

      model_cat_iris = CatBoostClassifier() model_cat_iris.fit(X = df_iris.drop('target', axis=1), y = df_iris['target']) cat_iris_imp = pd.Series(model_cat_iris.get_feature_importance(), df_iris.drop(['target'], axis=1).columns) fig, ax = plt.subplots(figsize=(16,14)) cat_iris_imp.plot.bar(ax=ax) ax.set_title("Важность признаков") ax.set_ylabel('Важность, %') fig.tight_layout() 

      Сравнение результатов feature importance для sklearn и catboost на iris:

      DF_iris = pd.DataFrame(, index=iris['feature_names']) fig, ax = plt.subplots(figsize=(16,14)) ax = DF_iris.plot.bar(ax=ax) ax.set_xlabel('Признак') ax.set_ylabel('Важность, %') plt.show() 

      Загрузка датасета wine:

      wine = datasets.load_wine() df_wine = pd.DataFrame(data=wine['data'], columns=wine['feature_names']) df_wine['target'] = wine['target'] df_wine.head() 

      Обучение sklearn RandomForest и построение гистограммы для визуализации важности признаков:

      model_skl_wine = RandomForestClassifier() model_skl_wine.fit(X = df_wine.drop(['target'], axis=1), y = df_wine['target']) skl_wine_imp = pd.Series(model_skl_wine.feature_importances_, df_wine.drop(['target'], axis=1).columns) fig, ax = plt.subplots(figsize=(16,14)) skl_wine_imp.plot.bar(ax=ax) ax.set_title("Важность признаков") ax.set_ylabel('Важность') fig.tight_layout() 

      Обучение catboost Classifier и построение гистограммы для визуализации важности признаков:

      model_cat_wine = CatBoostClassifier() model_cat_wine.fit(X = df_wine.drop('target', axis=1), y = df_wine['target']) cat_wine_imp = pd.Series(model_cat_wine.get_feature_importance(), df_wine.drop(['target'], axis=1).columns) fig, ax = plt.subplots(figsize=(16,14)) cat_wine_imp.plot.bar(ax=ax) ax.set_title("Важность признаков") fig.tight_layout() 

      Сравнение результатов feature importance для sklearn и catboost на wine:

      DF_wine = pd.DataFrame(, index=wine['feature_names']) fig, ax = plt.subplots(figsize=(16,14)) ax = DF_wine.plot.bar(ax=ax) ax.set_xlabel('Признак') ax.set_ylabel('Важность, %') plt.show() 

      Приведённые выше графики показывают, что на выбранных данных обе модели ведут себя схожим образом и отбирают почти одни и те же признаки, как наиболее важные.

      Полученные данные можно использовать, например, для ручного сокращения размерности данных или просто наглядного представления зависимости целевой переменной от определённых признаков.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *