Что такое сердечная недостаточность?

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

В этом исследовании изучалась выживаемость пациентов с сердечной недостаточностью, госпитализированных в Институт кардиологии и смежную больницу в Фейсалабаде, Пакистан, в период с апреля по декабрь (2015 г.).

Цели этого проекта разделены на два раздела: -

1) Теоретическая часть:

  • Что такое отраслевой стандарт Cross для интеллектуального анализа данных?
  • Понимание концепции предиктивной аналитики

2) Раздел приложения:

  • Понимание данных
  • Предварительная обработка данных
  • Моделирование (Два алгоритма прогнозной аналитики)
  • Оценка

Что такое общеотраслевой стандартный процесс?

CRISP-DM (Cross Standard Industry Process for Data Mining) — это шестиэтапная модель процесса, которая точно отражает жизненный цикл науки о данных. Цель этого процесса заключалась в стандартизации процедур интеллектуального анализа данных в разных секторах, и он был опубликован в 1999 году. Он функционирует как серия рекомендаций, которые помогут вам в планировании, организации и реализации вашего проекта по науке о данных (или машинному обучению). Однако шесть этапов: понимание бизнеса, понимание данных, подготовка данных, моделирование, оценка, развертывание.

Что такое прогнозная аналитика?

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

1. Модель кластеризации. Этот подход группирует данные на основе их общих свойств. Он работает, классифицируя объекты или людей на основе схожих характеристик или поведения, а затем вырабатывая стратегию в большем масштабе для каждой группы.

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

3- Модели классификации: это процесс определения класса предоставленных точек данных. Классы иногда называют целями/метками или категориями. Прогнозное моделирование для классификации — это процесс оценки функции отображения (f) от дискретных входных переменных (X) до дискретных выходных переменных (y).

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

В разделе «Приложение» язык программирования python использовался в среде Google Colab. Согласно используемым библиотекам, Pandas и Numpy используются для чтения и обработки данных, Seaborn и Matplotlip для построения графика EDA, а также для применения алгоритмов используется Sklearn.

Давайте начнем делать это шаг за шагом!

1- Понимание данных

Как указывалось ранее, в этом проекте использовались данные пациентов с сердечной недостаточностью, госпитализированных в Институт кардиологии и союзную больницу в Фейсалабаде, Пакистан, в период с апреля по декабрь (2015 г.). Данные представлены в CSV-файле, полученном из Репозитория машинного обучения UCI.

Прежде всего, мы импортируем необходимые библиотеки и читаем CSV-файл набора данных.

#Libraries Calling
import pandas as pd
import numpy as np
import matplotlib.pylab as plt
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
data_0 = pd.read_csv("heart_failure_clinical_records_dataset.csv")
data_0.columns
data_0.shape
data_0.head()

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

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

-получим общую статистику по набору данных

data_0.describe().transpose()

-Визуализация данных помогает лучше понять набор данных

Изучив предыдущий график, мы можем получить, что:

  • График распределения по возрасту кажется нормально распределенным с перекосом вправо. Также наименьший возраст составляет 40 лет, а наиболее часто встречающиеся числа находятся в диапазоне 55–60 лет.
  • Доля графика анемии, доля неинфицированных анемий больше, чем анемий инфицированных 57%
  • график распределения креатинин_фосфокиназы, наиболее часто встречающиеся числа находятся в диапазоне от 0 до 1000, и есть некоторые выбросы.
  • Доля графика диабета, доля недиабетиков больше, чем диабетиков с 58%
  • График распределения Ejection_fraction кажется нормально распределенным, также наиболее частые значения находятся в диапазоне 30–40.
  • Диаграмма высокого_кровяного_давления, высокое давление меньше, чем отсутствие высокого давления, где значения высокого давления составляют около 110, а значения без высокого давления составляют около 190.
  • График распределения тромбоцитов, наиболее частые числа находятся в диапазоне 200 000–400 000, и есть некоторые выбросы.
  • График распределения сыворотки_креатинина, наиболее часто встречающиеся числа находятся в диапазоне от 0 до 2, и есть некоторые выбросы.
  • График распределения натрия в сыворотке кажется нормально распределенным с перекосом подъема, наиболее частые числа находятся в диапазоне 135–140.
  • Доля графика пола, доля женщин больше, чем мужчин с 65%
  • График доли курящих, мы видим, что доля некурящих больше, чем курящих с 68%
  • Доля графика событий смерти, доля выживших больше, чем умерших с 68%

