Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
interaction_index = approximate_interactions(ind, shap_values, features)[0]
interaction_index = convert_name(interaction_index, shap_values, feature_names)
categorical_interaction = False
# create a matplotlib figure, if `ax` hasn't been specified.
if not ax:
figsize = (7.5, 5) if interaction_index != ind else (6, 5)
fig = pl.figure(figsize=figsize)
ax = fig.gca()
else:
fig = ax.get_figure()
# plotting SHAP interaction values
if len(shap_values.shape) == 3 and len(ind) == 2:
ind1 = convert_name(ind[0], shap_values, feature_names)
ind2 = convert_name(ind[1], shap_values, feature_names)
if ind1 == ind2:
proj_shap_values = shap_values[:, ind2, :]
else:
proj_shap_values = shap_values[:, ind2, :] * 2 # off-diag values are split in half
# TODO: remove recursion; generally the functions should be shorter for more maintainable code
dependence_plot(
ind1, proj_shap_values, features, feature_names=feature_names,
interaction_index=(None if ind1 == ind2 else ind2), display_features=display_features, ax=ax, show=False,
xmin=xmin, xmax=xmax, x_jitter=x_jitter, alpha=alpha
)
if ind1 == ind2:
ax.set_ylabel(labels['MAIN_EFFECT'] % feature_names[ind1])
else:
ax.set_ylabel(labels['INTERACTION_EFFECT'] % (feature_names[ind1], feature_names[ind2]))
)
stemlines.set_edgecolors([shap.plots.colors.red_rgb if v > 0 else shap.plots.colors.blue_rgb for v in vals])
pl.setp(stemlines, 'zorder', -1)
pl.setp(stemlines, 'linewidth', 2)
pl.setp(markerline, 'color', "black")
pl.setp(markerline, 'markersize', 4)
if show:
pl.show()
else:
return fig,ax1
# this is for a 2D partial dependence plot
else:
ind0 = convert_name(ind[0], None, feature_names)
ind1 = convert_name(ind[1], None, feature_names)
xv0 = features[:,ind0]
xv1 = features[:,ind1]
xmin0 = xmin[0] if type(xmin) is tuple else xmin
xmin1 = xmin[1] if type(xmin) is tuple else xmin
xmax0 = xmax[0] if type(xmax) is tuple else xmax
xmax1 = xmax[1] if type(xmax) is tuple else xmax
xmin0, xmax0 = compute_bounds(xmin0, xmax0, xv0)
xmin1, xmax1 = compute_bounds(xmin1, xmax1, xv1)
npoints = 20 if npoints is None else npoints
xs0 = np.linspace(xmin0, xmax0, npoints)
xs1 = np.linspace(xmin1, xmax1, npoints)
features_tmp = features.copy()
stemlines.set_edgecolors([shap.plots.colors.red_rgb if v > 0 else shap.plots.colors.blue_rgb for v in vals])
pl.setp(stemlines, 'zorder', -1)
pl.setp(stemlines, 'linewidth', 2)
pl.setp(markerline, 'color', "black")
pl.setp(markerline, 'markersize', 4)
if show:
pl.show()
else:
return fig,ax1
# this is for a 2D partial dependence plot
else:
ind0 = convert_name(ind[0], None, feature_names)
ind1 = convert_name(ind[1], None, feature_names)
xv0 = features[:,ind0]
xv1 = features[:,ind1]
xmin0 = xmin[0] if type(xmin) is tuple else xmin
xmin1 = xmin[1] if type(xmin) is tuple else xmin
xmax0 = xmax[0] if type(xmax) is tuple else xmax
xmax1 = xmax[1] if type(xmax) is tuple else xmax
xmin0, xmax0 = compute_bounds(xmin0, xmax0, xv0)
xmin1, xmax1 = compute_bounds(xmin1, xmax1, xv1)
npoints = 20 if npoints is None else npoints
xs0 = np.linspace(xmin0, xmax0, npoints)
xs1 = np.linspace(xmin1, xmax1, npoints)
features_tmp = features.copy()
x0 = np.zeros((npoints, npoints))
if feature_names is None:
feature_names = [labels['FEATURE'] % str(i) for i in range(shap_values.shape[1])]
# allow vectors to be passed
if len(shap_values.shape) == 1:
shap_values = np.reshape(shap_values, len(shap_values), 1)
if len(features.shape) == 1:
features = np.reshape(features, len(features), 1)
ind = convert_name(ind, shap_values, feature_names)
# guess what other feature as the stongest interaction with the plotted feature
if interaction_index == "auto":
interaction_index = approximate_interactions(ind, shap_values, features)[0]
interaction_index = convert_name(interaction_index, shap_values, feature_names)
categorical_interaction = False
# create a matplotlib figure, if `ax` hasn't been specified.
if not ax:
figsize = (7.5, 5) if interaction_index != ind else (6, 5)
fig = pl.figure(figsize=figsize)
ax = fig.gca()
else:
fig = ax.get_figure()
# plotting SHAP interaction values
if len(shap_values.shape) == 3 and len(ind) == 2:
ind1 = convert_name(ind[0], shap_values, feature_names)
ind2 = convert_name(ind[1], shap_values, feature_names)
if ind1 == ind2:
proj_shap_values = shap_values[:, ind2, :]
if interaction_index == "auto":
interaction_index = approximate_interactions(ind, shap_values, features)[0]
interaction_index = convert_name(interaction_index, shap_values, feature_names)
categorical_interaction = False
# create a matplotlib figure, if `ax` hasn't been specified.
if not ax:
figsize = (7.5, 5) if interaction_index != ind else (6, 5)
fig = pl.figure(figsize=figsize)
ax = fig.gca()
else:
fig = ax.get_figure()
# plotting SHAP interaction values
if len(shap_values.shape) == 3 and len(ind) == 2:
ind1 = convert_name(ind[0], shap_values, feature_names)
ind2 = convert_name(ind[1], shap_values, feature_names)
if ind1 == ind2:
proj_shap_values = shap_values[:, ind2, :]
else:
proj_shap_values = shap_values[:, ind2, :] * 2 # off-diag values are split in half
# TODO: remove recursion; generally the functions should be shorter for more maintainable code
dependence_plot(
ind1, proj_shap_values, features, feature_names=feature_names,
interaction_index=(None if ind1 == ind2 else ind2), display_features=display_features, ax=ax, show=False,
xmin=xmin, xmax=xmax, x_jitter=x_jitter, alpha=alpha
)
if ind1 == ind2:
ax.set_ylabel(labels['MAIN_EFFECT'] % feature_names[ind1])
else:
ax.set_ylabel(labels['INTERACTION_EFFECT'] % (feature_names[ind1], feature_names[ind2]))
The names of the features in the shap_values array.
method : "pca" or numpy.array
How to reduce the dimensions of the shap_values to 2D. If "pca" then the 2D
PCA projection of shap_values is used. If a numpy array then is should be
(# samples x 2) and represent the embedding of that values.
alpha : float
The transparency of the data points (between 0 and 1). This can be useful to the
show density of the data points when using a large dataset.
"""
if feature_names is None:
feature_names = [labels['FEATURE'] % str(i) for i in range(shap_values.shape[1])]
ind = convert_name(ind, shap_values, feature_names)
if ind == "sum()":
cvals = shap_values.sum(1)
fname = "sum(SHAP values)"
else:
cvals = shap_values[:,ind]
fname = feature_names[ind]
# see if we need to compute the embedding
if type(method) == str and method == "pca":
pca = sklearn.decomposition.PCA(2)
embedding_values = pca.fit_transform(shap_values)
elif hasattr(method, "shape") and method.shape[1] == 2:
embedding_values = method
else:
print("Unsupported embedding method:", method)