«Машинное обучение в медицинских учреждениях может значительно улучшить медицинскую диагностику».

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

Что такое диабет?

Диабет - это заболевание, которое возникает, когда уровень глюкозы в крови становится высоким, что в конечном итоге приводит к другим проблемам со здоровьем, таким как болезни сердца, болезни почек и т. Д. Диабет возникает в основном из-за употребления продуктов с высокой степенью переработки, вредных привычек потребления и т. Д. и др. По данным ВОЗ, количество людей с диабетом с годами увеличивалось.

Предпосылки

  • Python 3. +
  • Анаконда (Scikit Learn, Numpy, Pandas, Matplotlib, Seaborn)
  • Блокнот Jupyter.
  • Базовое понимание контролируемых методов машинного обучения: в частности, классификация.

Этап 0 - Подготовка данных

Как специалист по анализу данных, самая утомительная задача, с которой мы сталкиваемся, - это сбор и подготовка набора данных. Несмотря на то, что в эту эпоху существует множество данных, все еще трудно найти подходящий набор данных, который подходит для проблемы, которую вы пытаетесь решить. Если подходящих наборов данных найти не удалось, возможно, придется создать свои собственные.

В этом руководстве мы не собираемся создавать собственный набор данных, вместо этого мы будем использовать существующий набор данных под названием База данных диабета индейцев пима », предоставляемый репозиторием машинного обучения UCI ( известный репозиторий для наборов данных машинного обучения). Мы будем выполнять рабочий процесс машинного обучения с использованием приведенного выше набора данных о диабете.

Этап 1 - Исследование данных

Когда мы сталкиваемся с набором данных, сначала мы должны проанализировать и «узнать» набор данных. Этот шаг необходим, чтобы ознакомиться с данными, получить некоторое представление о потенциальных функциях и увидеть, нужна ли очистка данных.

Сначала мы импортируем необходимые библиотеки и импортируем наш набор данных в записную книжку Jupyter. Мы можем наблюдать упомянутые столбцы в наборе данных.

%matplotlib inline
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
diabetes = pd.read_csv('datasets/diabetes.csv')
diabetes.columns 

Индекс (['Беременности', 'Глюкоза', 'Кровяное давление', 'Толщина кожи', 'Инсулин',
'ИМТ', 'Диабетическая родовая функция', 'Возраст', 'Результат'],
dtype = 'объект')

Важно: следует отметить, что приведенный выше набор данных содержит только ограниченные функции, хотя в действительности в игру вступают многочисленные функции.

Мы можем проверить набор данных с помощью метода pandas head ().

diabetes.head()

Мы можем найти размеры набора данных, используя атрибут «shape» panda Dataframes.

print("Diabetes data set dimensions : {}".format(diabetes.shape))

Параметры набора данных о диабете: (768, 9)

Мы можем заметить, что набор данных содержит 768 строк и 9 столбцов. «Результат» - это столбец, который мы собираемся спрогнозировать и который сообщает, болен ли пациент диабетом или нет. 1 означает, что человек страдает диабетом, а 0 означает, что человек не болен. Мы можем определить, что из 768 человек 500 помечены как 0 (недиабетики), а 268 - как 1 (диабетики).

diabetes.groupby('Outcome').size()

Визуализация данных - обязательный аспект науки о данных. Это помогает понять данные, а также объяснить их другому человеку. Python имеет несколько интересных библиотек визуализации, таких как Matplotlib, Seaborn и т. Д.

В этом руководстве мы будем использовать визуализацию pandas, которая построена поверх matplotlib, чтобы найти распределение данных функций.

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

diabetes.groupby(‘Outcome’).hist(figsize=(9, 9))

Этап 2 - Очистка данных

Следующим этапом рабочего процесса машинного обучения является очистка данных. Считается одним из важнейших этапов рабочего процесса, потому что он может сделать или сломать модель. В машинном обучении есть поговорка: «Лучше данные лучше, чем сложные алгоритмы», которая предполагает, что лучшие данные дают лучшие результирующие модели.

