从SHAP值中获取特征重要性

12

我希望获得一个重要特征的数据框。使用以下代码,我已经获得了shap_values,但我不确定这些值的含义。我的数据框中有142个特征和67个实验,但是我得到了大约2500个值的数组。

explainer = shap.TreeExplainer(rf)
shap_values = explainer.shap_values(X_test)

shap.summary_plot(shap_values, X_test, plot_type="bar")

输入图像描述在这里

我已经尝试将它们存储在一个df中:

rf_resultX = pd.DataFrame(shap_values, columns = ['shap_values'])

但是得到了错误信息:ValueError: 传递的值的形状为(18, 142),但索引表明它应该是(18, 1)

142 - 特征的数量。 18 - 我不知道。

我认为它的运作方式如下:

  • shap_values需要平均。
  • 并与特征名称配对:pd.DataFrame(feature_names, columns = ['feature_names'])

有人有解释shap_values的经验吗? 起初我认为,数值的数量是特征数乘以行数。

5个回答

11

按照另外两个答案的方法组合,我成功地解决了问题。

feature_names = X_train.columns


rf_resultX = pd.DataFrame(shap_values, columns = feature_names)

vals = np.abs(rf_resultX.values).mean(0)

shap_importance = pd.DataFrame(list(zip(feature_names, vals)),
                                  columns=['col_name','feature_importance_vals'])
shap_importance.sort_values(by=['feature_importance_vals'],
                               ascending=False, inplace=True)
shap_importance.head()

4
我为此编写了一个简短的函数,它也适用于多类分类。该函数期望数据以 pandas DataFrame 的形式提供,以每个类别一个 shap 值数组的列表形式提供,并可选择提供要计算平均 shap 值的列的列表。
explainer = shap.TreeExplainer(model)  
shap_values = explainer.shap_values(X)


def shap_feature_ranking(data, shap_values, columns=[]):
    if not columns: columns = data.columns.tolist()     # If columns are not given, take all columns
    
    c_idxs = []
    for column in columns: c_idxs.append(data.columns.get_loc(column))  # Get column locations for desired columns in given dataframe
    if isinstance(shap_values, list):   # If shap values is a list of arrays (i.e., several classes)
        means = [np.abs(shap_values[class_][:, c_idxs]).mean(axis=0) for class_ in range(len(shap_values))]  # Compute mean shap values per class 
        shap_means = np.sum(np.column_stack(means), 1)  # Sum of shap values over all classes 
    else:                               # Else there is only one 2D array of shap values
        assert len(shap_values.shape) == 2, 'Expected two-dimensional shap values array.'
        shap_means = np.abs(shap_values).mean(axis=0)
    
    # Put into dataframe along with columns and sort by shap_means, reset index to get ranking
    df_ranking = pd.DataFrame({'feature': columns, 'mean_shap_value': shap_means}).sort_values(by='mean_shap_value', ascending=False).reset_index(drop=True)
    df_ranking.index += 1
    return df_ranking

4

shap_values的shape为(num_rows, num_features); 如果你想将其转换为dataframe,你需要将特征名列表传递给columns参数:rf_resultX = pd.DataFrame(shap_values, columns = feature_names).

每个样本都有自己的shap值,用于表示该特征对于该特定样本的预测有多大贡献; 这被称为局部解释。您可以对每个特征的shap值进行平均以了解全局特征重要性,但我建议您查看文档,因为shap软件包本身提供了更强大的可视化/解释功能。


非常感谢!它按照我所希望的方式工作。您使用文档是正确的。 - Parsyk
2
这里也有我原来问题的答案:vals= np.abs(shap_values).mean(0) feature_importance = pd.DataFrame(list(zip(X_train.columns,vals)),columns=['col_name','feature_importance_vals']) feature_importance.sort_values(by=['feature_importance_vals'],ascending=False,inplace=True) feature_importance.head() - Parsyk
API已经改变,请随意更新答案。 - Manu Valdés
@ManuValdés - 你知道如何将SHAP本地解释导出到数据框中吗?可以帮我吗?https://dev59.com/bcPra4cB1Zd3GeqPuP9N - The Great

4

From https://github.com/slundberg/shap/issues/632

vals = np.abs(shap_values.values).mean(0)
feature_names = train_x.columns()

feature_importance = pd.DataFrame(list(zip(feature_names, vals)),
                                 columns=['col_name','feature_importance_vals'])
feature_importance.sort_values(by=['feature_importance_vals'],
                              ascending=False, inplace=True)
feature_importance.head()

2
为了避免进一步的建议编辑尝试:a)这是一个引用; b)原始的GitHub问题不断更新,我们可以看到正确答案取决于shap软件包版本。 - banderlog013

3

针对最新版本0.40.0:

    feature_names = shap_values.feature_names
    shap_df = pd.DataFrame(shap_values.values, columns=feature_names)
    vals = np.abs(shap_df.values).mean(0)
    shap_importance = pd.DataFrame(list(zip(feature_names, vals)), columns=['col_name', 'feature_importance_vals'])
    shap_importance.sort_values(by=['feature_importance_vals'], ascending=False, inplace=True)

当我使用 shap_values.feature_names 时, 我会得到一个 AttributeError:'numpy.ndarray' 对象没有 'feature_names' 属性。 - Maths12
shap_values是一个列表。 - ABCD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接