- BrainTools - https://www.braintools.ru -
Метод SHAP (SHapley Additive exPlanations), опирающийся на классическую теорию игр, утвердился в качестве стандарта для оценки значимости признаков в моделях машинного обучения [1]. В задачах бинарной классификации процесс построения графиков waterfall plot или beeswarm plot достаточно тривиален и подробно описан в документации.
Однако при переходе к многоклассовой классификации возникают сложности, связанные с изменением размерности выходных данных. Прямое применение стандартного кода к многомерным выходным данным часто приводит к ошибкам несовпадения размерностей или некорректной интерпретации результатов.
В данной статье рассматриваются технические нюансы работы с SHAP в многоклассовых задачах и предлагается проверенное решение на языке Python. В качестве прикладного примера используется исследование 2025 года, опубликованное в журнале Measurement (Luo et al., “Thermodynamic simulation-assisted random forest: Towards explainable fault diagnosis of combustion chamber components of marine diesel engines“), где авторы реализовали интерпретируемую диагностику 14 категорий состояния судовых двигателей.
Репозиторий проекта на GitHub: https://github.com/TS-RF/TSRF [2]
Основное препятствие при переходе от бинарных моделей к многоклассовым заключается в структуре переменной shap_values.
Бинарная классификация или регрессия: Переменная shap_values представляет собой матрицу размерностью (n_samples, n_features). Каждое значение является скаляром, отражающим вклад признака в прогноз.
Многоклассовая классификация: shap_values преобразуется в трехмерный тензор (или список матриц) размерностью (n_samples, n_features, n_classes).
Логическое различие: В многоклассовых моделях выходной слой генерирует не одно значение, а распределение вероятностей (или логитов) по всем классам. Следовательно, SHAP вычисляет вклад каждого признака отдельно для каждого целевого класса. Если передать трехмерный массив в функцию визуализации без предварительной обработки, интерпретатор не сможет определить, для какого именно класса требуется построить график, что приведет к исключению.
Для корректной работы требуется выполнить срез данных (slicing) по оси классов. Ниже представлена программная реализация, адаптированная под требования научных публикаций.

Различные методы визуализации в библиотеке SHAP предъявляют разные требования к формату входных данных:
shap.plots.waterfall: требует объект Explanation, содержащий базовые значения и данные.
shap.summary_plot: лучше работает с массивами формата numpy.array.
import shap
import matplotlib.pyplot as plt
import numpy as np
# Настройки графиков для соответствия академическим стандартам
plt.rcParams['font.family'] = 'Arial'
plt.rcParams['font.size'] = '24'
plt.rcParams['axes.unicode_minus'] = False
# Предполагается, что best_model — обученная модель (Random Forest, XGBoost и т.д.)
# X_train, X_test — соответствующие наборы данных Pandas DataFrame
# 1. Расчет значений SHAP в формате Numpy (для глобального анализа)
explainer_tree = shap.TreeExplainer(best_model)
shap_values_numpy = explainer_tree.shap_values(X_train)
# В многоклассовых задачах это обычно список массивов длиной n_classes
# 2. Создание объекта Explanation (для локального анализа, например, waterfall plot)
explainer_obj = shap.Explainer(best_model, X_test)
shap_values_obj = explainer_obj(X_test)
# Размерность shap_values_obj.values: (n_samples, n_features, n_classes)
График waterfall plot используется для объяснения причин прогноза конкретного класса для отдельно взятого образца. Необходимо зафиксировать индекс класса через срез [:, class_idx].
# --- (a) Waterfall Plot: атрибуция для одного образца ---
class_idx = 4 # Индекс целевого класса (например, тип неисправности F4)
sample_idx = 3 # Индекс конкретного образца
plt.figure()
# Срез объекта Explanation для конкретного образца и класса
shap.plots.waterfall(
shap_values_obj[sample_idx, :, class_idx],
max_display=9,
show=False
)
# Оформление графика
ax = plt.gca()
ax.set_xlabel(ax.get_xlabel(), fontsize=36)
ax.set_ylabel(ax.get_ylabel(), fontsize=36)
ax.spines['bottom'].set_linewidth(3)
plt.show()
График beeswarm plot демонстрирует общее распределение влияния признаков на выход модели. Для многоклассовых задач данные передаются в виде shap_values_numpy[…, class_idx].
# --- (b) Beeswarm Plot: глобальное распределение признаков ---
class_idx = 5
plt.figure(figsize=(10, 8))
shap.summary_plot(
shap_values_numpy[..., class_idx],
X_train,
feature_names=X_train.columns,
plot_type="dot",
show=False
)
# Настройка цветовой шкалы (Color Bar)
cbar = plt.gcf().axes[-1]
cbar.set_ylabel('Parameter Value', fontsize=24)
cbar.tick_params(labelsize=20)
plt.show()
В статьях высокого уровня часто объединяют столбчатую диаграмму важности и график beeswarm plot. Это достигается через использование двойной оси (twiny) в matplotlib.
# --- (c) Составной график (Beeswarm + Bar Importance) ---
class_idx = 5
fig, ax1 = plt.subplots(figsize=(10, 8))
# 1. Отрисовка beeswarm plot (основной слой)
shap.summary_plot(
shap_values_numpy[..., class_idx],
X_train,
feature_names=X_train.columns,
plot_type="dot",
show=False,
color_bar=True
)
plt.gca().set_position([0.2, 0.2, 0.65, 0.65])
# 2. Отрисовка столбчатой диаграммы важности на вторичной оси
ax2 = ax1.twiny()
shap.summary_plot(
shap_values_numpy[..., class_idx],
X_train,
plot_type="bar",
show=False
)
plt.gca().set_position([0.2, 0.2, 0.65, 0.65])
# Настройка прозрачности столбцов
bars = ax2.patches
for bar in bars:
bar.set_color('#CCE5FB')
bar.set_alpha(0.4)
# Стандартизация подписей осей
ax1.set_xlabel(f'Shapley Value Contribution (F{class_idx})', fontsize=24, labelpad=5)
ax2.set_xlabel('Mean Shapley Value (Parameter Importance)', fontsize=24, labelpad=10)
ax2.xaxis.set_label_position('top')
ax2.xaxis.tick_top()
# Управление слоями: точки должны быть поверх столбцов
ax1.set_zorder(ax1.get_zorder() + 1)
ax1.patch.set_visible(False)
plt.show()
При использовании SHAP для многоклассовых задач ключевыми являются следующие аспекты:
Контроль размерности: необходимо учитывать трехмерную структуру тензора значений SHAP и использовать срезы […, class_idx] для анализа конкретных классов.
Совместимость интерфейсов: следует различать использование объектов Explanation для локальных графиков и массивов Numpy для глобальных сводных диаграмм.
Информативность визуализации: применение комбинированных графиков позволяет наглядно представить как среднюю важность признаков, так и характер их влияния на прогноз, что соответствует стандартам ведущих научных журналов.
[1] Luo C, Zhao M, Fu X, et al. Thermodynamic simulation-assisted random forest: Towards explainable fault diagnosis of combustion chamber components of marine diesel engines[J]. Measurement, 2025, 251: 117252.
Автор: CiCiR
Источник [4]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/25862
URLs in this post:
[1] обучения: http://www.braintools.ru/article/5125
[2] https://github.com/TS-RF/TSRF: https://github.com/TS-RF/TSRF
[3] Image: https://sourcecraft.dev/
[4] Источник: https://habr.com/ru/articles/1000994/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1000994
Нажмите здесь для печати.