Время прочтения: 5 мин.

В данной статье будет рассмотрен пример вычисления и визуализации 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()



Рисунок 1 — Пример данных из датасета iris

Обучение 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()
Рисунок 2 – feature importance sklearn для iris

Обучение 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()
Рисунок 3 — feature importance catboost для iris

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

DF_iris = pd.DataFrame({'Catboost' : model_cat_iris.get_feature_importance(),
                        'RForest'  : list(map(lambda x: x*100, model_skl_iris.feature_importances_))},
                       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()
Рисунок 4 – Сравнение feature importance для iris

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

wine = datasets.load_wine()
df_wine = pd.DataFrame(data=wine['data'], columns=wine['feature_names'])
df_wine['target'] = wine['target']
df_wine.head()
Рисунок 5 — Пример данных из датасета wine

Обучение 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()
Рисунок 6 — feature importance sklearn для wine

Обучение 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()
Рисунок 7 — feature importance catboost для wine

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

DF_wine = pd.DataFrame({'Catboost' : model_cat_wine.get_feature_importance(),
                        'RForest'  : list(map(lambda x: x*100, model_skl_wine.feature_importances_))}, 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()
Рисунок 8 – Сравнение feature importance для wine

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

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