При очистке данных необходимо учитывать несколько факторов.

  1. Повторяющиеся или не относящиеся к делу наблюдения.
  2. Плохая маркировка данных, одна и та же категория встречается несколько раз.
  3. Отсутствующие или нулевые точки данных.
  4. Неожиданные выбросы.

В этом руководстве мы не будем подробно обсуждать процедуру очистки данных.

Поскольку мы используем стандартный набор данных, мы можем с уверенностью предположить, что факторы 1, 2 уже учтены. Неожиданные выбросы либо полезны, либо потенциально вредны.

Отсутствующие или нулевые точки данных

Мы можем найти любые отсутствующие или нулевые точки данных набора данных (если они есть), используя следующую функцию pandas.

diabetes.isnull().sum()
diabetes.isna().sum()

Мы можем заметить, что в наборе данных нет отсутствующих точек данных. Если таковые были, мы должны поступить с ними соответствующим образом.

Неожиданные выбросы

При анализе гистограммы мы можем определить, что в некоторых столбцах есть выбросы. Мы продолжим анализ этих выбросов и определим, что мы можем с ними сделать.

Артериальное давление: просмотрев данные, мы можем увидеть, что для артериального давления имеется 0 значений. И очевидно, что показания набора данных кажутся неправильными, потому что у живого человека не может быть нулевого диастолического артериального давления. Наблюдая за данными, мы можем увидеть 35 отсчетов, где значение равно 0.

print("Total : ", diabetes[diabetes.BloodPressure == 0].shape[0])
Total :  35
print(diabetes[diabetes.BloodPressure == 0].groupby('Outcome')['Age'].count())
Outcome
0    19
1    16
Name: Age, dtype: int64

Уровни глюкозы в плазме: даже после голодания уровень глюкозы не будет ниже нуля. Следовательно, ноль является недопустимым показанием. Наблюдая за данными, мы можем увидеть 5 отсчетов, где значение равно 0.

print("Total : ", diabetes[diabetes.Glucose == 0].shape[0])
Total :  5
print(diabetes[diabetes.Glucose == 0].groupby('Outcome')['Age'].count())
Total :  5
Outcome
0    3
1    2
Name: Age, dtype: int64

Толщина кожной складки. Для нормальных людей толщина кожной складки не может быть меньше 10 мм, но лучше ноль. Общее количество при значении 0: 227.

print("Total : ", diabetes[diabetes.SkinThickness == 0].shape[0])
Total :  227
print(diabetes[diabetes.SkinThickness == 0].groupby('Outcome')['Age'].count())
Outcome
0    139
1     88
Name: Age, dtype: int64

ИМТ: не должен быть 0 или близок к нулю, если только у человека действительно недостаточный вес, что может быть опасно для жизни.

print("Total : ", diabetes[diabetes.BMI == 0].shape[0])
Total :  11
print(diabetes[diabetes.BMI == 0].groupby('Outcome')['Age'].count())
Outcome
0    9
1    2
Name: Age, dtype: int64

Инсулин: в редких случаях у человека может быть нулевой инсулин, но, наблюдая за данными, мы можем обнаружить, что всего 374 отсчета.

print("Total : ", diabetes[diabetes.Insulin == 0].shape[0])
Total :  374
print(diabetes[diabetes.Insulin == 0].groupby('Outcome')['Age'].count())
Outcome
0    236
1    138
Name: Age, dtype: int64

Вот несколько способов обработки недопустимых значений данных:

  1. Игнорировать / удалять эти случаи: в большинстве случаев это невозможно, потому что это будет означать потерю ценной информации. И в этом случае столбцы «толщина кожи» и «инсулин» означают наличие множества недействительных точек. Но это может сработать для точек данных «ИМТ», «глюкоза» и «артериальное давление».
  2. Поместите средние / средние значения: это может сработать для некоторых наборов данных, но в нашем случае установка среднего значения в столбец артериального давления отправит неверный сигнал модели.
  3. Избегайте использования функций: можно не использовать функции с большим количеством недопустимых значений для модели. Это может сработать для «толщины кожи», но это трудно предсказать.

