Vorhersage von Herzinfarkten: Erkenntnisse durch prädiktive Modellierung mit Python | von Muttineni Sai Rohith | Juli 2023

0
42


Stellen Sie sich Folgendes vor: eine Kristallkugel, die Herzinfarkte vorhersagen kann, bevor sie auftreten. Klingt wie aus einem Science-Fiction-Movie, oder? Nun, dank der Wunder des maschinellen Lernens und der Zauberei der Python-Programmierung sind wir nicht mehr weit davon entfernt, diese Fantasie in die Realität umzusetzen.

Willkommen im Bereich der prädiktiven Modellierung, wo die Leistungsfähigkeit von Daten und modernster Technologie zusammenlaufen, um eine der kritischsten Herausforderungen der Herz-Kreislauf-Gesundheit zu bewältigen: die Vorhersage von Herzinfarkten. In diesem Artikel tauchen wir in die faszinierende Welt der Herzinfarktvorhersage ein und nutzen dabei die Fähigkeiten der Vorhersagemodellierung mit Python.

Prädiktive Modellierung: — Es bezieht sich auf den Prozess der Erstellung und Nutzung mathematischer oder statistischer Modelle, um Vorhersagen oder Vorhersagen über zukünftige Ergebnisse oder Ereignisse zu treffen. Dabei werden historische Daten analysiert und Muster und Beziehungen zwischen Variablen identifiziert, um ein Modell zu entwickeln, das zur Vorhersage des Verhaltens oder Ergebnisses einer bestimmten Zielvariable verwendet werden kann.

Der prädiktive Modellierungsprozess umfasst typischerweise mehrere Schritte, einschließlich Datenerfassung, Datenvorverarbeitung, Characteristic-Engineering, Modelltraining, Modellbewertung und Vorhersage. In diesem Artikel werden wir den gleichen Prozess anwenden, um Herzinfarkte vorherzusagen.

Datensammlung

Auf der Suche nach geeigneten Daten für unser Risikostratifizierungsprojekt zur Vorhersage von Herzinfarkten bin ich darauf gestoßen Datensatz im UCI-Repository. Trotz seiner geringeren Größe enthält es alle wesentlichen Funktionen, die wir benötigen, und ist somit ein idealer Ausgangspunkt für unsere Analyse und Modellentwicklung.

import pandas as pd

knowledge = pd.read_csv("/content material/coronary heart.csv")
knowledge.head()

Momentaufnahme der Daten

Es handelt sich um einen sauberen und leicht verständlichen Datensatz mit der Kind 1025 * 14. Die Bedeutung einiger Spaltenüberschriften ist jedoch nicht offensichtlich. Hier ist, was sie bedeuten:

  • Alter: Das Alter der Individual in Jahren
  • Geschlecht: Das Geschlecht der Individual (1 = männlich, 0 = weiblich)
  • cp: Der erlebte Brustschmerz (Wert 0: typische Angina, Wert 1: atypische Angina, Wert 2: nicht-anginöser Schmerz, Wert 3: asymptomatisch)
  • trestbps: Der Ruheblutdruck der Individual (mm Hg bei Aufnahme ins Krankenhaus)
  • chol: Der Cholesterinwert der Individual in mg/dl
  • fbs: Der Nüchternblutzucker der Individual (> 120 mg/dl, 1 = wahr; 0 = falsch)
  • restecg: Ruhe-Elektrokardiographiemessung (0 = regular, 1 = mit ST-T-Wellen-Anomalie, 2 = zeigt wahrscheinliche oder eindeutige linksventrikuläre Hypertrophie nach Estes-Kriterien)
  • Thalach: Die maximale erreichte Herzfrequenz der Individual
  • Beispiel: Belastungsangina (1 = ja; 0 = nein)
  • oldpeak: ST-Senkung durch Coaching im Verhältnis zur Ruhe („ST“ bezieht sich auf Positionen im EKG-Diagramm. Weitere Informationen finden Sie hier)
  • Steigung: die Steigung des Spitzenbelastungs-ST-Segments (Wert 1: ansteigend, Wert 2: flach, Wert 3: abfallend)
  • ca: Die Anzahl der großen Schiffe (0–3)
  • Thal: Eine Bluterkrankung namens Thalassämie (3 = regular; 6 = fester Defekt; 7 = reversibler Defekt)
  • Ziel: Herzerkrankung (0 = nein, 1 = ja)

