Überlebensdaten für Kaplan-Meier-Plots in Python simulieren

English Deutsch

Bibliotheken wie lifelines bieten eine Fülle von Beispieldatensätzen, mit denen man arbeiten kann. Für viele Aufgaben musst du jedoch spezifisches Verhalten in Überlebenskurven simulieren.

In diesem Post demonstrieren wir einen einfachen Algorithmus zum Generieren von Überlebensdaten in einem Format, das mit dem in den lifelines-Beispieldatensätzen wie load_leukemia() verwendeten vergleichbar ist.

Der Generierungsalgorithmus basiert auf den folgenden Annahmen:

Code:

simulate_survival_linear.py
import numpy as np
import random
from lifelines import KaplanMeierFitter

def simulate_survival_data_linear(N, survival_plateau, t_plateau, t_end):
    """
    Generiert zufällige simulierte Überlebensdaten mit einem linearen Modell

    Schlüsselparameter
    ------------------
    N : integer
        Anzahl der zu generierenden Einträge
    survival_plateau : float
        Die Überlebenswahrscheinlichkeit des Überlebensplateaus
    t_plateau : float
        Der Zeitpunkt, an dem das Überlebensplateau beginnt
    t_end : float
        Der Zeitpunkt, an dem alle überlebenden Teilnehmer zensiert werden.

    Returns
    -------
    Ein Dict mit "Time"- und "Event"-NumPy-Arrays: 0 ist zensiert, 1 ist Ereignis
    """
    data = {"Time": np.zeros(N), "Event": np.zeros(N)}

    for i in range(N):
        r = random.random()
        if r <= survival_plateau:
            # Ereignis ist Zensierung am Ende des Zeitraums
            data["Time"][i] = t_end
            data["Event"][i] = 0
        else: # Ereignis tritt ein
            # Normalisieren, wo wir uns zwischen 100% und dem Überlebensplateau befinden
            p = (r - survival_plateau) / (1 - survival_plateau)
            # Lineares Modell: Zeitpunkt des Ereignisses hängt linear von der gleichmäßig & zufällig gewählten Position
            #  im Bereich (0...tplateau) ab
            t = p * t_plateau
            data["Time"][i] = t
            data["Event"][i] = 1
    return data

# Beispielverwendung
data1 = simulate_survival_data_linear(250, 0.2, 18, 24)
data2 = simulate_survival_data_linear(250, 0.4, 17.2, 24)

Gegeben data1 und data2 (siehe das Verwendungsbeispiel am Ende des Codes) kannst du sie plotten mit

plot_kaplan_meier.py
# Schlechte Untergruppe plotten
kmf1 = KaplanMeierFitter()
kmf1.fit(data1["Time"], event_observed=data1["Event"], label="Bad subgroup")
ax = kmf1.plot()

# Gute Untergruppe plotten
kmf2 = KaplanMeierFitter()
kmf2.fit(data2["Time"], event_observed=data2["Event"], label="Good subgroup")
ax = kmf2.plot(ax=ax)

# Y-Achse auf feste Skalierung setzen
ax.set_ylim([0.0, 1.0])

ThiSimulierte Kaplan-Meier-Überlebenskurven mit linearem Verlauf und Überlebensplateau

Kein Überlebensplateau gewünscht?

Setze einfach t_end = t_survival:

simulate_survival_no_plateau.py
# Beispielverwendung
data1 = simulate_survival_data_linear(250, 0.2, 24, 24)
data2 = simulate_survival_data_linear(250, 0.4, 24, 24)
# Code zum Plotten: Siehe oben

Simulierte Kaplan-Meier-Überlebenskurven ohne Überlebensplateau

Was passiert bei einer geringen Teilnehmerzahl?

Verwenden wir 25 statt 250 wie oben:

simulate_survival_low_n.py
# Beispielverwendung
data1 = simulate_survival_data_linear(25, 0.2, 24, 24)
data2 = simulate_survival_data_linear(25, 0.4, 24, 24)
# Plot-Code: Siehe oben

Simulierte Kaplan-Meier-Überlebenskurven mit geringer Teilnehmerzahl

Obwohl wir die Daten mit denselben Daten generiert haben, ist der Unterschied in diesem Beispiel viel weniger deutlich, insbesondere gegen Ende der Zeitleiste (beachte jedoch, dass die Daten zufällig generiert werden, sodass du ein anderes Ergebnis sehen könntest). Man sieht einen großen Teil der überlappenden Konfidenzintervalle nahe t=24. Mit anderen Worten, basierend auf diesen Daten ist es nicht klar, dass sich die beiden Patientengruppen signifikant unterscheiden (mit anderen Worten, $P \geq 0.05$)


Check out similar posts by category: Python, Statistics