2- Предварительная обработка данных

Перед запуском любых алгоритмов интеллектуального анализа данных необходима предварительная обработка.

-Обнаружение пустых значений

Мы видим, что в столбце «ejection_fraction» есть 15 нулевых значений.

data_0.isnull().sum()

Здесь мы заполним нулевые значения средним значением этого столбца («ejection_fraction»)

data_0.replace(" ", np.nan, inplace = True)
avg_ejection_fraction=data_0['ejection_fraction'].astype('float').mean(axis=0)
print("Average of ejection_fraction:", avg_ejection_fraction)
data_0["ejection_fraction"].replace(np.nan, avg_ejection_fraction, inplace=True)

Теперь мы видим, что пустых значений больше нет

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

# Correlation analysis (Heat Map)
corrMatt = data_0.corr()
mask = np.array(corrMatt)
mask[np.tril_indices_from(mask)] = False
fig,ax= plt.subplots()
fig.set_size_inches(20,10)
sns.heatmap(corrMatt, mask=mask,vmax=.8, square=True,annot=True)

Тепловая карта выше показывает, что наибольшая корреляция наблюдается между временем (период наблюдения) и СОБЫТИЕМ СМЕРТИ со значением -0,53 (отрицательная корреляция). Далее следуют креатинин сыворотки, фракция выброса и возраст со значениями корреляции 0,29, 0,26 и 0,25 со смертельным исходом соответственно.

Здесь мы собираемся разделить данные на Train & Test, что является важным этапом предварительной обработки в нашем проекте.

Во-первых, мы разделим входы и выходы. где вывод: столбец «Death_event»

#input
data_1 = data_0.drop('DEATH_EVENT', axis=1)
data_1 = np.array(data_1, dtype=int)
#output
target_1 = data_0['DEATH_EVENT']
target_1 = np.array(target_1, dtype=int)

Во-вторых, разделите данные для обучения и тестирования, где: 80% для обучения и 20% для тестирования.

#Calling some extra libraries
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import normalize
# splitting the data for training and testing
x_train, x_test, y_train, y_test = train_test_split(data_1, target_1, test_size=0.2, random_state=4)

И здесь, в качестве последнего шага в предварительной обработке данных, мы нормализуем набор данных. Нормализация была выполнена, чтобы сделать все значения атрибутов между нулем и единицей (0–1) для достижения большей точности.

x_train = normalize(x_train)
x_test = normalize(x_test)

3- Моделирование

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

  • Применение K ближайших соседей (KNN)

Прежде всего, мы попробовали K = 4, и точность была = 0,75.

# I will start the algorithm with k=4 for now:
k = 4
#Train Model and Predict
neigh = KNeighborsClassifier(n_neighbors = k).fit(x_train,y_train)
neigh
# use the model to make predictions on the test set
yhat = neigh.predict(x_test)
yhat[0:5]
# Accuracy evaluation
from sklearn import metrics
print("Train set Accuracy: ", metrics.accuracy_score(y_train, neigh.predict(x_train)))
print("Test set Accuracy: ", metrics.accuracy_score(y_test, yhat))

Затем мы использовали код, отображающий оптимальное значение K для наилучшей точности.

#checking the best number of k
Ks = 10
mean_acc = np.zeros((Ks-1))
std_acc = np.zeros((Ks-1))
for n in range(1,Ks):
  #Train Model and Predict
  neigh = KNeighborsClassifier(n_neighbors = n).fit(x_train,y_train)
  yhat=neigh.predict(x_test)
  mean_acc[n-1] = metrics.accuracy_score(y_test, yhat)
  std_acc[n-1]=np.std(yhat==y_test)/np.sqrt(yhat.shape[0])
mean_acc
#Plot the model accuracy for a different number of neighbors
plt.plot(range(1,Ks),mean_acc,'g')
plt.fill_between(range(1,Ks),mean_acc - 1 * std_acc,mean_acc + 1 * std_acc, alpha=0.10)
plt.fill_between(range(1,Ks),mean_acc - 3 * std_acc,mean_acc + 3 * std_acc, alpha=0.10,color="green")
plt.legend(('Accuracy ', '+/- 1xstd','+/- 3xstd'))
plt.ylabel('Accuracy ')
plt.xlabel('Number of Neighbors (K)')
plt.tight_layout()
plt.show()

