Как получить функцию плотности вероятности из CoxPHSurvivalAnalysis в scikit-survival?

Я использую sksurv.linear_model.CoxPHSurvivalAnasis для соответствия регрессии ph рулевого управления и хотел бы восстановить функцию плотности f(t). Класс sksurv имеет методы для прогнозирования функции выживания и кумулятивной функции распределения S(t) = 1-F(t) и кумулятивной функции риска $H(t)$, но, похоже, он не создает функцию плотности.

В моем варианте использования цензура отсутствует, поэтому вот пример:

import pandas as pd
import numpy as np
from sksurv.linear_model import CoxPHSurvivalAnalysis

data = np.random.randint(5,30,size=10)
X_train = pd.DataFrame(data, columns=['covariate'])

y_train = np.array(np.random.randint(0,100,size=10)/100,dtype=[('status',bool),('target',float)])

estimator = CoxPHSurvivalAnalysis()
estimator.fit(X_train,y_train)

X_test = pd.DataFrame({'covariate':[12,2]})
chf = estimator.predict_cumulative_hazard_function(X_test)
cdf = estimator.predict_survival_function(X_test)

fig, ax = plt.subplots(1,2)
for fn_h, fn_c in zip(chf, cdf):
    ax[0].step(fn_h.x,fn_h(fn_h.x),where='post')
    ax[1].step(fn_c.x,fn_c(fn_c.x),where='post')

ax[0].set_title('Cumulative Hazard Functions')
ax[1].set_title('Survival Functions')
plt.show()


Как я могу получить доступ к функции плотности и построить ее график?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
70
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Функцию плотности вероятности (PDF) можно получить из кумулятивной функции распределения (CDF) как:

f(t) = dF(t)/dt

Теперь в анализе выживания (SA) PDF (f(t)) можно выразить через функцию выживания S(t) и функцию риска h(t), которая определяется следующим образом:

f(t) = h(t) x S(t)

где S(t) = 1 - F(t) и h(t) = -dS(t)/dt x S(t) = dH(t)/dt

Итак, PDF f(t) можно выразить как: f(t) = dH(t)/dt x S(t)

Теперь, чтобы вычислить функцию риска f(t), нам нужна производная кумулятивной функции риска (CHF) H(t). Поскольку все CHF являются дискретными точками данных, нам нужен InterpolatedUnivariateSpline из библиотеки scipy, чтобы дифференцировать их. Он создает плавную сплайн-интерполяцию CHF, которую затем можно дифференцировать, чтобы получить h(t). Вот небольшая модификация вставленного кода:

# Import the necessary libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sksurv.linear_model import CoxPHSurvivalAnalysis
from scipy.interpolate import InterpolatedUnivariateSpline

# Define a function to compute the probability density function (pdf) 
# from the cumulative hazard function (chf) and survival function (sf).
def compute_pdf_from_chf_and_sf(chf, sf):
    # The hazard function is the derivative of the cumulative hazard function.
    # We use InterpolatedUnivariateSpline for spline interpolation to create a smooth 
    # function approximation of the CHF. This provides us with a smooth curve that 
    # passes through each data point, allowing us to differentiate the function and obtain 
    # the hazard function.
    chf_spline = InterpolatedUnivariateSpline(chf.x, chf(chf.x))
    hazard_function = chf_spline.derivative()(chf.x)
    
    # The pdf can be computed using the formula: pdf(t) = hazard(t) * survival(t)
    pdf = hazard_function * sf(chf.x)
    return chf.x, pdf

# Generate random data for demonstration purposes
# Here, we create a random dataset with one covariate and survival times.

np.random.seed(42)  # Setting a fixed seed.
data = np.random.randint(5, 30, size=10)
X_train = pd.DataFrame(data, columns=['covariate'])
y_train = np.array(np.random.randint(0, 100, size=10)/100, dtype=[('status', bool), ('target', float)])

# Initialize and fit the Cox Proportional Hazards model
estimator = CoxPHSurvivalAnalysis()
estimator.fit(X_train, y_train)

# Predict for new data points
X_test = pd.DataFrame({'covariate': [12, 2]})
cumulative_hazard_functions = estimator.predict_cumulative_hazard_function(X_test)
survival_functions = estimator.predict_survival_function(X_test)

# Plot the Cumulative Hazard, Survival, and PDF side by side in a single row
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
for chf, sf in zip(cumulative_hazard_functions, survival_functions):
    # Compute the pdf using our defined function
    times, pdf_values = compute_pdf_from_chf_and_sf(chf, sf)
    
    # Plotting the cumulative hazard function
    axes[0].step(chf.x, chf(chf.x), where='post')
    
    # Plotting the survival function
    axes[1].step(sf.x, sf(sf.x), where='post')
    
    # Plotting the probability density function
    axes[2].step(times, pdf_values, where='post')

# Setting titles for each subplot
axes[0].set_title('Cumulative Hazard Functions')
axes[1].set_title('Survival Functions')
axes[2].set_title('Probability Density Functions')

# Display the plots
plt.tight_layout()
plt.show()


что приводит к

Ссылки : Машинное обучение для анализа выживания: опрос

Это сработало, спасибо! Дополнительный вопрос: я ожидал, что функция плотности будет выглядеть примерно как гистограмма цели или кривая Каплана-Мейера, вычисленная на ее основе. Я в чем-то ошибаюсь?

Kayvon Coffey 06.10.2023 06:03

@Kavyon: Кривая Каплана-Мейера дает общий профиль выживаемости для всей когорты, PDF-файл модели Кокса зависит от ковариат и предоставляет информацию о выживаемости для конкретных профилей на основе этих ковариат. Таким образом, хотя в общей форме или тенденции между PDF-файлом и кривой Каплана-Мейера могут быть некоторые сходства, они фундаментально различны и могут не совпадать в точности, особенно когда влияние ковариат сильно.

user3046211 06.10.2023 07:01

Возможно, вы можете просмотреть ссылку на обзорный документ, которую я вставил в свой ответ, которая поможет вам получить очень хорошее представление о кривых Каплана-Мейера (КМ).

user3046211 06.10.2023 07:06

Попался, да, эта статья была полезна. Оказывается, я думал о кривой КМ как об оценке функции плотности, но на самом деле она оценивает функцию выживания. Таким образом, кривая КМ и кривая выживаемости от cox-ph должны быть похожими (отличаться только влиянием ковариат), но ни одна из них не является функцией плотности, поэтому они не обязательно должны выглядеть одинаково.

Kayvon Coffey 06.10.2023 19:14

Другие вопросы по теме