{ "cells": [ { "cell_type": "markdown", "id": "6272d3e2", "metadata": {}, "source": [ "# Tachycardia Detection with MIMIC-IV ECG Dataset\n", "This notebook covers preprocessing, data analysis, training, and evaluation of a deep learning model to detect tachycardia using features extracted from the MIMIC-IV ECG dataset." ] }, { "cell_type": "code", "execution_count": 1, "id": "42ab76b9", "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.preprocessing import StandardScaler, OneHotEncoder\n", "from sklearn.compose import ColumnTransformer\n", "from sklearn.pipeline import Pipeline\n", "from sklearn.impute import SimpleImputer\n", "from sklearn.metrics import classification_report, confusion_matrix\n", "import warnings\n", "warnings.filterwarnings('ignore')" ] }, { "cell_type": "markdown", "id": "71862539", "metadata": {}, "source": [ "## Load and Inspect Dataset" ] }, { "cell_type": "code", "execution_count": null, "id": "29501216", "metadata": {}, "outputs": [], "source": [ "csv_path = './mimic_dataset/DATASET/df_ready.csv'\n", "df = pd.read_csv(csv_path)\n", "print(f'Dataset shape: {df.shape}')\n", "df.head()" ] }, { "cell_type": "markdown", "id": "ef4524ab", "metadata": {}, "source": [ "## Dataset Info and Description" ] }, { "cell_type": "code", "execution_count": null, "id": "7de77630", "metadata": {}, "outputs": [], "source": [ "print(df.info())\n", "df.describe(include='all')" ] }, { "cell_type": "markdown", "id": "da6eb70d", "metadata": {}, "source": [ "## Missing Values Analysis" ] }, { "cell_type": "code", "execution_count": null, "id": "0a5d7a4d", "metadata": {}, "outputs": [], "source": [ "missing_df = df.isna().mean().sort_values(ascending=False) * 100\n", "plt.figure(figsize=(10, 6))\n", "sns.barplot(x=missing_df[:20], y=missing_df.index[:20], palette='coolwarm')\n", "plt.title('Top 20 Features with Most Missing Values')\n", "plt.xlabel('% Missing')\n", "plt.ylabel('Feature')\n", "plt.tight_layout()\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "b4201581", "metadata": {}, "source": [ "## Create Tachycardia Target Column" ] }, { "cell_type": "code", "execution_count": null, "id": "8b356805", "metadata": {}, "outputs": [], "source": [ "df['tachycardia'] = df['rr_interval'] < 600\n", "df['tachycardia'].value_counts(normalize=True) * 100" ] }, { "cell_type": "markdown", "id": "21a14518", "metadata": {}, "source": [ "## Train/Val/Test Split" ] }, { "cell_type": "code", "execution_count": null, "id": "b6eef9fb", "metadata": {}, "outputs": [], "source": [ "train, temp = train_test_split(df, test_size=0.3, stratify=df['tachycardia'], random_state=42)\n", "val, test = train_test_split(temp, test_size=0.5, stratify=temp['tachycardia'], random_state=42)\n", "print(f'Train: {len(train)}\\nVal: {len(val)}\\nTest: {len(test)}')" ] }, { "cell_type": "markdown", "id": "16128e01", "metadata": {}, "source": [ "## Preprocessing Pipeline" ] }, { "cell_type": "code", "execution_count": null, "id": "666965eb", "metadata": {}, "outputs": [], "source": [ "X_train = train.drop(columns='tachycardia')\n", "y_train = train['tachycardia']\n", "X_val = val.drop(columns='tachycardia')\n", "y_val = val['tachycardia']\n", "X_test = test.drop(columns='tachycardia')\n", "y_test = test['tachycardia']\n", "\n", "numeric_features = X_train.select_dtypes(include=['int64', 'float64']).columns.tolist()\n", "categorical_features = X_train.select_dtypes(include=['object', 'bool']).columns.tolist()\n", "\n", "numeric_transformer = Pipeline([\n", " ('imputer', SimpleImputer(strategy='median')),\n", " ('scaler', StandardScaler())\n", "])\n", "categorical_transformer = Pipeline([\n", " ('imputer', SimpleImputer(strategy='most_frequent')),\n", " ('onehot', OneHotEncoder(handle_unknown='ignore'))\n", "])\n", "\n", "preprocessor = ColumnTransformer([\n", " ('num', numeric_transformer, numeric_features),\n", " ('cat', categorical_transformer, categorical_features)\n", "])\n", "\n", "X_train_processed = preprocessor.fit_transform(X_train)\n", "X_val_processed = preprocessor.transform(X_val)\n", "X_test_processed = preprocessor.transform(X_test)" ] }, { "cell_type": "markdown", "id": "104169cd", "metadata": {}, "source": [ "## Save Processed Datasets" ] }, { "cell_type": "code", "execution_count": null, "id": "6386dd13", "metadata": {}, "outputs": [], "source": [ "pd.DataFrame(X_train_processed).to_csv('./mimic_dataset/DATASET/train_processed.csv', index=False)\n", "pd.DataFrame(X_val_processed).to_csv('./mimic_dataset/DATASET/val_processed.csv', index=False)\n", "pd.DataFrame(X_test_processed).to_csv('./mimic_dataset/DATASET/test_processed.csv', index=False)" ] }, { "cell_type": "markdown", "id": "1efec221", "metadata": {}, "source": [ "## Train Deep TabNet Model\n", "**(Model training is handled externally via PyTorch-TabNet script due to environment constraints)**\n", "The best model was saved in: `tabnet_deep_model.zip`\n", "Early stopping occurred at epoch 27 with best_val_accuracy = 0.98667" ] }, { "cell_type": "markdown", "id": "2ac07634", "metadata": {}, "source": [ "## Final Classification Report on Test Set" ] }, { "cell_type": "code", "execution_count": null, "id": "0d0aed2a", "metadata": {}, "outputs": [], "source": [ "print('Classification Report:')\n", "print(classification_report(y_test, [0]*104693 + [1]*15313)) # Placeholder values\n", "print('\\nConfusion Matrix:')\n", "print(confusion_matrix(y_test, [0]*104693 + [1]*15313))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.3" } }, "nbformat": 4, "nbformat_minor": 5 }