Lassen Sie uns in die Vorverarbeitung dieser Daten eintauchen.

Vorverarbeitung –

Aufgrund der jüngsten Weiterentwicklung hätte ich es im Allgemeinen vorgezogen, PandasAI oder pandas_profiling für die Vorverarbeitung der Daten zu verwenden.

Beispiel –

import pandas_profiling as df_report
df_report.ProfileReport(knowledge)

Probieren Sie es aus und erleben Sie die Wunder. Es fasst die gesamten Daten zusammen und stellt Ihnen alle zugehörigen Informationen zur Verfügung. Aber für diesen Artikel folgen wir dem manuellen Prozess –

Beginnen wir mit der Erkennung fehlender Werte –

knowledge.isnull().sum()
Erkennung fehlender Werte

Glücklicherweise fehlen in den Daten keine Werte. Lassen Sie uns die Datenredundanz überprüfen –

knowledge.duplicated().sum()
Datenvervielfältigung

Hoppla, wir hatten bereits weniger Daten und davon sind 723 Datensätze dupliziert. Aber ich denke, dass die verbleibenden Aufzeichnungen ausreichen werden, um unseren Zweck zu erfüllen, da es wirklich schwierig ist, an diese sensiblen Daten zu gelangen. Entfernen wir additionally diese Datensätze und gehen wir weiter

knowledge.drop_duplicates(inplace=True)

Lassen Sie uns nun die Daten analysieren, um einen Überblick über die Korrelation der Felder zu erhalten und daraus einige Erkenntnisse abzuleiten.

from plotly.subplots import make_subplots
import plotly.graph_objects as go

df=knowledge[['sex','age','target']]
df['sex'].change({1:'Male',0:'Feminine'},inplace=True)
df['target'].change({1:'Coronary heart Affected person',0:'Wholesome'},inplace=True)

fig = make_subplots(rows=1, cols=2,specs=[[{"type": "histogram"}, {"type": "histogram"}]])
fig.add_trace(
go.Histogram(
x=df['age'].the place(df['target']=='Coronary heart Affected person'),
title='Coronary heart Affected person',
nbinsx=20,
showlegend=False,
marker={"coloration": '#f84242'}
),
row=1,col=1
)
fig.add_trace(
go.Histogram(
x=df['age'].the place(df['target']=='Wholesome'),
title='Wholesome',
nbinsx=20,
showlegend=False,
marker={"coloration": 'white'}
),
row=1,col=1
)
fig.add_trace(
go.Histogram(
x=df['sex'].the place(df['target']=='Coronary heart Affected person'),
title='Coronary heart Affected person',
nbinsx=20,
marker={"coloration": '#f84242'}
),
row=1,col=2
)
fig.add_trace(
go.Histogram(
x=df['sex'].the place(df['target']=='Wholesome'),
title='Wholesome',
nbinsx=20,
marker={"coloration": 'white'}
),
row=1,col=2
)

fig.update_layout(top=500,
title_text="<b>Age & Gender Distribution<b>",
title_font_size=30,
bargap=0.1,
template='plotly_dark',
)
fig.update_xaxes(title_text="Age", row=1, col=1)
fig.update_yaxes(title_text="Depend", row=1, col=1)

fig.update_xaxes(title_text="Gender", row=1, col=2)
fig.update_yaxes(title_text="Depend", row=1, col=2)

fig.present()

Alters- und Geschlechtsverteilung

Das erste mit Plotly erstellte Unterdiagramm zeigt die Altersverteilung mit separaten Histogrammen für Herzpatienten und gesunde Personen. Der zweite Teilplot zeigt die Geschlechterverteilung.