К концу процесса очистки данных мы пришли к выводу, что данный набор данных является неполным. Поскольку это демонстрация машинного обучения, мы продолжим работу с данными с небольшими изменениями.

Мы удалим строки, в которых «Кровяное давление», «ИМТ» и «Глюкоза» равны нулю.

diabetes_mod = diabetes[(diabetes.BloodPressure != 0) & (diabetes.BMI != 0) & (diabetes.Glucose != 0)]
print(diabetes_mod.shape)
(724, 9)

Этап 3 - Разработка функций

Разработка функций - это процесс преобразования собранных данных в функции, которые лучше представляют проблему, которую мы пытаемся решить для модели, для повышения ее производительности и точности.

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

«Разработка функций позволяет нам выделить важные функции и упростить предоставление экспертных знаний по проблеме. Это также позволяет избежать переобучения модели, несмотря на наличие множества входных функций ».

Область проблемы, которую мы пытаемся решить, требует множества связанных функций. Поскольку набор данных уже предоставлен, и, исследуя данные, мы не можем создавать или удалять какие-либо данные на этом этапе. В наборе данных у нас есть следующие особенности.

«Беременность», «Глюкоза», «Артериальное давление», «Толщина кожи», «Инсулин», «ИМТ», «Диабетическая родословная», «Возраст»

Грубым наблюдением мы можем сказать, что «толщина кожи» не является показателем диабета. Но мы не можем отрицать тот факт, что на данный момент он непригоден для использования.

Поэтому мы будем использовать все доступные возможности. Мы разделяем набор данных на функции и ответ, который мы собираемся предсказать. Мы назначим функции переменной X, а ответ - переменной y.

feature_names = ['Pregnancies', 'Glucose', 'BloodPressure', 'SkinThickness', 'Insulin', 'BMI', 'DiabetesPedigreeFunction', 'Age']
X = diabetes_mod[feature_names]
y = diabetes_mod.Outcome

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

Данная статья дает очень хорошее объяснение Feature Engineering.

Этап 4 - Выбор модели

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

Во-первых, мы будем вычислять «Точность классификации (точность тестирования)» данного набора моделей классификации с их параметрами по умолчанию, чтобы определить, какая модель работает лучше с набором данных о диабете.

Импортируем необходимые библиотеки для записной книжки. Мы импортируем 7 классификаторов, а именно K-ближайшие соседи, классификатор опорных векторов, логистическая регрессия, гауссовский наивный байесовский анализ, случайный лес и градиентное усиление, чтобы претендовать на звание лучшего классификатора.

from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier

Мы инициализируем модели классификаторов с их параметрами по умолчанию и добавим их в список моделей.

models = []
models.append(('KNN', KNeighborsClassifier()))
models.append(('SVC', SVC()))
models.append(('LR', LogisticRegression()))
models.append(('DT', DecisionTreeClassifier()))
models.append(('GNB', GaussianNB()))
models.append(('RF', RandomForestClassifier()))
models.append(('GB', GradientBoostingClassifier()))

Пример: Обычно обучение модели с помощью Scikit learn выглядит следующим образом.

knn = KNeighborsClassifier ()
knn.fit (X_train, y_train)

Методы оценки

Это общая практика - избегать обучения и тестирования на одних и тех же данных. Причина в том, что цель модели - предсказать данные вне выборки, а модель может быть слишком сложной, что приведет к переобучению. Чтобы избежать вышеупомянутых проблем, есть две меры предосторожности.

  1. Тренировка / тестовый сплит
  2. К-фолд перекрестная проверка

