{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceType":"competition","sourceId":131653,"databundleVersionId":15802687}],"dockerImageVersionId":31287,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-02-24T05:16:22.565631Z","iopub.execute_input":"2026-02-24T05:16:22.565904Z","iopub.status.idle":"2026-02-24T05:16:23.500290Z","shell.execute_reply.started":"2026-02-24T05:16:22.565850Z","shell.execute_reply":"2026-02-24T05:16:23.499591Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport lightgbm as lgb\nfrom sklearn.model_selection import StratifiedKFold\nfrom sklearn.metrics import roc_auc_score\nimport warnings\n\nwarnings.filterwarnings('ignore')\n\n# Set Kaggle base path\nbase_path = '/kaggle/input/ai-emergency-medicine-turkiye/'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T05:17:33.413537Z","iopub.execute_input":"2026-02-24T05:17:33.413895Z","iopub.status.idle":"2026-02-24T05:17:38.807691Z","shell.execute_reply.started":"2026-02-24T05:17:33.413867Z","shell.execute_reply":"2026-02-24T05:17:38.807141Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Loading core datasets...\")\ntrain = pd.read_csv(base_path + 'train.csv')\ntest = pd.read_csv(base_path + 'test.csv')\nhosp_ref = pd.read_csv(base_path + 'hospital_reference.csv')\nicd_ref = pd.read_csv(base_path + 'icd10_reference.csv')\n\nprint(f\"Train shape: {train.shape}\")\nprint(f\"Test shape: {test.shape}\")\n\ntargets = ['adverse_outcome', 'readmission_30d']\nid_col = 'encounter_id'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T05:17:49.824877Z","iopub.execute_input":"2026-02-24T05:17:49.825892Z","iopub.status.idle":"2026-02-24T05:18:02.790882Z","shell.execute_reply.started":"2026-02-24T05:17:49.825862Z","shell.execute_reply":"2026-02-24T05:18:02.790149Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Merging hospital and ICD-10 reference data...\")\n\n# 1. Merge hospital data on 'city'\ntrain = train.merge(hosp_ref, on='city', how='left')\ntest = test.merge(hosp_ref, on='city', how='left')\n\n# 2. Merge ICD-10 data \n# (Assuming the diagnosis column in train/test is named 'primary_icd10_code' based on common conventions)\nif 'primary_icd10_code' in train.columns:\n    train = train.merge(icd_ref, left_on='primary_icd10_code', right_on='icd10_code', how='left')\n    test = test.merge(icd_ref, left_on='primary_icd10_code', right_on='icd10_code', how='left')\n    \nprint(f\"Train shape after merges: {train.shape}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T05:18:24.558098Z","iopub.execute_input":"2026-02-24T05:18:24.558609Z","iopub.status.idle":"2026-02-24T05:18:26.978999Z","shell.execute_reply.started":"2026-02-24T05:18:24.558583Z","shell.execute_reply":"2026-02-24T05:18:26.978268Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Engineering missingness indicators...\")\nmnar_columns = [\n    'troponin_i_ngml', 'bnp_pgl', 'd_dimer_mgfl', \n    'lactate_mmoll', 'lipase_ul', 'procalcitonin_ngl', 'albumin_gdl'\n]\n\nfor df in [train, test]:\n    for col in mnar_columns:\n        if col in df.columns:\n            # Create a binary indicator: 1 if missing, 0 otherwise\n            df[f'{col}_is_missing'] = df[col].isnull().astype(int)\n\nprint(\"Missingness indicators added.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T05:18:34.058338Z","iopub.execute_input":"2026-02-24T05:18:34.058868Z","iopub.status.idle":"2026-02-24T05:18:34.088599Z","shell.execute_reply.started":"2026-02-24T05:18:34.058841Z","shell.execute_reply":"2026-02-24T05:18:34.088009Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Drop ID, targets, and any leaky features (like 'disposition')\ndrop_cols = [id_col, 'disposition'] + targets \nfeatures = [col for col in train.columns if col not in drop_cols]\n\n# Identify and convert object/string columns to category type for LightGBM\ncat_features = train[features].select_dtypes(include=['object', 'category']).columns.tolist()\n\nprint(f\"Converting {len(cat_features)} categorical columns...\")\nfor c in cat_features:\n    train[c] = train[c].astype('category')\n    test[c] = test[c].astype('category')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T05:18:36.878172Z","iopub.execute_input":"2026-02-24T05:18:36.878884Z","iopub.status.idle":"2026-02-24T05:18:38.967373Z","shell.execute_reply.started":"2026-02-24T05:18:36.878860Z","shell.execute_reply":"2026-02-24T05:18:38.966804Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"n_splits = 5\nskf = StratifiedKFold(n_splits=n_splits, shuffle=True, random_state=42)\n\n# Arrays to store the final test predictions\ntest_preds = {target: np.zeros(len(test)) for target in targets}\nmacro_auc_scores = []\n\n# Baseline LightGBM hyperparameters\nlgb_params = {\n    'objective': 'binary',\n    'metric': 'auc',\n    'learning_rate': 0.05,\n    'num_leaves': 31,\n    'random_state': 42,\n    'n_jobs': -1,\n    'verbose': -1\n}\n\nfor target in targets:\n    print(f\"\\n========== Training for {target} ==========\")\n    y = train[target]\n    target_auc_scores = []\n    \n    for fold, (train_idx, valid_idx) in enumerate(skf.split(train[features], y)):\n        X_train, y_train = train[features].iloc[train_idx], y.iloc[train_idx]\n        X_valid, y_valid = train[features].iloc[valid_idx], y.iloc[valid_idx]\n        \n        # Create LightGBM datasets\n        dtrain = lgb.Dataset(X_train, label=y_train, categorical_feature=cat_features)\n        dvalid = lgb.Dataset(X_valid, label=y_valid, reference=dtrain, categorical_feature=cat_features)\n        \n        # Train the model with early stopping\n        model = lgb.train(\n            lgb_params,\n            dtrain,\n            num_boost_round=1500,\n            valid_sets=[dtrain, dvalid],\n            callbacks=[lgb.early_stopping(stopping_rounds=50, verbose=False)]\n        )\n        \n        # Validate and predict\n        valid_preds = model.predict(X_valid, num_iteration=model.best_iteration)\n        fold_auc = roc_auc_score(y_valid, valid_preds)\n        target_auc_scores.append(fold_auc)\n        print(f\"Fold {fold + 1} AUC: {fold_auc:.5f} (Best Iter: {model.best_iteration})\")\n        \n        # Accumulate test predictions (averaged over folds)\n        test_preds[target] += model.predict(test[features], num_iteration=model.best_iteration) / n_splits\n        \n    mean_auc = np.mean(target_auc_scores)\n    print(f\"--> Mean AUC for {target}: {mean_auc:.5f}\")\n    macro_auc_scores.append(mean_auc)\n\nprint(f\"\\n===========================================\")\nprint(f\"Overall Cross-Validation Macro AUC: {np.mean(macro_auc_scores):.5f}\")\nprint(f\"===========================================\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T05:18:43.037997Z","iopub.execute_input":"2026-02-24T05:18:43.038597Z","iopub.status.idle":"2026-02-24T05:24:13.557870Z","shell.execute_reply.started":"2026-02-24T05:18:43.038571Z","shell.execute_reply":"2026-02-24T05:24:13.556447Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Format the submission DataFrame\nsubmission = pd.DataFrame({\n    'encounter_id': test[id_col],\n    'adverse_outcome': test_preds['adverse_outcome'],\n    'readmission_30d': test_preds['readmission_30d']\n})\n\n# Ensure values are strictly between 0 and 1\nsubmission['adverse_outcome'] = submission['adverse_outcome'].clip(0, 1)\nsubmission['readmission_30d'] = submission['readmission_30d'].clip(0, 1)\n\n# Save to CSV\nsubmission.to_csv('submission.csv', index=False)\nprint(\"Saved Kaggle submission to 'submission.csv'\")\nsubmission.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T05:24:20.804211Z","iopub.execute_input":"2026-02-24T05:24:20.804531Z","iopub.status.idle":"2026-02-24T05:24:21.508868Z","shell.execute_reply.started":"2026-02-24T05:24:20.804505Z","shell.execute_reply":"2026-02-24T05:24:21.508151Z"}},"outputs":[],"execution_count":null}]}