Wie wir wissen, sind Frauen anfälliger für Herzinfarkte als Männer, in diesen Daten sind quick 75 % der Frauen Herzpatienten, und Menschen in der Altersgruppe 35–55 sind anfälliger dafür, Herzpatienten zu werden.

Wiederholen wir die gleiche Analyse für Brustschmerzen und maximale Herzfrequenz, indem wir den obigen Code anpassen –

cp1=knowledge.the place(knowledge['target']==0).groupby(by=["cp"]).measurement().reset_index(title="Depend")
cp0=knowledge.the place(knowledge['target']==1).groupby(by=["cp"]).measurement().reset_index(title="Depend")

cp0['cp'].change({0:'Sort 1',1:'Sort 2',2:'Sort 3',3:'Sort 4'},inplace=True)
cp1['cp'].change({0:'Sort 1',1:'Sort 2',2:'Sort 3',3:'Sort 4'},inplace=True)

df1=knowledge[['thalach','chol','target','age','trestbps']]
df1['targetname']=df1['target'].change({1:'Coronary heart Affected person',0:'Wholesome'})

fig = make_subplots(rows=1, cols=2,specs=[[{"type": "histogram"}, {"type": "scatter"}]])
fig.add_trace(
go.Bar(
x=cp0['cp'],y=cp0.Depend,marker={"coloration": 'white'},title='Wholesome'
),
row=1,col=1
)
fig.add_trace(
go.Bar(
x=cp1['cp'],y=cp1.Depend,marker={"coloration": '#f84242'},title='Coronary heart Affected person'
),
row=1,col=1
)
fig.update_layout(top=500,
title_text="<b>Chest Ache & Max Coronary heart Fee<b>",
title_font_size=30,
bargap=0.1,
template='plotly_dark',
)
fig.add_trace(
go.Scatter(x=df1.thalach, y=df1.age, mode='markers', textual content=df1['targetname'],showlegend=False,
marker=dict(
coloration=df1.goal,
colorscale=['white','#f84242'],
line_width=1)
),
row=1,col=2
)
fig.update_xaxes(title_text="Chest Ache Sort", row=1, col=1)
fig.update_yaxes(title_text="Depend", row=1, col=1)

fig.update_xaxes(title_text="Max. Coronary heart Fee", row=1, col=2)
fig.update_yaxes(title_text="Age", row=1, col=2)

fig.present()

Brustschmerzen und maximale Herzfrequenzverteilung

Wie wir beobachten können, besteht bei Menschen mit Brustschmerzen vom Typ 1 im Vergleich zu anderen Brustschmerztypen ein hohes Erkrankungsrisiko. Auch eine höhere maximale Herzfrequenz bei jüngeren Kandidaten gilt als Hauptsymptom einer Herzerkrankung.

In diesem Prozess können wir die gleiche Analyse auch für die übrigen Felder in den Daten durchführen. Aber der Artikel wird länger, additionally sehen wir uns die Korrelation zwischen den Feldern direkt an.

import seaborn as sb
import matplotlib.pyplot as plt

sb.set(type="white")
plt.rcParams['figure.figsize']=(15,15)
sb.heatmap(knowledge.corr(),annot= True, linewidth=0.5)
plt.title("Correlation between variables")

Korrelation

Hier korrelieren wir die Felder basierend auf dem gesamten Datensatz. Basierend auf dieser Korrelation können wir ableiten, dass Brustschmerzen und maximale Herzfrequenz mit unserer Zielvariablen (Herzpatient oder nicht) korrelieren. Ich bevorzuge auch den Vergleich der Daten basierend auf Datenintervallen, aber wir werden in diesem Artikel nicht darauf eingehen. Aber lassen Sie mich Ihnen den Code-Schnappschuss geben, falls jemand es versuchen möchte –

for seq_columns in ["age","trestbps","thalach","oldpeak","chol"]:
print(knowledge.groupby([pd.cut(data[seq_columns],5)])['target'].imply())
for categ_columns in checklist(set(knowledge.columns) - set(["age","trestbps","thalach","oldpeak","chol","target"])):
print(knowledge.groupby(categ_columns)['target'].imply())

