Вас только что наняли в качестве специалиста по данным.

Содержание

1. Введение. Сценарии и цели, функции и прогнозирование

2. Обработка данных

3. Исследовательский анализ данных: корреляции, графики скрипки и ящика, фильтрация данных по положительным и отрицательным пациентам с болезнью сердца

4. Машинное обучение + прогнозная аналитика: подготовка данных для моделирования, моделирования / обучения, матрицы путаницы, важности функций, прогнозов ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍ ‍

5. Выводы

1. Введение

Сценарий:

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

Цель:

  • Предскажите, стоит ли диагностировать у пациента болезнь сердца. Это двоичный результат.
    Положительно (+) = 1, у пациента диагностировано заболевание сердца
    Отрицательно (-) = 0, у пациента не диагностировано заболевание сердца.
  • Поэкспериментируйте с различными моделями классификации и посмотрите, какая из них дает наибольшую точность.
  • Изучите тенденции и корреляции в наших данных
  • Определите, какие особенности являются наиболее важными для постановки диагноза "положительный / отрицательный порок сердца".

Особенности и предсказатель:

Наш предиктор (Y, положительный или отрицательный диагноз болезни сердца) определяется 13 характеристиками (X):

1. возраст (#)
2. пол: 1 = мужской, 0 = женский (двоичный)
3 . (cp) тип боли в груди (4 значения - Порядковый): значение 1: типичная стенокардия, значение 2: атипичная стенокардия, значение 3: неангинальная боль, значение 4. : бессимптомно
4. (trestbps) артериальное давление в покое (#)
5. (chol) холестерин сыворотки в мг / дл (#) < br /> 6. (fbs) уровень сахара в крови натощак ›120 мг / дл (Двоичный) (1 = true; 0 = false)
7. ( restecg) результаты электрокардиографии в покое (значения 0,1,2)
8. (thalach) достигнутая максимальная частота пульса (#)
9. ( exang) стенокардия, вызванная нагрузкой (бинарная) (1 = да; 0 = нет)
10. (oldpeak) = индуцированная депрессия ST по упражнению относительно отдыха (#)
11. (наклон) сегмента ST пиковой нагрузки (Порядковый) (Значение 1: наклон вверх, Значение 2: плоский, Значение 3: наклон вниз)
12. (ca) количество крупных сосудов (0–3, порядковый номер), окрашенных при рентгеноскопии
13 (thal) максимальная достигнутая частота пульса - (порядковый номер): 3 = нормальный; 6 = исправленный дефект; 7 = обратимый дефект

Примечание. Наши данные содержат 3 типа данных:

Непрерывный (#): количественные данные, которые можно измерить.

Порядковые данные: категориальные данные, которые имеют порядок (0,1,2,3 и т. д.).

Двоичные данные: данные, единица которых может принимать только два возможных состояния (0 и 1).

2. Преодоление данных

import numpy as np
import pandas as pd
import matplotlib as plt
import seaborn as sns
import matplotlib.pyplot as plt
filePath = '/Users/jarar_zaidi/Downloads/datasets-33180-43520-heart.csv'

data = pd.read_csv(filePath)

data.head(5)

print("(Rows, columns): " + str(data.shape))
data.columns

data.nunique(axis=0)# returns the number of unique values for each variable.

#summarizes the count, mean, standard deviation, min, and max for numeric variables.
data.describe()

# Display the Missing Values

print(data.isna().sum())

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

data['target'].value_counts()

3. Исследовательский анализ данных

Корреляции

Матрица корреляции - позволяет увидеть корреляцию между всеми переменными.

Через несколько секунд вы сможете увидеть, положительно или отрицательно коррелирует что-то с нашим предиктором (целью).

# calculate correlation matrix

corr = data.corr()
plt.subplots(figsize=(15,10))
sns.heatmap(corr, xticklabels=corr.columns, yticklabels=corr.columns, annot=True, cmap=sns.diverging_palette(220, 20, as_cmap=True))
sns.heatmap(corr, xticklabels=corr.columns,
            yticklabels=corr.columns, 
            annot=True,
            cmap=sns.diverging_palette(220, 20, as_cmap=True))

Мы видим, что существует положительная корреляция между болью в груди (cp) и целью (нашим предсказателем). Это имеет смысл, поскольку сильная боль в груди увеличивает вероятность сердечного заболевания. Cp (боль в груди) - это порядковый признак с 4 значениями: значение 1: типичная стенокардия, значение 2: атипичная стенокардия, значение 3: неангинальная боль, значение 4: бессимптомное течение.

Кроме того, мы видим отрицательную корреляцию между стенокардией, вызванной физической нагрузкой (exang), и нашим предсказателем. Это имеет смысл, потому что, когда вы тренируетесь, вашему сердцу требуется больше крови, суженные артерии замедляют кровоток.

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

subData = data[['age','trestbps','chol','thalach','oldpeak']]
sns.pairplot(subData)

sns.catplot(x="target", y="oldpeak", hue="slope", kind="bar", data=data);

plt.title('ST depression (induced by exercise relative to rest) vs. Heart Disease',size=25)
plt.xlabel('Heart Disease',size=20)
plt.ylabel('ST depression',size=20)

Депрессия сегмента ST возникает, когда желудочек находится в состоянии покоя и, следовательно, реполяризован. Если кривая в сегменте ST находится на аномально низком уровне ниже базовой линии, это может привести к заболеванию сердца. Это подтверждает график выше, потому что низкая депрессия ST повышает риск сердечных заболеваний. В то время как высокая депрессия ST считается нормальным и здоровым. Оттенок «наклон» относится к сегменту ST пиковой нагрузки со значениями: 0: восходящий, 1: ровный, 2: нисходящий). И у положительных, и у отрицательных пациентов с сердечными заболеваниями наблюдается одинаковое распределение трех категорий наклона.

Сюжеты для скрипки и шкатулки

Преимущества отображения графиков Box & Violin заключаются в том, что они показывают базовую статистику данных, а также их распределение . Эти графики часто используются для сравнения распределения данной переменной по некоторым категориям.

Он показывает медианное значение, IQR и предел Тьюки (минимум, первый квартиль (Q1), медиана, третий квартиль (Q3) и максимум).

Кроме того, он может предоставить нам выбросы в наших данных.

plt.figure(figsize=(12,8))
sns.violinplot(x= 'target', y= 'oldpeak',hue="sex", inner='quartile',data= data )
plt.title("Thalach Level vs. Heart Disease",fontsize=20)
plt.xlabel("Heart Disease Target", fontsize=16)
plt.ylabel("Thalach Level", fontsize=16)

plt.figure(figsize=(12,8))
sns.boxplot(x= 'target', y= 'thalach',hue="sex", data=data )
plt.title("ST depression Level vs. Heart Disease", fontsize=20)
plt.xlabel("Heart Disease Target",fontsize=16)
plt.ylabel("ST depression induced by exercise relative to rest", fontsize=16)

Фильтрация данных по положительным и отрицательным пациентам с болезнью сердца

# Filtering data by POSITIVE Heart Disease patient
pos_data = data[data['target']==1]
pos_data.describe()

# Filtering data by NEGATIVE Heart Disease patient
pos_data = data[data['target']==0]
pos_data.describe()

print("(Positive Patients ST depression): " + str(pos_data['oldpeak'].mean()))
print("(Negative Patients ST depression): " + str(neg_data['oldpeak'].mean()))

print("(Positive Patients thalach): " + str(pos_data['thalach'].mean()))
print("(Negative Patients thalach): " + str(neg_data['thalach'].mean()))

Сравнивая положительных и отрицательных пациентов, мы видим огромные различия в средствах для многих из наших 13 функций. Изучая детали, мы можем заметить, что положительные пациенты испытывают повышенную максимальную достигнутую частоту сердечных сокращений (талах). Кроме того, положительные пациенты демонстрируют примерно 1/3 степени депрессии ST, вызванной упражнениями, по сравнению с отдыхом (старый пик).

4. Машинное обучение + прогнозная аналитика.

Подготовьте данные для моделирования

Чтобы подготовить данные для моделирования, просто запомните ASN (Назначить, Разделить, Нормализовать).

Назначьте 13 характеристик значку X и последний столбец нашему предиктору классификации y.

X = data.iloc[:, :-1].values
y = data.iloc[:, -1].values

Разделить: набор данных на обучающий набор и тестовый набор.

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 = 1)

Нормализовать: стандартизация данных преобразует данные так, что их распределение будет иметь среднее значение 0 и стандартное отклонение 1.

from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
x_train = sc.fit_transform(x_train)
x_test = sc.transform(x_test)

Моделирование / Обучение

Теперь мы обучим различные модели классификации на обучающем наборе и посмотрим, какие дают наивысшую точность. Мы сравним точность логистической регрессии, K-NN ( k-ближайших соседей) , SVM (машина опорных векторов), наивный байесовский классификатор, деревья решений, Случайный лес и XGBoost.

Примечание. Все это модели обучения с учителем.

Модель 1: логистическая регрессия

from sklearn.metrics import classification_report 
from sklearn.linear_model import LogisticRegression

model1 = LogisticRegression(random_state=1) # get instance of model
model1.fit(x_train, y_train) # Train/Fit model 

y_pred1 = model1.predict(x_test) # get y predictions
print(classification_report(y_test, y_pred1)) # output accuracy

Модель 2: K-NN (K-ближайшие соседи)

from sklearn.metrics import classification_report 
from sklearn.neighbors import KNeighborsClassifier

model2 = KNeighborsClassifier() # get instance of model
model2.fit(x_train, y_train) # Train/Fit model 

y_pred2 = model2.predict(x_test) # get y predictions
print(classification_report(y_test, y_pred2)) # output accuracy

Модель 3: SVM (машина опорных векторов)

from sklearn.metrics import classification_report 
from sklearn.svm import SVC

model3 = SVC(random_state=1) # get instance of model
model3.fit(x_train, y_train) # Train/Fit model 

y_pred3 = model3.predict(x_test) # get y predictions
print(classification_report(y_test, y_pred3)) # output accuracy

Модель 4: наивный классификатор Байеса

from sklearn.metrics import classification_report 
from sklearn.naive_bayes import GaussianNB

model4 = GaussianNB() # get instance of model
model4.fit(x_train, y_train) # Train/Fit model 

y_pred4 = model4.predict(x_test) # get y predictions
print(classification_report(y_test, y_pred4)) # output accuracy

Модель 5. Деревья решений

from sklearn.metrics import classification_report 
from sklearn.tree import DecisionTreeClassifier

model5 = DecisionTreeClassifier(random_state=1) # get instance of model
model5.fit(x_train, y_train) # Train/Fit model 

y_pred5 = model5.predict(x_test) # get y predictions
print(classification_report(y_test, y_pred5)) # output accuracy

Модель 6: случайный лес 🏆

from sklearn.metrics import classification_report 
from sklearn.ensemble import RandomForestClassifier

model6 = RandomForestClassifier(random_state=1)# get instance of model
model6.fit(x_train, y_train) # Train/Fit model 

y_pred6 = model6.predict(x_test) # get y predictions
print(classification_report(y_test, y_pred6)) # output accuracy

Модель 7: XGBoost

from xgboost import XGBClassifier

model7 = XGBClassifier(random_state=1)
model7.fit(x_train, y_train)
y_pred7 = model7.predict(x_test)
print(classification_report(y_test, y_pred7))

Сравнивая 7 моделей, мы можем заключить, что Модель 6: Случайный лес дает самую высокую точность. С точностью до 80%. 🏆

Точность, отзывчивость, оценка F1 и Поддержка:

Точность: «сколько правильно отнесено к этому классу».

Вспомните: «сколько элементов этого класса вы найдете по всему количеству элементов этого класса»

F1-score: гармоническое среднее значений точности и повторения.
Оценка F1 достигает своего наилучшего значения при 1 и худшего значения при 0.
Оценка F1 = 2 x ((точность x отзыв) / (точность + отзыв))

Поддержка: количество образцов истинного ответа, относящихся к этому классу.

Создание матрицы путаницы

from sklearn.metrics import confusion_matrix, accuracy_score
cm = confusion_matrix(y_test, y_pred6)
print(cm)
accuracy_score(y_test, y_pred6)

Как интерпретировать матрицу неточностей:

21 - это количество истинных положительных результатов в наших данных, а 28 - количество истинных отрицательных результатов.

9 и 3 - это количество ошибок.

Имеется 9 ошибок 1-го типа (ложные срабатывания) - вы предсказали положительный результат, но он неверен.

Имеются 3 ошибки 2 типа (ложно-отрицательные) - вы предсказали отрицательный результат, но он неверен.

Следовательно, если мы вычисляем точность, это # ​​правильно спрогнозировано / # общее.
Другими словами, где TP, FN, FP и TN представляют количество истинных положительных результатов, ложных отрицательных результатов, ложных срабатываний. и истинные негативы.

Точность = (TP + TN) / (TP + TN + FP + FN).
Точность = (21 + 28) / (21 + 28 + 9 +3) = 0,80 = 80% точность

Важность функции

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

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

# get importance
importance = model6.feature_importances_

# summarize feature importance
for i,v in enumerate(importance):
    print('Feature: %0d, Score: %.5f' % (i,v))

index= data.columns[:-1]
importance = pd.Series(model6.feature_importances_, index=index)
importance.nlargest(13).plot(kind='barh', colormap='winter')

Прогнозы

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

Ему 20 лет, значение боли в груди 2 (атипичная стенокардия) и артериальное давление в состоянии покоя 110.

Кроме того, у него холесторальный уровень сыворотки 230 мг / дл.

У него уровень сахара в крови натощак ›120 мг / дл

У него результат электрокардиографии в покое 1.

Достигнутая максимальная частота пульса пациента составляет 140.

Кроме того, у него была стенокардия, вызванная физической нагрузкой.

Его депрессия ST, вызванная физическими упражнениями, по сравнению с уровнем покоя составила 2,2.

Наклон сегмента ST пиковой нагрузки плоский.

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

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

print(model6.predict(sc.transform([[20,1,2,110,230,1,1,140,1,2.2,2,0,2]])))

Прогнозирование результатов набора тестов:

Первое значение представляет наше прогнозируемое значение, Второе значение представляет наше фактическое значение.

Если значения совпадают, значит, мы предсказали правильно.

y_pred = model6.predict(x_test)
print(np.concatenate((y_pred.reshape(len(y_pred),1), y_test.reshape(len(y_test),1)),1))

Мы видим, что наши результаты очень точны (80%)!

Выводы

1. Из 13 изученных нами признаков 4 главными значимыми характеристиками, которые помогли нам классифицировать положительный и отрицательный диагноз, были тип боли в груди (cp), максимальная достигнутая частота сердечных сокращений (талах), количество крупных сосудов (ca) и депрессия ST. вызвано физическими упражнениями по сравнению с отдыхом (старый пик).

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

3. Наш алгоритм случайного леса дает наивысшую точность - 80%. Любая точность выше 70% считается хорошей, но будьте осторожны, потому что, если ваша точность чрезвычайно высока, она может быть слишком хорошей, чтобы быть правдой (пример чрезмерной подгонки). Таким образом, 80% - это идеальная точность!

Вот доступ к набору данных и коду с моей страницы GitHub:

Https://github.com/jzaidi143/Project-Predicting-Heart-Disease-with-Classification-Machine-Learning-Algorithms

Рекомендации и комментарии приветствуются!

Благодарности

Создатели:

  1. Венгерский институт кардиологии. Будапешт: Андраш Яноши, доктор медицины
  2. Университетская больница, Цюрих, Швейцария: Уильям Штайнбрунн, доктор медицины
  3. Университетская клиника, Базель, Швейцария: Маттиас Пфистерер, доктор медицины
  4. В.А. Медицинский центр, Фонд клиники Лонг-Бич и Кливленда: Роберт Детрано, доктор медицины, доктор философии.

Донор:
Дэвид В. Аха (aha ‘@’ ics.uci.edu) (714) 856–8779