Survival Analysis with Python

비망록으로 정리합니다.

생존 분석은 생물의 죽음과 기계 시스템의 고장과 같은 특정 사건이 발생할 때까지의 기간을 분석하는 통계적 기법 중 하나입니다.
어느 시기를 지나 생존하는 사람의 비율은 얼마입니까? 어떤 행사가 일어난 사람 가운데, 그 사람들은 얼마나의 비율로 천수를 부드럽게 하는가? 어떤 특성은 생존 확률을 어떻게 증가 또는 감소? 이러한 의문에 대답하는 수법을 모색하기 위한 학문이군요.

Kaplan-Meier 방법을 이용한 예측



어느 시기에 발생하는 이벤트의 비율로부터 발생 확률을 예측합니다.
데이터는 여기를 사용합니다.
"Tongue"
h tps://d ゔぇ. 오, ぇ. 코 m/후에/d/1f 피아 KFMc9QP보아 mKdぉ1sW로 zf1DP1·ぃ에에 w? 우 sp = 샤린 g
원본 데이터

sksurv 사용


#sksurvを使う方法
!pip install scikit-survival
#してから
#CSVファイルをこのノートへロードします。
#ファイルを開くダイアログを表示
from google.colab import files
file = files.upload()

#ファイルをCSVとして読み込みます
import pandas as pd
import io
data = pd.read_csv(io.StringIO(file['tongue.csv'].decode('utf-8')),header=0)
#中身の大きさと先頭5行のデータの内容を確認してみます。
print('データの形式:{}'.format(data.shape))
print(data.head())

#イベントのデータ型がintだと駄目なようなので、真偽値に変換しておきます。
#一先ず、グループ1のみを計算対象にします。
f = data.type==1
T = data[f]['time']
event = data[f]['delta']
eventBool = []
for i in event:
  if(event[i]==1):
    eventBool.append(True)
  else :
    eventBool.append(False)

#予測します。
from sksurv.nonparametric import kaplan_meier_estimator
x, y = kaplan_meier_estimator(eventBool, time)

#グラフにします
import matplotlib.pyplot as plt
plt.step(x, y, where="post")
plt.ylim(0, 1)
plt.show()



lifelines 사용


!pip install lifelines # このライブラリも便利です。https://lifelines.readthedocs.io/en/latest/Quickstart.html

#からの予測器を初期化して
from lifelines import KaplanMeierFitter
kmf = KaplanMeierFitter()

#真偽値変換無しでそのまま予測器の引数に渡します
f = data.type==1
T = data[f]['time']
C = data[f]['delta']

kmf.fit(T, event_observed=C)

#グラフにします
kmf.plot(title='Tumor DNA Profile 1')



비교



sksurv에서도 가능하지만 lifelines 라이브러리를 사용하여 그룹 2 (즉 type : 2)와 비교해보십시오.
f2 = data.type==2
T2 = data[f2]['time']
C2 = data[f2]['delta']

ax = plt.subplot(111)

kmf.fit(T, event_observed=C, label=['Type 1 DNA'])
kmf.survival_function_.plot(ax=ax)
kmf.fit(T2, event_observed=C2, label=['Type 2 DNA'])
kmf.survival_function_.plot(ax=ax)

plt.title('Lifespans of different tumor DNA profile')



운용 nk-test



