«Прогнозирование результатов клинических испытаний»

Предсказание результатов клинических испытаний экспертный подход

Часть 2: Прогнозирование исходов клинических испытаний с использованием XGBoost

В первой части этой серии я сосредоточился на внедрении многомодальных данных реального мира, полученных из ClinicalTrials.gov. В этой статье я реализую базовую модель XGBoost, обучу ее на внедрениях, созданных в части 1, и сравню ее производительность с моделью HINT (иерархическая графовая нейронная сеть), от которой было вдохновлено данное проектом.

Схема рабочего процесса (изображение автора)

В этой статье я буду следовать следующим шагам:

  • Загрузка наборов данных для обучения, валидации и тестирования
  • Встраивание молекул препарата(ов), критериев включения/исключения, показаний к заболеванию, спонсора испытания и количества участников
  • Определение метрик оценки
  • Обучение модели XGBoost и краткое сравнение с производительностью модели HINT
Фокус второй части этой серии: Прогнозирование исходов клинических испытаний на основе встраивания характеристик, созданных в первой части (изображение автора)

Вы можете следовать всем шагам в этой тетрадке Jupyter: Руководство по встраиванию клинических испытаний.

Загрузка наборов данных для обучения, валидации и тестирования

import osimport pandas as pdimport numpy as npimport pickle# Импорт игрушечного набора данныхtoy_df = pd.read_pickle('data/toy_df_full.pkl')train_df = toy_df[toy_df['split'] == 'train']val_df = toy_df[toy_df['split'] == 'valid']test_df = toy_df[toy_df['split'] == 'test']y_train = train_df['label']y_val = val_df['label']y_test = test_df['label']print(train_df.shape, val_df.shape, test_df.shape)print(y_train.shape, y_val.shape, y_test.shape)### Результат:# (1028, 14) (146, 14) (295, 14)# (1028,) (146,) (295,)

Встраивание молекулы препарата, протокола, показания и спонсора испытания

В этом разделе мы загружаем словари, созданные в части 1 этой серии, и используем их для отображения значений в наборах данных для обучения, валидации и тестирования их соответствующим встраиваниям.

def embed_all(df):    print('форма входных данных: ', df.shape)    ### ВСТРАИВАНИЕ МОЛЕКУЛ ###    print('встраивание молекул препаратов..')    nctid2molecule_embedding_dict = load_nctid2molecule_embedding_dict()    h_m = np.stack(df['nctid'].map(nctid2molecule_embedding_dict))     print(f"молекулы препаратов успешно встроены в {h_m.shape} измерений")    ### ВСТРАИВАНИЕ ПРОТОКОЛОВ ###    print('встраивание протоколов..')    nctid2protocol_embedding_dict = load_nctid2protocol_embedding_dict()    h_p = np.stack(df['nctid'].map(nctid2protocol_embedding_dict))    print(f"протоколы успешно встроены в {h_p.shape} измерений")    ### ВСТРАИВАНИЕ ПОКАЗАНИЙ НА БОЛЕЗНЬ ###    print('встраивание показаний на заболевание..')    nctid2disease_embedding_dict = load_nctid2disease_embedding_dict()    h_d = np.stack(df['nctid'].map(nctid2disease_embedding_dict))    print(f"показания на заболевание успешно встроены в {h_d.shape} измерений")    ### ВСТРАИВАНИЕ СПОНСОРОВ ИСПЫТАНИЯ ###    print('встраивание спонсоров..')    sponsor2embedding_dict = load_sponsor2embedding_dict()    h_s = np.stack(df['lead_sponsor'].map(sponsor2embedding_dict))    print(f"спонсоры успешно встроены в {h_s.shape} измерений")    ### ВСТРАИВАНИЕ КОЛИЧЕСТВА УЧАСТНИКОВ ###    print('нормализация числа участников..')    enrollment = pd.to_numeric(df['enrollment'] , errors='coerce')    if enrollment.isna().sum() != 0:        print(f"заполнение {enrollment.isna().sum()} NaN с медианным значением")        enrollment.fillna(int(enrollment.median()), inplace=True)        print(f"успешно заполнены NaN с медианным значением: осталось {enrollment.isna().sum()} NaNs")    enrollment = enrollment.astype(int)    h_e = np.array((enrollment - enrollment.mean())/enrollment.std()).reshape(len(df),-1)    print(f"количество участников успешно встроено в {h_e.shape} измерений")    ### КОМБИНИРОВАТЬ ВСЕ ВСТРАИВАНИЯ ###    embedded_df = pd.DataFrame(data=np.column_stack((h_m, h_p, h_d, h_s, h_e)))    print('форма выходных данных: ', embedded_df.shape)    return embedded_df# Встраивание данныхX_train = embed_all(train_df)X_val = embed_all(val_df)X_test = embed_all(test_df)

