How to plot specific features on SHAP summary plots?

Viewed 3244

I am currently trying to plot a set of specific features on a SHAP summary plot. However, I am struggling to find the code necessary to do so.

When looking at the source code on Github, the summary_plot function does seem to have a 'features' attribute. However, this does not seem to be the solution to my problem.

Could anybody help me plot a specific set of features, or is this not a viable option in the current code of SHAP.

3 Answers

A possible, albeit hacky, solution could be as follows, for example plotting a summary plot for a single feature in the 5th column

shap.summary_plot(shap_values[:,5:6], X.iloc[:, 5:6])

I reconstruct the shap_value to include the feature you want into the plot using below code.

shap_values = explainer.shap_values(samples)[1]

vals = np.abs(shap_values).mean(0)
feature_importance = pd.DataFrame(
    list(zip(samples.columns, vals)),
    columns=["col_name", "feature_importance_vals"],
)
feature_importance.sort_values(
    by=["feature_importance_vals"], ascending=False, inplace=True
)

feature_importance['rank'] = feature_importance['feature_importance_vals'].rank(method='max',ascending=False)

missing_features = [
    i
    for i in columns_to_show
    if i not in feature_importance["col_name"][:20].tolist()
]
missing_index = []
for i in missing_features:
    missing_index.append(samples.columns.tolist().index(i))

missing_features_new = []
rename_col = {}
for i in missing_features:
    rank = int(feature_importance[feature_importance['col_name']==i]['rank'].values)
    missing_features_new.append('rank:'+str(rank)+' - '+i)
    rename_col[i] = 'rank:'+str(rank)+' - '+i

column_names = feature_importance["col_name"][:20].values.tolist() + missing_features_new

feature_index = feature_importance.index[:20].tolist() + missing_index

shap.summary_plot(
        shap_values[:, feature_index].reshape(
            samples.shape[0], len(feature_index)
        ),
            samples.rename(columns=rename_col)[column_names],
            max_display=len(feature_index),
        )

To plot only 1 feature, get the index of your feature you want to check in list of features

i = X.iloc[:,:].index.tolist().index('your_feature_name_here')
shap.summary_plot(shap_values[1][:,i:i+1], X.iloc[:, i:i+1])

To plot your selected features,

your_feature_list = ['your_feature_1','your_feature_2','your_feature_3']
your_feature_indices = [X.iloc[:,:].index.tolist().index(x) for x in your_feature_list]
shap.summary_plot(shap_values[1][:,your_feature_indices], X.iloc[:, your_feature_indices])

feel free to change "your_feature_indices" to a shorter variable name

change shap_values[1] to shap_values if you are not doing binary classification

Related