생존 시간 해석에 있어서, 2군의 생존 시간에 차이가 있는지를 검정하는 비파라메트릭인 검정 수법.
일반화 Wilcoxon 검정에 대해 상대적으로 후기에 일어난 사망을 무겁게 평가한다는 특징을 가진다. 시간이 지남에 따라 생존 곡선의 차이가 열리는 경우 로그 랭크 검정은 일반화 Wilcoxon 검정에 비해 검출력이 높아진다. (htps : // 벨 r ゔぇ. jp / s 들 s cs / g ぉ さ ry / 719. HTML)
from lifelines.statistics import logrank_test
summary_= logrank_test(T, T2, C, C2, alpha=99)
summary_.print_summary()

출력
t_0 = -1
null_distribution = chi squared
degrees_of_freedom = 1
alpha = 99
test_statistic p -log2(p)
2.79 0.09 3.40

위험 비율 계산 (Nelson-Aalen 커널 사용)



위험 비율도 계산할 수 있습니다.
어떤 임상시험에서 검토하고 싶은 신약 A와 비교 대상의 약제 B를 비교했을 때, 위험비가 1이면 2개의 치료법에 차이는 없고, 위험비가 1보다 작은 경우에는 치료 A쪽이 유효라고 판정되고, 그 수치가 작을수록 유효하다고 합니다. 예를 들면 A약과 대상의 B약을 비교한다고 하는 어느 임상 시험에서 위험비가 0.94라고 하는 결과이면, A약은 B약보다 리스크를 6% 감소시켰다는 의미가 됩니다. ( h tps : // 온코. jp/ぢc 치오나 ry/hr )
from lifelines import NelsonAalenFitter

naf = NelsonAalenFitter()
naf.fit(T, event_observed=C)

naf.plot(title='Nelson-Aalen Estimate')



마지막으로 'Time Dependent AUC'



자주 바이너리 예측기를 작성할 때 ROC 곡선을 사용합니다만, 이 때의 ROC는 어디까지나 그 시점에서 수집할 수 있는 데이터로 작성한 예측기의 정밀도를 나타내는 ROC입니다.
이 ROC를 일정 기간마다 계산하고, 각각의 시점에서 데이터를 정돈하고 분류 모델로 ROC(그 시점의 생존의 정답을 이용)를 그려, AUC를 계산해, 시간에 따른 AUC의 변화를 가시화했다 는 Time dependent AUC입니다.

이것은 sksurv 라이브러리를 사용하여 시도합니다.
면역 글로불린 유리 L 사슬 카파/λ 비율 샘플 데이터를로드합니다.
이것은 다음과 같은 데이터입니다.
7874 샘플에 9개의 항목이 있습니다.
age: 연수
sex: F = 여성, M = 남성
sample.yr: 혈액 샘플을 얻은 달력
kappa: FLC 카파
lambda: FLC 람다
flc.grp: 대상의 FLC 그룹
creatinine: 혈청 크레아티닌
mgus: 대상이 monoclonal gammapothy (MGUS)로 진단되었는지 여부
chapter : 국제 질병 코드 ICD-9 장 표제에 의한 주요 사인의 그룹화
#データをロードします
from sksurv.datasets import load_flchain
x, y = load_flchain()

#今回はテスト用にデータを分けることにします
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)

#'age', 'creatinine', 'kappa', 'lambda'のみ学習に利用します
num_columns = ['age', 'creatinine', 'kappa', 'lambda']

#欠測を簡易的に単一補完します
from sklearn.impute import SimpleImputer
imputer = SimpleImputer().fit(x_train.loc[:, num_columns])
x_train = imputer.transform(x_train.loc[:, num_columns])
x_test = imputer.transform(x_test.loc[:, num_columns])

#正解ラベルからトレーニングとテストのそれぞれのデータセットの生存期間の最大最小を取得します。
y_events = y_train[y_train['death']]
train_min, train_max = y_events["futime"].min(), y_events["futime"].max()

y_events = y_test[y_test['death']]
test_min, test_max = y_events["futime"].min(), y_events["futime"].max()

#データの整合性を確認します。テストデータに用いるデータの生存期間はトレーニングに用いるデータの生存期間内になければなりません。
assert train_min <= test_min < test_max < train_max, \
    "time range or test data is not within time range of training data."

#今回は生存期間が、5から81までの間で15間隔で計算します。
import numpy as np
times = np.percentile(y["futime"], np.linspace(5, 81, 15))
print(times)

#time dependent aucを描きます。
from sksurv.metrics import cumulative_dynamic_auc
from sksurv.metrics import concordance_index_ipcw
import matplotlib.pyplot as plt

def plot_cumulative_dynamic_auc(risk_score, label, color=None):
    auc, mean_auc = cumulative_dynamic_auc(y_train, y_test, risk_score, times)

    plt.plot(times, auc, marker="o", color=color, label=label)
    plt.xlabel("days from enrollment")
    plt.ylabel("time-dependent AUC")
    plt.axhline(mean_auc, color=color, linestyle="--")
    plt.legend()

for i, col in enumerate(num_columns):
    plot_cumulative_dynamic_auc(x_test[:, i], col, color="C{}".format(i))
    ret = concordance_index_ipcw(y_train, y_test, x_test[:, i], tau=times[-1])



위의 그래프로부터 예측력 높은 특징량은 「Age, kappa/lambda, creatinine」의 순서인 것을 알 수 있습니다.

이상입니다.

p.s

또한 sksurv 개발자가 심층 학습을 이용한 생존 분석 접근법을 소개합니다.
공부하지 않으면. .
SurvivalAnalysisForDeepLearning

Reference


  • htps // 엔.ぃきぺぢ아. 오 rg / uuki / sur ゔ ぃ ゔ ぁ l_ 아나 ly
  • htps // p t. ly/py 텐/v3/이 py 텐-노보오 ks/스 rゃゔめ
  • h tps://k-d-w. rg / s ぃ에서 s / py 코누 k 2017 /
  • htp // 신 hrks. 하테나 bぉg. 코m/엔트리/2014/11/01/223504
  • 좋은 웹페이지 즐겨찾기