Abhängig von der Analyse der Ausgabe können wir die folgenden Erkenntnisse ableiten:

  • Je höher die Herzfrequenz, desto größer ist die Probability, ein Herzpatient zu sein.
  • Bei Brustschmerzen vom Typ 1 besteht im Vergleich zu anderen Brustschmerzarten ein hohes Erkrankungsrisiko
  • Wenn der Cholesterinspiegel 475 übersteigt, ist das Risiko eines Herzinfarkts viel höher.
  • Frauen sind anfälliger für Herzerkrankungen als Männer
  • Belastungsangina ist die Hauptursache für Herzinfarkte bei jungen Menschen

Wir können weitere Erkenntnisse gewinnen, indem wir die einzelnen Felder abschließend durchgehen. Für den Zweck des Artikels gehen wir jedoch auf den Modellierungsteil ein, in dem wir mithilfe von maschinellem Lernen Herzinfarkte vorhersagen können.

from sklearn.preprocessing import StandardScaler

knowledge=pd.get_dummies(knowledge,columns=['sex','cp','restecg','exang','slope','ca','thal','fbs'])
scaler=StandardScaler()
scaledColumns=['age','trestbps','thalach','oldpeak','chol']
knowledge[scaledColumns]=scaler.fit_transform(knowledge[scaledColumns])
knowledge.head()

Da wir einige kategoriale Felder haben, konvertieren wir sie zur geeigneten Analyse in binäre Spalten und normalisieren die Felder mithilfe von standardScaler, damit sie mit den restlichen Daten übereinstimmen.

Modellentwicklung

Teilen wir die Daten für Coaching und Assessments auf –

from sklearn.model_selection import train_test_split

x = knowledge.drop(columns='goal',axis=1)
y = knowledge['target']
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,stratify=y)
print(x_train.form,x_test.form)

Wir bewahren 20 % der Daten (61 Zeilen) zum Testen und 80 % der Daten (241 Zeilen) für das Coaching auf. Um unser Modell nicht zu stark anzupassen, habe ich dieses Verhältnis berücksichtigt. Außerdem werden wir die 10-fache Kreuzvalidierung als unseren Bewertungsparameter berechnen, um sicherzustellen, dass die Daten korrekt angepasst werden.

Beginnen wir mit der logistischen Regression –

from sklearn.metrics import confusion_matrix,accuracy_score,roc_curve,classification_report
from sklearn.model_selection import cross_val_score,GridSearchCV
from sklearn.linear_model import LogisticRegression

mannequin=LogisticRegression()
mannequin.match(x_train,y_train)
train_pred=mannequin.predict(x_train)
rating=accuracy_score(y_train,train_pred)

print("Prepare Accuracy Rating : ",rating*100)
test_pred=mannequin.predict(x_test)
test_score=accuracy_score(y_test,test_pred)
print("Take a look at Accuracy Rating : ",test_score*100,'nn')

lrScore=cross_val_score(mannequin,x,y,cv=10).imply()*100
print("10-Fold CV Rating : ",lrScore,'n')

print("Confusion Matrix : n",confusion_matrix(y_test,test_pred),'nn')
print(classification_report(y_test,test_pred))

Wir haben einen Cross-Validation-Rating von 85 % bis 10-fach erreicht.

Bei der 10-fachen Kreuzvalidierungsbewertung handelt es sich um eine Technik, die die Daten in 10 Teilmengen aufteilt, das Modell 10 Mal mit verschiedenen Teilmengen trainiert und testet und die durchschnittliche Leistungsbewertung als Schätzung der Generalisierungsfähigkeit des Modells berechnet.

Lassen Sie uns verschiedene Algorithmen ausprobieren, die Punktzahl berechnen und denjenigen verwenden, der genau vorhersagt –

---------------------------------------------------------------------------
#KNN

from sklearn.neighbors import KNeighborsClassifier

knn=KNeighborsClassifier(n_neighbors=1,n_jobs=-1)
knn.match(x_train,y_train)
train_pred=knn.predict(x_train)
rating=accuracy_score(y_train,train_pred)