Мы импортируем «train_test_split» для разделения поездов / тестов и «cross_val_score» для k-кратной перекрестной проверки. «Precision_score» предназначен для оценки точности модели в методе разделения «поезд / тест».

from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score

Мы воспользуемся указанными методами, чтобы найти наиболее эффективные базовые модели.

Разделение на тренировку / тест

Этот метод разбивает набор данных на две части: обучающий набор и тестовый набор. обучающий набор используется для обучения модели. И набор для тестирования используется для тестирования модели и оценки точности.

Плюсы: но разделение "поезд / тест" по-прежнему полезно из-за его гибкости и скорости.

Минусы: дает оценку с большим разбросом вне выборки.

Разделение на обучение и тестирование с помощью Scikit Learn:

Затем мы можем разделить функции и ответы на обучающие и тестовые части. Мы стратифицируем (процесс, при котором каждый класс ответа должен быть представлен в равных пропорциях в каждой из частей) выборки.

X_train, X_test, y_train, y_test = train_test_split(X, y, stratify = diabetes_mod.Outcome, random_state=0)

Затем мы помещаем каждую модель в цикл и вычисляем точность соответствующей модели с помощью «precision_score».

names = []
scores = []
for name, model in models:
    model.fit(X_train, y_train)
    y_pred = model.predict(X_test)
    scores.append(accuracy_score(y_test, y_pred))
    names.append(name)
tr_split = pd.DataFrame({'Name': names, 'Score': scores})
print(tr_split)

Перекрестная проверка K-Fold

Этот метод разбивает набор данных на K равных разделов («складок»), затем использует 1 кратность в качестве тестового набора и объединение других складок в качестве обучающий набор. Затем модель проверяется на точность. Процесс будет повторять вышеуказанные шаги K раз, каждый раз используя разные складки в качестве набора для тестирования. Средняя точность тестирования процесса - это точность тестирования.

Плюсы: более точная оценка точности вне выборки. Более «эффективное» использование данных (каждое наблюдение используется как для обучения, так и для тестирования)

Минусы: намного медленнее, чем разделение "Обучение / Тест".

Этот метод рекомендуется использовать там, где вычислительные возможности не ограничены. С этого момента мы будем использовать этот метод.

Перекрестная проверка K-Fold с помощью Scikit Learn:

Мы будем продвигаться вперед с перекрестной проверкой K-Fold, поскольку она более точна и эффективно использует данные. Мы обучим модели с использованием 10-кратной перекрестной проверки и рассчитаем среднюю точность моделей. «Cross_val_score» предоставляет собственный интерфейс для обучения и расчета точности.

names = []
scores = []
for name, model in models:
    
    kfold = KFold(n_splits=10, random_state=10) 
    score = cross_val_score(model, X, y, cv=kfold, scoring='accuracy').mean()
    
    names.append(name)
    scores.append(score)
kf_cross_val = pd.DataFrame({'Name': names, 'Score': scores})
print(kf_cross_val)

Мы можем построить оценки точности с помощью seaborn

axis = sns.barplot(x = 'Name', y = 'Score', data = kf_cross_val)
axis.set(xlabel='Classifier', ylabel='Accuracy')
for p in axis.patches:
    height = p.get_height()
    axis.text(p.get_x() + p.get_width()/2, height + 0.005, '{:1.4f}'.format(height), ha="center") 
    
plt.show()

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

На исходном уровне логистической регрессии удалось достичь точности классификации 77,64%. Он будет выбран в качестве основного кандидата для следующих этапов.

Резюме

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

Обновлять

Вы можете найти Часть 02 этой серии по следующей ссылке.



Исходный код, с помощью которого был создан этот пост, можно найти ниже.



Если у вас есть какие-либо проблемы или вопросы относительно этой статьи, не стесняйтесь оставлять комментарии ниже или напишите мне по электронной почте: [email protected]

Надеюсь, вам понравилась статья. Ваше здоровье !!!