{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":31192,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"id":"4c77e87e","cell_type":"markdown","source":"### Kaggle Assignment 2 ","metadata":{}},{"id":"6465a182","cell_type":"code","source":"# Imports + random seed for reproducibility\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\n\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, Dropout\nfrom tensorflow.keras.utils import to_categorical\n\nnp.random.seed(42)\ntf.random.set_seed(42)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-02T11:17:51.483858Z","iopub.execute_input":"2025-12-02T11:17:51.484673Z","iopub.status.idle":"2025-12-02T11:17:51.491867Z","shell.execute_reply.started":"2025-12-02T11:17:51.484645Z","shell.execute_reply":"2025-12-02T11:17:51.490751Z"}},"outputs":[],"execution_count":null},{"id":"939a9310-b660-4af6-8bee-7278bc8b1a0d","cell_type":"code","source":"# Load training and test data\ntrain_df = pd.read_csv(\"/kaggle/input/digit-recognizer/train.csv\")\ntest_df  = pd.read_csv(\"/kaggle/input/digit-recognizer/test.csv\")\n\nprint(\"Train shape:\", train_df.shape)\nprint(\"Test shape:\",  test_df.shape)\n\ntrain_df.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-02T11:17:59.159107Z","iopub.execute_input":"2025-12-02T11:17:59.160075Z","iopub.status.idle":"2025-12-02T11:18:02.890489Z","shell.execute_reply.started":"2025-12-02T11:17:59.160044Z","shell.execute_reply":"2025-12-02T11:18:02.889569Z"}},"outputs":[],"execution_count":null},{"id":"0d31bd5f","cell_type":"code","source":"# Data quality check: missing values + duplicates\ntrain_nulls = train_df.isna().sum().sum()\ntest_nulls  = test_df.isna().sum().sum()\n\ntrain_dups = train_df.duplicated().sum()\ntest_dups  = test_df.duplicated().sum()\n\nprint(f\"Missing → Train: {train_nulls:,} | Test: {test_nulls:,}\")\nprint(f\"Duplicates → Train: {train_dups:,} | Test: {test_dups:,}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-02T11:18:05.288922Z","iopub.execute_input":"2025-12-02T11:18:05.289256Z","iopub.status.idle":"2025-12-02T11:18:06.184943Z","shell.execute_reply.started":"2025-12-02T11:18:05.289231Z","shell.execute_reply":"2025-12-02T11:18:06.183783Z"}},"outputs":[],"execution_count":null},{"id":"83972f81","cell_type":"code","source":"# Prepare features + labels (normalize 0→1)\nX = train_df.drop(\"label\", axis=1).astype(\"float32\") / 255.0\ny = train_df[\"label\"].values\n\nX_test = test_df.astype(\"float32\") / 255.0\n\nprint(X.shape, y.shape, X_test.shape)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-02T11:18:10.169469Z","iopub.execute_input":"2025-12-02T11:18:10.169804Z","iopub.status.idle":"2025-12-02T11:18:10.503439Z","shell.execute_reply.started":"2025-12-02T11:18:10.169781Z","shell.execute_reply":"2025-12-02T11:18:10.502481Z"}},"outputs":[],"execution_count":null},{"id":"6392c230","cell_type":"code","source":"# Train/Val split + one-hot encoding\nX_train, X_val, y_train, y_val = train_test_split(\n    X, y, test_size=0.2, random_state=42, stratify=y\n)\n\ny_train_cat = to_categorical(y_train, 10)\ny_val_cat   = to_categorical(y_val, 10)\n\nprint(\"Train:\", X_train.shape, y_train_cat.shape)\nprint(\"Val:\",   X_val.shape,   y_val_cat.shape)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-02T11:18:14.337497Z","iopub.execute_input":"2025-12-02T11:18:14.337825Z","iopub.status.idle":"2025-12-02T11:18:14.572452Z","shell.execute_reply.started":"2025-12-02T11:18:14.337802Z","shell.execute_reply":"2025-12-02T11:18:14.571501Z"}},"outputs":[],"execution_count":null},{"id":"d0bbf633","cell_type":"code","source":"# Dense MLP model\nmodel = Sequential([\n    Dense(256, activation=\"relu\", input_shape=(784,)),\n    Dropout(0.3),\n    Dense(128, activation=\"relu\"),\n    Dropout(0.3),\n    Dense(10, activation=\"softmax\"),\n])\n\nmodel.compile(\n    loss=\"categorical_crossentropy\",\n    optimizer=\"adam\",\n    metrics=[\"accuracy\"],\n)\n\nmodel.summary()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-02T11:18:19.26148Z","iopub.execute_input":"2025-12-02T11:18:19.261803Z","iopub.status.idle":"2025-12-02T11:18:19.342638Z","shell.execute_reply.started":"2025-12-02T11:18:19.261781Z","shell.execute_reply":"2025-12-02T11:18:19.341676Z"}},"outputs":[],"execution_count":null},{"id":"6ca6f971","cell_type":"code","source":"# Train MLP\nepochs = 15\nbatch_size = 128\n\nhistory = model.fit(\n    X_train,\n    y_train_cat,\n    validation_data=(X_val, y_val_cat),\n    epochs=epochs,\n    batch_size=batch_size,\n    verbose=1,\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-02T11:18:24.225948Z","iopub.execute_input":"2025-12-02T11:18:24.226294Z","iopub.status.idle":"2025-12-02T11:18:56.412517Z","shell.execute_reply.started":"2025-12-02T11:18:24.226261Z","shell.execute_reply":"2025-12-02T11:18:56.411237Z"}},"outputs":[],"execution_count":null},{"id":"0de74895","cell_type":"code","source":"# Validation performance\nval_loss, val_acc = model.evaluate(X_val, y_val_cat, verbose=0)\nprint(f\"Validation loss: {val_loss:.4f}\")\nprint(f\"Validation accuracy: {val_acc:.4f}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-02T11:20:17.751313Z","iopub.execute_input":"2025-12-02T11:20:17.751692Z","iopub.status.idle":"2025-12-02T11:20:18.459221Z","shell.execute_reply.started":"2025-12-02T11:20:17.751666Z","shell.execute_reply":"2025-12-02T11:20:18.458159Z"}},"outputs":[],"execution_count":null},{"id":"c60ff0d2","cell_type":"code","source":"# Predict test  data\ntest_probs = model.predict(X_test)\ntest_preds = test_probs.argmax(axis=1)\n\nprint(test_preds.shape)\nprint(test_preds[:10])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-02T11:20:22.35179Z","iopub.execute_input":"2025-12-02T11:20:22.352111Z","iopub.status.idle":"2025-12-02T11:20:24.353447Z","shell.execute_reply.started":"2025-12-02T11:20:22.352089Z","shell.execute_reply":"2025-12-02T11:20:24.352315Z"}},"outputs":[],"execution_count":null},{"id":"c5b257a9","cell_type":"code","source":"# Create Kaggle submission file\nsubmission = pd.DataFrame({\n    \"ImageId\": np.arange(1, len(test_preds) + 1),\n    \"Label\": test_preds,\n})\n\nsubmission.to_csv(\"submission.csv\", index=False)\nsubmission.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-02T11:20:55.076833Z","iopub.execute_input":"2025-12-02T11:20:55.077125Z","iopub.status.idle":"2025-12-02T11:20:55.119725Z","shell.execute_reply.started":"2025-12-02T11:20:55.077106Z","shell.execute_reply":"2025-12-02T11:20:55.118589Z"}},"outputs":[],"execution_count":null}]}