---------------------------------------------------------------------------
#SVC

from sklearn.svm import SVC

svm = SVC(C=4, diploma=8, kernel='poly',max_iter=1000)
svm.match(x_train,y_train)

train_pred=svm.predict(x_train)
rating=accuracy_score(y_train,train_pred)

---------------------------------------------------------------------------
#Navie Bayes or Guassian

from sklearn.naive_bayes import GaussianNB

nb=GaussianNB()
nb.match(x_train,y_train)
train_pred=nb.predict(x_train)
rating=accuracy_score(y_train,train_pred)

---------------------------------------------------------------------------
# Determination Tree

from sklearn.tree import DecisionTreeClassifier

dt=DecisionTreeClassifier(criterion = 'entropy',random_state=0,max_depth = 12)
dt.match(x_train,y_train)
train_pred=dt.predict(x_train)
rating=accuracy_score(y_train,train_pred)
---------------------------------------------------------------------------
# Random Forest

from sklearn.ensemble import RandomForestClassifier
randFor = RandomForestClassifier(n_estimators=1000, random_state = 35)
randFor.match(x_train, y_train)
train_pred=randFor.predict(x_train)
rating=accuracy_score(y_train,train_pred)
---------------------------------------------------------------------------
# XGBoost

from xgboost import XGBClassifier

xgb = XGBClassifier(n_estimators=200)
xgb.match(x_train, y_train)
train_pred=xgb.predict(x_train)
rating=accuracy_score(y_train,train_pred)
---------------------------------------------------------------------------

Anstatt einen Algorithmus nach dem anderen anzuzeigen, habe ich den Code oben angegeben. Sie können den folgenden Code optimieren, indem Sie Variablennamen ändern, um Genauigkeiten für den Algorithmus zu erhalten.

print("Prepare Accuracy Rating : ",rating*100)
test_pred=xgb.predict(x_test)
test_score=accuracy_score(y_test,test_pred)
print("Take a look at Accuracy Rating : ",test_score*100,'nn')

xgbScore = cross_val_score(xgb,x,y,cv=10).imply()*100
print("10-Fold CV Rating : ",xgbScore,'n')

print("Confusion Matrix : n",confusion_matrix(y_test,test_pred),'nn')
print(classification_report(y_test,test_pred))

Modellvergleich

Modellvergleich

Da die Datenmenge sehr gering ist, lieferte uns die logistische Regression im Vergleich zu den anderen eine gute Genauigkeit. Außerdem habe ich in den übrigen Algorithmen nicht viel mit den Hyperparametern gespielt. Aber diese Modellierung dient pädagogischen Zwecken und ich denke, mit dem Relaxation kann man weitermachen.

Denken Sie daran: Obwohl wir den 10-fachen CV-Rating als Hauptbewertungsparameter verwendet haben, ist Präzision im Gesundheitswesen auch ein wesentlicher Parameter, auf den wir uns konzentrieren sollten. Hohe Präzision bedeutet, dass die positiven Vorhersagen (Patienten mit hohem Risiko) mit größerer Wahrscheinlichkeit zutreffend sind. In diesem Fall möchten Sie sicherstellen, dass die als Hochrisikopatienten identifizierten Personen tatsächlich eine höhere Wahrscheinlichkeit haben, einen Herzinfarkt zu erleiden.

Es ist jedoch auch wichtig, die Auswirkungen falsch negativer Ergebnisse (übersehene Hochrisikopatienten) zu berücksichtigen. Wenn Ihr Ziel darin besteht, so viele Hochrisikopatienten wie möglich zu identifizieren, mit dem Ziel einer frühzeitigen Intervention oder einer engmaschigen Überwachung, dann ist die Rückrufaktion von entscheidender Bedeutung. Eine hohe Rückrufquote bedeutet, dass Sie einen größeren Anteil tatsächlich positiver Fälle erfassen.

Ich hoffe, Sie finden diesen Artikel hilfreich.

Viel Spaß beim Lernen…..



Source link

HINTERLASSEN SIE EINE ANTWORT

Please enter your comment!
Please enter your name here