2

我有一个基因数据集,其中行的索引是基因的名称。我还希望找到任何给定基因的行号,以便在基因通过机器学习模型预测后单独查看基因 - 以解释基因的预测。我如何为 shap 图编码目前需要一个行号来提取特定基因。

我的数据如下所示:

Index   Feature1  Feature2   ... FeatureN
Gene1     1           0.2          10
Gene2     1           0.1          7
Gene3     0           0.3          10

例如,如果我想拉出并查看模型预测,Gene3我会这样做:

import shap
shap.initjs()

xgbr = xgboost.XGBRegressor()

def shap_plot(j):
    explainerModel = shap.TreeExplainer(xgbr)
    shap_values_Model = explainerModel.shap_values(X_train)
    p = shap.force_plot(explainerModel.expected_value, shap_values_Model[j], X_train.iloc[[j]],feature_names=df.columns)
    return(p)

shap_plot(3)

shap_plot(3)对我来说是个问题,因为我实际上不知道我想要的基因是否在打乱的训练或测试数据的第 3 行。

有没有办法从已知的基因索引中提取行号?或者可能重新编码我的 shap 图,以便它接受我的字符串索引?我有生物学背景,所以任何指导将不胜感激。

4

3 回答 3

2

试试下面的。df 是您的数据框,结果将为您提供给定基因的行号(第一行将产生 1 等)

list(df.index).index('Gene3')+1

#result

3
于 2020-10-09T11:19:37.873 回答
0

有很多方法可以获取与索引值或列值关联的行号。

如果您的基因实际上位于名为"Index"example 的列中,您可以这样做:

x_train[x_train["Index"] == "gene3"].index + 1

如果没有,您总是可以通过调用reset_index()您的数据框来实现。

另一种选择是在数据框中创建一个从 1 到 n 的新列,例如

mapping = x_train.assign(index_number=range(x_train.shape[0]))["index_number"]

现在mapping应该是这样的:

Index   index_mapping 
Gene1     0           
Gene2     1           
Gene3     2           

并且调用mapping["Gene2"]应该返回1

除此之外,我注意到您正在使用力图。我建议你阅读这篇文章,了解为什么 shap 用决策图代替了它们。

另外,每次调用函数时都在重新构建树解释器。这非常低效,为什么不构建一次,然后多次查询:

class ShapPlotter:
    def __init__(self, model, x_train):
        self.explainer_model = shap.TreeExplainer(model)
        self.shap_values_Model = self.explainer_model.shap_values(x_train)
        self.gene_index_mapping = x_train.assign(index_value=range(x_train.shape[0]))["index_value"]

    def plot(gene):
        idx = self._get_index(gene)
        shap_plot = shap.force_plot(...) # replace j with idx here
        return shap_plot

    def _get_index(gene: str) -> int:
        # your choice of method here. e.g. https://stackoverflow.com/a/64279019/1011724
        # in this case, I built a mapping series in the __init__ fn so you can get the index number by just indexing directly with the gene string: 
        return self.gene_index_mapping.loc[gene]
于 2020-10-09T11:36:09.220 回答
0
list(df[df.Index=='Gene3'].index)
于 2020-10-09T11:40:24.860 回答