Pada venture kali ini saya mengimplementasikan deep studying untuk memprediksi tingkat resiko serangan jantung seseorang, dengan mannequin ANN dan RNN.
!mkdir ~/.kaggle/
!contact ~/.kaggle/kaggle.jsonapi_token = cred
import json
with open('/root/.kaggle/kaggle.json', 'w') as file:
json.dump(api_token, file)
!chmod 600 ~/.kaggle/kaggle.json
!kaggle datasets obtain -d rashikrahmanpritom/heart-attack-analysis-prediction-dataset
!unzip "heart-attack-analysis-prediction-dataset.zip"
Dalam dataset yang saya gunakan terdapat 2 tipe kolom yakni, kolom numerik dan kolom kategorikal. Berikut adalah kolom deskripsi untuk fitur-fitur yang ada pada dataset ini.
Sebelum melakukan preprocessing, import semua library yang dibutuhkan untuk melakukan preprocessing maupun modelling.
import numpy as np
import pandas as pd
import tensorflow as tf
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn import metrics
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix, classification_report
from sklearn.preprocessing import StandardScalerknowledge = pd.read_csv("/content material/coronary heart.csv")
knowledge = knowledge.dropna()
knowledge
Setelah memeriksa dataset, ditemukan adanya outlier pada kolom numerik dengan nilai yang signifikan dari nilai yang diharapkan.
Dealing with Outliers
plt.determine(figsize=(12, 6))
knowledge.boxplot()
plt.present()
sns.set_context('pocket book', font_scale= 1.2)
fig, ax = plt.subplots(2, 2, figsize = (20, 10))plt.suptitle('Boxplot of assorted options based mostly on the right track variable', fontsize = 20)
ax1 = sns.boxplot(x ='age', knowledge= knowledge, ax= ax[0, 0], coloration="#08498f")
ax1.set(xlabel = 'Age')
ax2 = sns.boxplot(x ='trtbps', knowledge= knowledge, ax= ax[0, 1], coloration="#08498f")
ax2.set(xlabel = 'Resting blood strain (in mm Hg)')
ax3 = sns.boxplot(x ='chol', knowledge= knowledge, ax= ax[1, 0], coloration="#08498f")
ax3.set(xlabel = 'Ldl cholesterol in mg/dl')
ax4 = sns.boxplot(x ='thalachh', knowledge= knowledge, ax= ax[1, 1], coloration="#08498f")
ax4.set(xlabel = 'Max Coronary heart Charge Achieved')
plt.present()
Saya menghandle outliers dengan mengkonversikan nilai outliers menjadi nilai wajar maksimum atau minimal dari kolom tersebut. Nilai akan ditentukan dari nilai outliers sebelumnya, apakah melebihi atau kurang dari nilai wajarnya.
knowledge.chol.loc[data.chol > 360] = 360
knowledge.trtbps.loc[data.trtbps > 180] = 180
knowledge.thalachh.loc[data.thalachh < 80] = 80
Selanjutnya, untuk memudahkan saat proses analisa knowledge. Saya memisahkan dan mengubah kolom kategorikal menjadi string.
cat_columns = ['sex', 'cp', 'fbs', 'restecg', 'exng', 'slp', 'caa', 'thall', 'output']
num_columns = ['age', 'trtbps', 'oldpeak', 'chol', 'thalachh']
knowledge[cat_columns] = knowledge[cat_columns].astype(str)
EDA
Pertama, saya ingin mengetahui distribusi kelompok orang dengan resiko serangan jantung rendah (0) dan tinggi (1), berdasarkan fitur-fitur numerik.
sns.set_context('pocket book', font_scale= 1.2)
fig, ax = plt.subplots(2, 2, figsize = (20, 13))plt.suptitle('Distribution of assorted options based mostly on the right track variable', fontsize = 20)
ax1 = sns.histplot(x ='age', knowledge= knowledge, hue= 'output', kde= True, ax= ax[0, 0], palette='winter')
ax1.set(xlabel = 'Age', title= 'Distribution of age based mostly on the right track variable')
ax2 = sns.histplot(x ='trtbps', knowledge= knowledge, hue= 'output', kde= True, ax= ax[0, 1], palette='plasma')
ax2.set(xlabel = 'Resting blood strain (in mm Hg)', title= 'Distribution of BP based mostly on the right track variable')
ax3 = sns.histplot(x ='chol', knowledge= knowledge, hue= 'output', kde= True, ax= ax[1, 0], palette='winter')
ax3.set(xlabel = 'Cholestoral in mg/dl', title= 'Distribution of Cholestrol based mostly on the right track variable')
ax4 = sns.histplot(x ='thalachh', knowledge= knowledge, hue= 'output', kde= True, ax= ax[1, 1], palette='plasma')
ax4.set(xlabel = 'Max Coronary heart Charge Achieved', title= 'Distribution of most coronary heart price achieved based mostly on the right track variable')
plt.present()
Grafik menunjukkan perbedaan distribusi fitur-fitur kesehatan antara dua kelompok goal. Kelompok (1) cenderung memiliki distribusi yang lebih terpusat pada rentang tertentu dibandingkan kelompok (0).
Kemudian, terdapat kecenderungan antara kelompok (1) dengan Max Coronary heart Charge. Di mana, jumlah kelompok (1) meningkat seiring dengan meningkatnya Max Coronary heart Charge yang menandakan bahwa peningkatan Max Coronary heart Charge juga dapat meningkatkan resiko serangan jantung.
Kedua, saya ingin mengetahui korelasi antar fitur numerik menggunakan Heatmap Correlation Matrix.
correlation_matrix = knowledge[num_columns].corr()plt.determine(figsize=(16, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='Blues', fmt=".2f")
plt.title('Heatmap of Correlation Matrix')
plt.present()
Dari heatmap di atas, tidak ada korelasi antar fitur numerik yang dapat dijadikan acuan.
Ketiga, saya ingin mengetahui jumlah kelompok orang dengan resiko serangan jantung rendah (0) dan tinggi (1), berdasarkan fitur-fitur kategorikal.
Secara keseluruhan, ada perbedaan distribusi yang signifikan antara kategori kelompok (1) dan kelompok (0) pada beberapa fitur kategorikal, menunjukkan bahwa fitur-fitur ini bisa menjadi indikator penting untuk membedakan antara kedua kelompok.
Pre-Modelling
Sebelum melakukan modelling, saya mempersiapkan knowledge dummy dan kemudian membaginya menjadi dua bagian: X sebagai fitur untuk memprediksi output, dan Y sebagai nilai output sebenarnya.
Setelah itu, saya menormalisasi X menggunakan commonplace scaler dan break up knowledge X Y menjadi train_data dan test_data dengan perbandingan 4:1.
df = pd.get_dummies(knowledge, drop_first=True)X = df.drop(columns=['output_1'])
y = df["output_1"]
scaler = StandardScaler()
X = scaler.fit_transform(X)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
Membuat Mannequin
Karena pada kasus ini merupakan klasifikasi dan jumlah knowledge yang digunakan relatif kecil. Saya menggunakan 1 hidden layer dengan jumlah neuron 32 dan fungsi aktivasi ReLu. Saya juga mengimplementasikan Dropout untun menghindari overfitting. Pada Output layer, saya menggunakan 2 neuron dan karena ini adalah masalah klasifikasi biner (output 1 atau 0), layer output menggunakan fungsi aktivasi softmax.
ann = tf.keras.Sequential([
tf.keras.Input(22),
tf.keras.layers.Dense(32, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(2, activation='softmax')
])ann.compile(optimizer='adam',loss='sparse_categorical_crossentropy', metrics=['accuracy'])
historical past = ann.match(X_train, y_train, epochs=50, batch_size=32, validation_split=0.2, verbose=1)
Berikut adalah grafik Loss Mannequin saat Coaching dibanding dengan Validating.
plt.determine(figsize=(10, 6))EPOCHS = 50
epochs = vary(1, EPOCHS + 1)
train_loss = historical past.historical past['loss']
val_loss = historical past.historical past['val_loss']
plt.plot(epochs, train_loss, label="Coaching Loss",coloration="blue")
plt.plot(epochs, val_loss, label="Validation Loss", coloration="gray")
plt.title("Coaching and Validation Loss")
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.legend()
plt.present()
Evaluasi Mannequin
Untuk mengevaluasi mannequin saya, menggunakan 5 parameter yakni: accuracy rating, precision, recall, f1 scrore, confusion matrix.
y_pred = ann.predict(X_test)
y_pred_classes = np.argmax(y_pred, axis=1)
accuracy = accuracy_score(y_test, y_pred_classes)print("Accuracy:", accuracy)
print(classification_report(y_test,y_pred_classes))
Accuracy: 0.8524590163934426
precision recall f1-score helpFalse 0.86 0.83 0.84 29
True 0.85 0.88 0.86 32
accuracy 0.85 61
macro avg 0.85 0.85 0.85 61
weighted avg 0.85 0.85 0.85 61
confusion_matrix = metrics.confusion_matrix(y_test, y_pred_classes)
cm_display = metrics.ConfusionMatrixDisplay(confusion_matrix = confusion_matrix, display_labels = [0, 1])cm_display.plot(cmap='Blues')
plt.present()
Membuat Mannequin
Saya menggunakan arsitektur LSTM karena lebih baik untuk klasifikasi biner. Karena saya menggunakan LSTM, perlu dilakukan reshape enter menjadi 3D. Kemudian saya menggunakan 1 hidden layer dengan jumlah neuron 32 dan fungsi aktivasi ReLu. Saya juga mengimplementasikan Dropout untun menghindari overfitting. Pada Output layer, saya menggunakan 2 neuron dan karena ini adalah masalah klasifikasi biner (output 1 atau 0), layer output menggunakan fungsi aktivasi softmax.
rnn = tf.keras.Sequential([
tf.keras.layers.Reshape((1, 22), input_shape=(22,)),
tf.keras.layers.LSTM(32, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(2, activation='softmax')
])rnn.compile(optimizer='adam',loss='sparse_categorical_crossentropy', metrics=['accuracy'])
historical past = rnn.match(X_train, y_train, epochs=50, batch_size=32, validation_split=0.2, verbose=1)
Berikut adalah grafik Loss Mannequin saat Coaching dibanding dengan Validating.
plt.determine(figsize=(10, 6))EPOCHS = 50
epochs = vary(1, EPOCHS + 1)
train_loss = historical past.historical past['loss']
val_loss = historical past.historical past['val_loss']
plt.plot(epochs, train_loss, label="Coaching Loss",coloration="blue")
plt.plot(epochs, val_loss, label="Validation Loss", coloration="gray")
plt.title("Coaching and Validation Loss")
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.legend()
plt.present()
Evaluasi Mannequin
Untuk mengevaluasi mannequin, saya menggunakan 5 parameter yakni: accuracy rating, precision, recall, f1 scrore, confusion matrix.
y_pred = ann.predict(X_test)
y_pred_classes = np.argmax(y_pred, axis=1)
accuracy = accuracy_score(y_test, y_pred_classes)print("Accuracy:", accuracy)
print(classification_report(y_test,y_pred_classes))
Accuracy: 0.8688524590163934
precision recall f1-score helpFalse 0.84 0.90 0.87 29
True 0.90 0.84 0.87 32
accuracy 0.87 61
macro avg 0.87 0.87 0.87 61
weighted avg 0.87 0.87 0.87 61
confusion_matrix = metrics.confusion_matrix(y_test, y_pred_classes)
cm_display = metrics.ConfusionMatrixDisplay(confusion_matrix = confusion_matrix, display_labels = [0, 1])cm_display.plot(cmap='Blues')
plt.present()
Berdasarkan hasil evaluasi mannequin, dapat disimpulkan bahwa RNN memiliki kinerja yang sedikit lebih baik daripada ANN. RNN mencapai akurasi sebesar 87%, sedangkan ANN mencapai 85%. Dari confusion matrix, terlihat bahwa RNN membuat 8 kesalahan prediksi, sementara ANN membuat 9 kesalahan prediksi. Oleh karena itu, meskipun perbedaannya tipis, RNN cenderung memberikan hasil yang sedikit lebih baik dalam memprediksi klasifikasi.