• 特定时点的c-index


    关注 码龄 粉丝数 原力等级 -- 被采纳 被点赞 采纳率 2301_81337622 2024-04-16 19:47 采纳率: 0% 浏览 0 首页/ 编程语言 / 特定时点的c-index python深度学习 import warnings import numpy as np import pandas as pd from pycox.evaluation.concordance import concordance_td from pycox.evaluation import ipcw, admin from pycox import utils class EvalSurv: """Class for evaluating predictions. Arguments: surv {pd.DataFrame} -- Survival predictions. durations {np.array} -- Durations of test set. events {np.array} -- Events of test set. Keyword Arguments: censor_surv {str, pd.DataFrame, EvalSurv} -- Censoring distribution. If provided data frame (survival function for censoring) or EvalSurv object, this will be used. If 'km', we will fit a Kaplan-Meier to the dataset. (default: {None}) censor_durations {np.array}: -- Administrative censoring times. (default: {None}) steps {str} -- For durations between values of `surv.index` choose the higher index 'pre' or lower index 'post'. For a visualization see `help(EvalSurv.steps)`. (default: {'post'}) """ def __init__(self, surv, durations, events, censor_surv=None, censor_durations=None, steps='post'): assert (type(durations) == type(events) == np.ndarray), 'Need `durations` and `events` to be arrays' self.surv = surv self.durations = durations self.events = events self.censor_surv = censor_surv self.censor_durations = censor_durations self.steps = steps assert pd.Series(self.index_surv).is_monotonic @property def censor_surv(self): """Estimated survival for censorings. Also an EvalSurv object. """ return self._censor_surv @censor_surv.setter def censor_surv(self, censor_surv): if isinstance(censor_surv, EvalSurv): self._censor_surv = censor_surv elif type(censor_surv) is str: if censor_surv == 'km': self.add_km_censor() else: raise ValueError(f"censor_surv cannot be {censor_surv}. Use e.g. 'km'") elif censor_surv is not None: self.add_censor_est(censor_surv) else: self._censor_surv = None @property def index_surv(self): return self.surv.index.values @property def steps(self): """How to handle predictions that are between two indexes in `index_surv`. For a visualization, run the following: ev = EvalSurv(pd.DataFrame(np.linspace(1, 0, 7)), np.empty(7), np.ones(7), steps='pre') ax = ev[0].plot_surv() ev.steps = 'post' ev[0].plot_surv(ax=ax, style='--') ax.legend(['pre', 'post']) """ return self._steps @steps.setter def steps(self, steps): vals = ['post', 'pre'] if steps not in vals: raise ValueError(f"`steps` needs to be {vals}, got {steps}") self._steps = steps def add_censor_est(self, censor_surv, steps='post'): """Add censoring estimates so one can use inverse censoring weighting. `censor_surv` are the survival estimates trained on (durations, 1-events), Arguments: censor_surv {pd.DataFrame} -- Censor survival curves. Keyword Arguments: round {str} -- For durations between values of `surv.index` choose the higher index 'pre' or lower index 'post'. If `None` use `self.steps` (default: {None}) """ if not isinstance(censor_surv, EvalSurv): censor_surv = self._constructor(censor_surv, self.durations, 1-self.events, None, steps=steps) self.censor_surv = censor_surv return self def add_km_censor(self, steps='post'): """Add censoring estimates obtained by Kaplan-Meier on the test set (durations, 1-events). """ km = utils.kaplan_meier(self.durations, 1-self.events) surv = pd.DataFrame(np.repeat(km.values.reshape(-1, 1), len(self.durations), axis=1), index=km.index) return self.add_censor_est(surv, steps) @property def censor_durations(self): """Administrative censoring times.""" return self._censor_durations @censor_durations.setter def censor_durations(self, val): if val is not None: assert (self.durations[self.events == 0] == val[self.events == 0]).all(),\ 'Censored observations need same `durations` and `censor_durations`' assert (self.durations[self.events == 1] <= val[self.events == 1]).all(),\ '`durations` cannot be larger than `censor_durations`' if (self.durations == val).all(): warnings.warn("`censor_durations` are equal to `durations`." + " `censor_durations` are likely wrong!") self._censor_durations = val else: self._censor_durations = val @property def _constructor(self): return EvalSurv def __getitem__(self, index): if not (hasattr(index, '__iter__') or type(index) is slice) : index = [index] surv = self.surv.iloc[:, index] durations = self.durations[index] events = self.events[index] new = self._constructor(surv, durations, events, None, steps=self.steps) if self.censor_surv is not None: new.censor_surv = self.censor_surv[index] return new def plot_surv(self, **kwargs): """Plot survival estimates. kwargs are passed to `self.surv.plot`. """ if len(self.durations) > 50: raise RuntimeError("We don't allow to plot more than 50 lines. Use e.g. `ev[1:5].plot()`") if 'drawstyle' in kwargs: raise RuntimeError(f"`drawstyle` is set by `self.steps`. Remove from **kwargs") return self.surv.plot(drawstyle=f"steps-{self.steps}", **kwargs) def idx_at_times(self, times): """Get the index (iloc) of the `surv.index` closest to `times`. I.e. surv.loc[tims] (almost)= surv.iloc[idx_at_times(times)]. Useful for finding predictions at given durations. """ return utils.idx_at_times(self.index_surv, times, self.steps) def _duration_idx(self): return self.idx_at_times(self.durations) def surv_at_times(self, times): idx = self.idx_at_times(times) return self.surv.iloc[idx] # def prob_alive(self, time_grid): # return self.surv_at_times(time_grid).values def concordance_td(self, method='adj_antolini'): """Time dependent concorance index from Antolini, L.; Boracchi, P.; and Biganzoli, E. 2005. A time-dependent discrimination index for survival data. Statistics in Medicine 24:3927–3944. If 'method' is 'antolini', the concordance from Antolini et al. is computed. If 'method' is 'adj_antolini' (default) we have made a small modifications for ties in predictions and event times. We have followed step 3. in Sec 5.1. in Random Survival Forests paper, except for the last point with "T_i = T_j, but not both are deaths", as that doesn't make much sense. See 'metrics._is_concordant'. Keyword Arguments: method {str} -- Type of c-index 'antolini' or 'adj_antolini' (default {'adj_antolini'}). Returns: float -- Time dependent concordance index. """ return concordance_td(self.durations, self.events, self.surv.values, self._duration_idx(), method) 根据以上的代码,我想在evalsurv类下创建一个子类MyEvalSurv,在这里定义一个可以计算特定时点的c-index的函数用于计算 应该怎么写代码 展开全部 收起 写回答 好问题 0 提建议 追加酬金 关注问题 微信扫一扫 点击复制链接 分享 邀请回答 编辑 收藏 删除 结题 收藏 举报 追加酬金 (90%的用户在追加酬金后获得了解决方案) 当前问题酬金 ¥ 0 (可追加 ¥500) ¥ 15¥ 20¥ 50¥ 100¥ 200 支付方式 扫码支付 二维码出错 点击刷新 支付金额 15 元 提供问题酬金的用户不参与问题酬金结算和分配 支付即为同意 《付费问题酬金结算规则》 结题 再想想 删除 再等等

    3条回答 默认 最新

    • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-16 19:47
      关注

      引自免费微信小程序:皆我百晓生

      要在EvalSurv类下创建一个名为MyEvalSurv的子类,并添加一个计算特定时点C-index的方法,你需要遵循以下步骤:

      首先,导入必要的库并定义MyEvalSurv类继承自EvalSurv

      import warnings
      import numpy as np
      import pandas as pd
      from pycox.evaluation.concordance import concordance_td
      from pycox.evaluation import ipcw, admin
      from pycox import utils
      
      class MyEvalSurv(EvalSurv):
          """Subclass of EvalSurv with added functionality for calculating specific-time c-index."""
          ...
      

      接着,为了实现特定时点C-index的计算,我们需要定义一个新的方法,例如concordance_at_time_point。这个方法将接受一个时间点作为输入参数,并返回该时间点上的C-index。

          def concordance_at_time_point(self, time_point):
              idx = self.idx_at_times([time_point])
              surv_at_time = self.surv_at_times(time_point)
              events_at_time = self.events[idx]
              durations_at_time = self.durations[idx]
      
              return concordance_td(durations_at_time, events_at_time, surv_at_time.values, idx, method='adj_antolini')
      

      在这个新方法中,我们首先找到给定时间点对应的索引,然后获取该时间点的生存预测、事件标记和持续时间。之后,我们可以调用concordance_td函数来计算特定时间点的C-index。

      现在,MyEvalSurv类已经具备了计算特定时点C-index的能力。你可以像下面这样实例化这个类并使用新的方法:

      # 假设你已经有了surv, durations, events数据
      my_eval_surv = MyEvalSurv(surv, durations, events)
      
      # 计算特定时间点(比如5)的C-index
      c_index_5 = my_eval_surv.concordance_at_time_point(5)
      print(f"C-index at time point 5: {c_index_5}")
      

      这将会输出在时间点5处的C-index值。请注意,确保提供的surv, durations, 和 events 数据与EvalSurv类的要求一致。

      展开全部

      评论 编辑记录
    • Kwan的解忧杂货铺 Java领域优质创作者 2024-04-16 19:47
      关注

      晚上好🌙🌙🌙
      本答案参考ChatGPT-3.5

      请问您对代码的哪一部分有疑问呢?请具体说明或提出问题,以便我能更好地为您提供帮助。

      评论
      2301_81337622 2024-04-16 19:48

      根据以上的代码,我想在evalsurv类下创建一个子类MyEvalSurv,在这里定义一个可以计算特定时点的c-index的函数用于计算 应该怎么写代码

      回复
    • GISer Liu 2024-04-16 20:14
      关注

      该回答引用自GPT-3.5,由博主GISer Liu编写:

      问题描述中提到了一个 assert 语句失败的问题,其错误信息为:
      luaCopy code

      assert pd.Series(self.index_surv).is_monotonic
      

      这个 assert 的作用是检查 self.index_surv 是否单调递增,如果不是则会触发 AssertionError。由于没有提供具体的错误信息,我会假设这个 assert 在运行时触发了 AssertionError,下面是我对这个问题的解决思路和解决方案:

      解决思路:

      1. 确认 self.index_surv 是一个单调递增的数组。
      2. 检查 self.index_surv 的内容,确保其符合预期。
      3. 如果 self.index_surv 不是单调递增的,找出导致这种情况的原因并加以修正。

        解决方案:

      4. 确认 self.index_surv 是否单调递增的方法是通过输出其内容并手动检查。我们可以在 __init__ 方法中添加一行代码来输出 self.index_surv,以便检查其内容。
      5. 如果确认 self.index_surv 不是单调递增的,我们需要检查生成该属性的逻辑,找出可能导致其非单调递增的原因。
      6. 在确定了问题原因后,可以采取适当的措施来修正,例如在生成 self.index_surv 的逻辑中添加排序操作,以确保其单调递增。
        下面是具体的代码修改建议:
        pythonCopy code
        class EvalSurv:
        def __init__(self, surv, durations, events, censor_surv=None, censor_durations=None, steps='post'):
        assert (type(durations) == type(events) == np.ndarray), 'Need `durations` and `events` to be arrays'
        self.surv = surv
        self.durations = durations
        self.events = events
        self.censor_surv = censor_surv
        self.censor_durations = censor_durations
        self.steps = steps
        # 输出 self.index_surv,用于检查内容是否符合预期
        print("self.index_surv:", self.index_surv)  
        @property
        def index_surv(self):
        return self.surv.index.values
        ...
        
        在添加了以上代码后,重新运行程序并查看输出,检查 self.index_surv 的内容是否符合预期。如果不符合预期,则需要进一步检查生成
        self.index_surv 的逻辑并进行修正。

      如果该回答解决了您的问题,请采纳!如果没有,请私信联系或评论您的疑惑

      展开全部

      评论
    编辑
    预览

    报告相同问题?

  • 相关阅读:
    智能与人机融合智能的思考
    Linux CentOS 8.x 生成rsa公私密钥
    电脑页面不能全屏怎么办?Win11页面不能全屏的解决方法
    【leetcode】仅仅反转字母 c++
    【前端笔记】HBuilderX通过微信开发者工具预览打开不了探索过程
    SpringBoot启动失败报错,spring.profiles.active:@env@中环境变量@无法识别报错_active: @env@
    新版ui周易测算网站H5源码/在线起名网站源码/运势测算网站系统源码,附带系统搭建教程
    [论文阅读]A ConvNet for the 2020s
    多通道反向字典模型
    快速掌握并发编程---深入学习ThreadLocal
  • 原文地址:https://ask.csdn.net/questions/8089554