Из приведенного выше графика ясно видно, что K=5 дает наилучшую точность, где она составляет 78,33%.

давайте проверим это

#Checking the accuracy of k=5
k = 5
neigh6 = KNeighborsClassifier(n_neighbors = k).fit(x_train,y_train)
yhat6 = neigh6.predict(x_test)
print("Train set Accuracy: ", metrics.accuracy_score(y_train, neigh6.predict(x_train)))
print("Test set Accuracy: ", metrics.accuracy_score(y_test, yhat6))

  • Применение наивного байесовского алгоритма

Мы применяем следующий код для наивной байесовской классификации

from sklearn.naive_bayes import GaussianNB
classifier = GaussianNB()
classifier.fit(x_train, y_train)
y_pred  =  classifier.predict(x_test)

Отлично.. Затем следующий код, чтобы получить точность

from sklearn.metrics import confusion_matrix,accuracy_score
ac = accuracy_score(y_test,y_pred)
print("Test set Accuracy: " ,ac)

Таким образом, точность алгоритма наивного Байеса составляет 71,66%.

4- Оценка

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

а) Результаты KNN

Прежде всего, мы применим код матрицы путаницы для KNN.

cnf_matrix = confusion_matrix(y_test, yhat6, labels=[1,0])
np.set_printoptions(precision=2)
# Plot non-normalized confusion matrix
plt.figure()
plot_confusion_matrix(cnf_matrix, classes=['DEATH_EVENT=1','DEATH_EVENT=0'],normalize= False,  title='Confusion matrix')

Согласно приведенному выше графику матрицы путаницы, общее прогнозируемое значение равно 60, что идентично количеству тестовых значений.

Ожидаемое значение для 18 значений – 1 (умер), а для 42 значений – 0 (выживание)

  • 8 из 18 значений смертности были предсказаны правильно, а 10 — неправильно.
  • 39 из 42 значений выживаемости были предсказаны правильно, а 3 были предсказаны неправильно.

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

print (classification_report(y_test, yhat6))

  • Точность — это мера точности при условии, что метка класса была предсказана. Он определяется точностью = TP / (TP + FP)
  • Напомним, это истинный положительный показатель. Он определяется как: Отзыв = TP / (TP + FN).
  • Показатель F1 представляет собой гармоническое среднее значение точности и полноты, при этом показатель F1 достигает своего наилучшего значения при 1 (идеальная точность и полнота), а наихудшего значения — 0.

Мы можем сказать, что средняя точность этого классификатора — это среднее значение F1-показателя для обоих ярлыков, которое в нашем случае равно 0,77.

б) Наивные байесовские результаты

Мы снова применим код матрицы путаницы для наивного Байеса.

cnf_matrix = confusion_matrix(y_test, y_pred, labels=[1,0])
np.set_printoptions(precision=2)
# Plot non-normalized confusion matrix
plt.figure()
plot_confusion_matrix(cnf_matrix, classes=['DEATH_EVENT=1','DEATH_EVENT=0'],normalize= False,  title='Confusion matrix')

Согласно приведенному выше графику матрицы путаницы, общее прогнозируемое значение равно 60, что идентично количеству тестовых значений.

Ожидаемое значение для 18 значений – 1 (умер), а для 42 значений – 0 (выживание)

  • 4 из 18 значений смертности были предсказаны правильно, а 14 - неправильно.
  • 39 из 42 значений выживаемости были предсказаны правильно, а 3 были предсказаны неправильно.

Затем отчет о классификации для наивного байесовского

print (classification_report(y_test, y_pred))

Мы можем сказать, что средняя точность этого классификатора – это среднее значение F1-показателя для обоих ярлыков, которое в нашем случае равно 0,67.

Итак, вывод..

В этом исследовании мы работали с набором данных клинических записей о сердечной недостаточности и следовали процессам CRISP-DM для завершения работы. Кроме того, мы использовали два алгоритма классификации для прогнозирования наступления смерти. Средняя точность алгоритмов KNN составляет 77 процентов, тогда как средняя точность наивного байесовского алгоритма составляет 67 процентов. Как следствие, мы можем заключить, что алгоритм KNN дает лучшие результаты и более точные прогнозы.