Определите метрики оценки

Мы будем использовать те же метрики оценки, что и предложенные в статье HINT: ROC AUC, F1, PR-AUC, Precision, Recall и Accuracy.

Тренируйте модель XGBoost и предсказывайте метки для обучающей, проверочной и тестовой выборок

import xgboost as xgb# Создание классификатора XGBoost с указанными гиперпараметрамиxgb_classifier = xgb.XGBClassifier(    learning_rate=0.1,    max_depth=3,    n_estimators=200,    objective='binary:logistic',  # для бинарной классификации    random_state=42)# Обучение модели XGBoostxgb_classifier.fit(X_train, y_train)# Прогнозированиеy_train_pred = xgb_classifier.predict(X_train)y_val_pred = xgb_classifier.predict(X_val)y_test_pred = xgb_classifier.predict(X_test)print('-----------Результаты на обучающих данных:-----------')print_results(y_train_pred, y_train)print('-----------Результаты на проверочных данных:-----------')print_results(y_val_pred, y_val)print('-----------Результаты на тестовых данных:-----------')print_results(y_test_pred, y_test)### Выходные данные:#-----------Результаты на обучающих данных:-----------# ROC AUC: 1.0# F1: 1.0# PR-AUC: 1.0# Precision: 1.0# Recall: 1.0# Accuracy: 1.0# Отношение предсказания 1: 0.661# Отношение метки 1: 0.661# -----------Результаты на проверочных данных:-----------# ROC AUC: 0.765# F1: 0.817# PR-AUC: 0.799# Precision: 0.840# Recall: 0.795# Accuracy: 0.773# Отношение предсказания 1: 0.602# Отношение метки 1: 0.636# -----------Результаты на тестовых данных:-----------# ROC AUC: 0.742# F1: 0.805# PR-AUC: 0.757# Precision: 0.790# Recall: 0.821# Accuracy: 0.759# Отношение предсказания 1: 0.630# Отношение метки 1: 0.606

Сравните результаты с моделью HINT

Эта простая модель XGBoost была обучена на встраиваниях признаков для молекул(ы) лекарств, критериев включения/исключения, показаний к болезни, спонсора испытания и количества участников, в то время как авторы HINT не использовали последние два признака: спонсор испытания и количество участников. Мы использовали несколько инструментов для встраивания языковых моделей, таких как BioBERT и SBERT, и использовали кодирование Morgan для представления лекарств, в то время как авторы HINT использовали различные нейронные сети для всех своих встраиваний.

Из рисунка ниже видно, что наши встраивания признаков, обученные простой моделью XGBoost, демонстрируют хорошие результаты по сравнению с более сложной моделью HINT. Наш проект имеет лучшую точность и точность на этом наборе данных, но худшую полноту.

Сравнение результатов этого проекта с результатами проекта HINT (изображение от автора)

Вывод

Следующими шагами могут быть анализ, чтобы выяснить, насколько внесение признаков спонсора испытания и количества участников способствует улучшению производительности (по некоторым метрикам) по сравнению с другими факторами, такими как выбор модели и техники встраивания. Интуитивно кажется, что эти признаки могут повысить предсказательную производительность, поскольку некоторые спонсоры исторически показывали более высокие результаты, и также можно ожидать связи между размером испытания и итогом.

Теперь вы можете задаться вопросом: “Какая польза от такой предсказательной модели? Можем ли мы полагаться на такую модель и не проводить испытания?” И вы правы (хотя некоторые компании создают цифровых двойников пациентов с целью виртуального проведения испытаний). Модель, подобная той, которую представили в этой серии, может, например, использоваться для улучшения анализа мощности клинических испытаний, связанной статистической практики. Анализ мощности используется для определения оптимального количества участников, которых следует включить в конкретное исследование, и для выполнения такого анализа необходимо сделать сильное допущение о воздействии лечения. Предсказательная модель, которая использует информацию об испытании, такую как структура молекулы препарата, показания к болезни и критерии подхода к испытуемым, подобная модели, которую мы реализовали здесь, может помочь создать более точный анализ мощности.

Ссылки

  • Fu, Tianfan, и др. “Hint: Иерархическая сеть взаимодействия для прогнозирования результатов клинических испытаний.” Patterns 3.4 (2022).