SHAP: Как интерпретировать ожидаемые значения для force_plot?

Я пытаюсь создать force_plot для моей модели Random Forest с двумя классами (1 и 2), но я немного запутался в параметрах force_plot.

У меня есть два разных параметра force_plot, я могу предоставить следующее:

shap.force_plot(explainer.expected_value[0], shap_values[0], choosen_instance, show=True, matplotlib=True)

ожидаемые значения и значения формы: 0

shap.force_plot(explainer.expected_value[1], shap_values[1], choosen_instance, show=True, matplotlib=True)

ожидаемые и формирующие значения: 1

Итак, мои вопросы:

  1. При создании force_plot я должен указать ожидаемое_значение. Для моей модели у меня есть два ожидаемых значения: [0,20826239 0,79173761], как мне узнать, какое использовать? Мое понимание ожидаемого значения состоит в том, что это средний прогноз моей модели на данных о поездах. Есть ли два значения, потому что у меня есть и class_1, и class_2? Итак, для класса_1 средний прогноз равен 0,20826239, а для класса_2 — 0,79173761?

  2. Следующий параметр — это shap_values ​​для выбранного экземпляра:

        index   B    G    R    Prediction
       113833  107  119  237      2
    

Я получаю следующие значения SHAP_values:

[array([[ 0.01705462, -0.01812987,  0.23416978]]), 
 array([[-0.01705462,  0.01812987, -0.23416978]])]

Я не совсем понимаю, почему я получаю два набора значений SHAP? Один для class_1 и один для class_2? Я пытался сравнить изображения, которые я приложил, учитывая оба набора значений SHAP и ожидаемое значение, но я не могу объяснить, что происходит с точки зрения прогноза.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Попробуем воспроизвести:

from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from shap import TreeExplainer
from shap.maskers import Independent
from scipy.special import expit, logit

X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)

model = RandomForestClassifier(max_depth=5, n_estimators=100).fit(X_train, y_train)

Затем ваши ожидаемые значения SHAP:

masker = Independent(data = X_train)
explainer = TreeExplainer(model, data=masker)
ev = explainer.expected_value
ev

array([0.35468973, 0.64531027])

Это то, что ваша модель будет предсказывать в среднем с учетом фонового набора данных (представленного пояснителю выше):

model.predict_proba(masker.data).mean(0)

array([0.35468973, 0.64531027])

Затем, если у вас есть интересующая точка данных:

data_to_explain = X_train[[0]]
model.predict_proba(data_to_explain)  

array([[0.00470234, 0.99529766]])

Вы можете добиться того же самого со значениями SHAP:

sv = explainer.shap_values(data_to_explain)
np.array(sv).sum(2).ravel() 

array([-0.34998739,  0.34998739])

Обратите внимание, они симметричны, потому что то, что увеличивает шансы на класс 1, уменьшает шансы на 0 на ту же величину.

С базовыми значениями и значениями SHAP вероятности (или шансы того, что точка данных окажется в листе 0 или 1):

ev + np.array(sv).sum(2).ravel()

array([0.00470234, 0.99529766])

Обратите внимание, что это то же самое, что и предсказания модели.

@Penguines Это отвечает на твой вопрос? У вас остались вопросы? Если да/нет, рассмотрите возможность принятия/проголосования за ответ.

Sergey Bushmanov 24.03.2022 04:24

Привет Сергей, спасибо за отличный ответ. Я все еще не уверен, следует ли мне использовать первое или второе значение массива из shap_values, это просто зависит от того, хочу ли я показать шансы на класс 0 или 1? Я вижу, что они симметричны, но допустим, я хочу использовать значения shap, чтобы найти сходство, тогда я бы просто выбрал shap_values[0] или shap_values[1]?

Penguines 27.03.2022 12:56

Я не совсем понимаю. Значения Shap предназначены для объяснения оценок, полученных с помощью моделей (на основе подхода теории игр, предложенного Шепли). Что вы имеете в виду «использовать значения формы для поиска сходства»? Как я себе это представляю, у вас будет одна оценка сходства и m sv (массив n-точек данных x m-функций).

Sergey Bushmanov 27.03.2022 15:08

Да, извините, я понимаю основы, но я имел в виду, что если, например, я хочу найти сходство между объяснениями, чтобы, возможно, сгруппировать их (используя некоторую меру расстояния), я бы использовал либо shap_values[0], либо shap_values[1]? Единственная разница между ними заключается в том, хочу ли я показать шансы на 0 или 1, поэтому имеет ли значение, что я использую, если это просто измерение того, насколько близко точка X находится к точке Y?

Penguines 27.03.2022 17:32

Другие вопросы по теме