Понимание машинного обучения в здравоохранении
Машинное обучение широко применяется в здравоохранении, например, в медицинской диагностике [1]. Одним из часто используемых наборов данных для исследований рака является набор данных по диагностике рака молочной железы штата Висконсин (WBCD) [2]. Как и в других областях, модели машинного обучения, используемые в здравоохранении, по-прежнему остаются черными ящиками. Как описано в [3], понимание причин, лежащих в основе прогнозов модели машинного обучения, очень важно для определения доверия, если врач планирует принять меры по лечению рака на основе прогноза диагноза. Такое понимание также может помочь врачам, специализирующимся в данной области, находить ошибки в прогнозах моделей машинного обучения. Этого можно добиться разными способами. Один из методов называется «объяснимое машинное обучение» [4].
В этой статье я использую набор данных WBCD [2], чтобы продемонстрировать, как реализовать объяснимое машинное обучение, чтобы сделать ненадежный прогноз достоверным.
1. Объяснимое машинное обучение
Как описано в [4], объяснимое машинное обучение в этой статье относится к апостериорному анализу и методам, которые используются для понимания предсказаний предварительно обученной модели. Существуют различные апостериорные методы, такие как генерация кода причины, локальная и глобальная визуализация прогнозов модели и т. Д. [4]. В этой статье я использую генерацию кода причины как апостериорный метод. В частности, Local Interpretable Model-Agnostic Explanations (LIME) [3] используется для объяснения того, какие функции используются моделью машинного обучения для принятия решения о прогнозировании.
2. Подготовка набора данных
Как описано ранее, набор данных, используемый в этой статье, является общедоступным набором данных WBCD [2]. В этом наборе данных для каждого образца были предоставлены следующие 9 функций, которые будут использоваться в качестве входных данных для модели машинного обучения:
- Толщина комка
- Однородность размера ячеек
- Однородность формы ячейки
- Маргинальная адгезия
- Размер одной эпителиальной клетки
- Голые ядра
- Блочный хроматин
- Нормальные ядрышки
- Митозы
2.1 Загрузка данных
Предполагая, что набор данных WBCD уже был загружен на локальный компьютер в виде файла csv груди-рака-wisconsin.csv, файл набора данных можно затем загрузить в фрейм данных Pandas следующее:
feature_names = ["CT","UCSize","UCShape","MA","SECSize","BN","BC","NN","Mitoses"] columns = ["ID"] columns.extend(feature_names) columns.extend(["Diagnosis"]) raw_data = pd.read_csv('breast-cancer-wisconsin.csv', na_values='?', header=None, index_col=['ID'], names = columns) raw_data = raw_data.reset_index(drop=True) raw_data.head(10)
2.2 Предварительная обработка данных
Набор данных WBCD имеет много общих проблем и, следовательно, требует предварительной обработки для решения этих проблем, прежде чем он может быть использован моделью машинного обучения.
- Отсутствующие данные
Следующая команда проверяет, для каких функций отсутствуют данные:
data = raw_data.copy() data.isnull().sum()
Как показано в таблице выше, 16 записей данных о голых ядрах отсутствуют. Эти отсутствующие записи данных просто заменяются на 0 в этой статье, поскольку общее количество отсутствующих записей относительно невелико.
- Маленький размер набора данных
Набор данных WBCD [2] включает всего 699 образцов, что слишком мало для машинного обучения. Эту проблему небольшого размера данных можно решить путем увеличения данных (подробности см. В разделе Несбалансированный набор данных).
- Разные шкалы значений характеристик
Диапазоны значений различных функций различаются. Класс Scale ниже предназначен для преобразования значений функций в тот же диапазон [0, 1]. Этот класс разработан таким образом, что его можно использовать с другими классами для формирования конвейера позже.
from sklearn.preprocessing import MinMaxScaler from sklearn.base import BaseEstimator, TransformerMixin minMaxScaler = MinMaxScaler() minMaxScaler.fit(features[feature_names]) class Scale(BaseEstimator, TransformerMixin): def __init__(self): pass def fit(self, X, y=None): return self def transform(self, X, y=None): if type(X) == pd.Series or type(X) == pd.DataFrame: X1 = X.values X1 = X1.reshape(1, -1) else: X1 = X.copy() X1 = minMaxScaler.transform(X1) return X1
- Несбалансированный набор данных
Следующий код предназначен для проверки того, сбалансирован ли набор данных с точки зрения помеченных значений диагностики:
data['Diagnosis'].value_counts()
Количество выборок данных с разными метками не сбалансировано. Имеется 458 образцов данных, помеченных как 2 (т. Е. B (доброкачественный)), но есть только 241 образец данных, помеченных как 4 (т. Е. M (злокачественный)).
Чтобы сбалансировать набор данных, для простоты копия 241 выборки данных, помеченная как M, добавляется в исходный набор данных.
- Перекошенный набор данных
Следующий код можно использовать для визуализации распределения значений функций:
data[numerical].hist(bins=20, figsize=(15, 10))
Видно, что значения большинства характеристик значительно смещены вправо. Приведенный ниже класс Sqrt предназначен для устранения проблемы асимметрии данных путем извлечения квадратного корня из значений функций. Как и класс Scale, этот класс разработан как компонент конвейера.
class Sqrt(BaseEstimator, TransformerMixin): def __init__(self): pass def fit(self, X, y=None): return self def transform(self, X, y=None): if type(X) == pd.Series or type(X) == pd.DataFrame: X1 = X.copy() if X1.isnull().values.any(): X1 = X1.fillna(0) X1 = X1.abs() # avoid negative values else: X1 = X.copy() X1 = np.absolute(X1) # avoid negative values X1 = np.sqrt(X1) return X1
2.3 Отделение меток от функций
Метки (т.е. диагностика) отделены от функций, поскольку метки и функции необходимы для обучения и тестирования модели.
labels = data['Diagnosis'] features = data.drop(['Diagnosis'], axis = 1)
2.4 Разделение набора данных на наборы данных для обучения и тестирования
Функции и метки случайным образом разделены на две части: 75% для обучения модели и 25% для тестирования модели:
from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.25, random_state=42)
3. Модель машинного обучения.
Классификатор случайного леса с настройками по умолчанию используется в демонстрационных целях. Обучение и тестирование модели можно проводить следующим образом:
from sklearn.ensemble import RandomForestClassifier rfc = RandomForestClassifier(n_estimators=100) rfc.fit(X_train, y_train) score = rfc.score(X_test, y_test)
Обученная модель достигла точности 98,23%.
4. Метод LIME для объяснения прогнозов.
Как описано в [3], определение доверия к индивидуальным прогнозам важно при принятии решений с помощью моделей машинного обучения. Например, когда машинное обучение используется для медицинской диагностики, такой как диагностика рака груди в Висконсине [1], прогнозы нельзя просто использовать для действий, поскольку последствия могут быть катастрофическими. В этом разделе показано, как использовать LIME [3] для объяснения индивидуальных прогнозов в качестве решения для определения доверия.
4.1 Создание конвейера
Ключевым моментом генерации кода причины в LIME является связывание результата прогнозирования модели с исходными непреобразованными значениями признаков. С этой целью метод LIME использует конвейер машинного обучения (включая конвейер предварительной обработки данных в начале и модель машинного обучения в конце конвейера) в качестве входных данных для объяснения результатов прогнозирования модели. Для этой цели предназначен следующий конвейер:
from sklearn.pipeline import make_pipeline scale = Scale() sqrt = Sqrt() # rfc is a pre-trained Random Forest model machine_learning_pipeline = make_pipeline(scale, sqrt, rfc)
4.2 Выбор LIME Explainer
Метод LIME поддерживает различные типы поясняющих моделей машинного обучения для различных типов наборов данных, таких как изображения, текст, табличные данные и т. Д. Табличный пояснитель выбран в этой статье, поскольку формат набора данных WBCD является табличным:
from lime.lime_tabular import LimeTabularExplainer class_names = ['Benign', 'Malignant'] explainer = LimeTabularExplainer(feature_names=feature_names, class_names=class_names, training_data=X_train.values)
4.3 Объяснение предсказания модели
После обучения модели машинного обучения с учетом любого вектора исходных значений признаков (т. Е. Вектора признаков) для объяснения предсказания модели можно использовать следующую функцию объяснять:
def explain(feature_vector, label=1): # feature_vector - a Pandas Series of features exp = explainer.explain_instance(feature_vector, machine_learning_pipeline.predict_proba, num_features=9) fig = plot(exp, label) exp.show_in_notebook(show_table=True, show_all=False)
Метод show_in_notebook () объяснителя LIME показывает связи между прогнозом и соответствующими исходными значениями функций в формате записной книжки.
Функция plot ниже предназначена для создания гистограммы для отображения результатов объяснения модели LIME:
def plot(exp, label=1): exp_list = exp.as_list() fig = plt.figure() vals = [x[1] for x in exp_list] names = [x[0] for x in exp_list] vals.reverse() names.reverse() colors = ['green' if x <= 0 else 'red' for x in vals] pos = np.arange(len(exp_list)) + .5 plt.barh(pos, vals, align='center', color=colors) plt.yticks(pos, names) if exp.mode == "classification": title = 'Local explanation for class {}'.format(exp.class_names[label]) else: title = 'Local explanation' plt.title(title) return fig
Пример 1. Объяснение прогноза злокачественности
Ниже приведен образец (вектор признаков) M (злокачественный):
sample_M = raw_data.loc[5, feature_names]
Результат прогнозирования этого вектора признаков можно объяснить с помощью LIME следующим образом:
explain(m_feature_vector, machine_learning_pipeline, label=1)
Результат предсказания Malignant показан в верхнем левом углу рисунка выше. В правом верхнем углу и внизу показано, какие особенности положительно коррелируют с прогнозом злокачественного новообразования, а какие отрицательно коррелируют с прогнозом злокачественного новообразования. В частности, элементы, отмеченные оранжевым / красным цветом, указывают на положительную корреляцию, в то время как элементы, отмеченные синим / зеленым цветом, представляют собой отрицательную корреляцию.
Пример 2. Объяснение прогноза доброкачественности
Ниже приведен образец вектора признаков B (доброкачественный):
sample_B = raw_data.loc[1, feature_names]
Результат прогнозирования этого вектора признаков может быть объяснен с помощью LIME следующим образом:
explain(sample_B, machine_learning_pipeline, label=0)
Результат предсказания Benign показан в верхнем левом углу рисунка выше. В правом верхнем углу и внизу показано, какие особенности положительно коррелируют с прогнозом злокачественного новообразования, а какие отрицательно коррелируют с прогнозом злокачественного новообразования. В частности, элементы, отмеченные оранжевым / красным цветом, указывают на положительную корреляцию, в то время как элементы, отмеченные синим / зеленым цветом, представляют собой отрицательную корреляцию.
5. Вывод
В этой статье я использовал метод LIME [3] и набор данных WBCD [2], чтобы продемонстрировать, как объяснить результаты прогнозирования модели машинного обучения в диагностике рака груди.
Как описано в начале этой статьи, понимание причин, лежащих в основе прогнозов модели машинного обучения, очень важно для оценки доверия, если врач планирует принять меры по лечению рака на основе прогноза диагноза. Такое понимание также может помочь врачам, обладающим знаниями в данной области, обнаруживать ошибки в прогнозах модели машинного обучения, чтобы можно было дополнительно улучшить используемую модель машинного обучения.
Блокнот Jupyter со всем исходным кодом из этой статьи доступен на Github [6].
использованная литература
[1] Набор данных диагностики рака груди, штат Висконсин
[2] Набор данных и описание WBCD
[3] М. Т. Рибейро, С. Сингх и К. Гестрин, Почему я должен вам доверять?
Объясняя предсказания любого классификатора »
[4] П. Холл и Н. Гилл, Введение в интерпретируемость машинного обучения, прикладная перспектива справедливости, подотчетности, прозрачности и объяснимого ИИ, второе издание, O’Reilly Media, Inc., 2019
[5] М. Т. Рибейро, С. Сингх и К. Гестрин, Локальные интерпретируемые модельно-агностические объяснения (LIME): Введение
[6] Юй Хуанг, блокнот Jupyter в Github
ЗАЯВЛЕНИЕ О РАСКРЫТИИ ИНФОРМАЦИИ: © 2020. Мнения, выраженные в этой статье, принадлежат автору и не обязательно отражают точку зрения Аргоннской национальной лаборатории.