{"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":"nvidiaTeslaT4","dataSources":[{"sourceType":"competition","sourceId":3004,"databundleVersionId":861823}],"dockerImageVersionId":31328,"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-05-20T06:41:37.503544Z","iopub.execute_input":"2026-05-20T06:41:37.503883Z","iopub.status.idle":"2026-05-20T06:41:38.689498Z","shell.execute_reply.started":"2026-05-20T06:41:37.503858Z","shell.execute_reply":"2026-05-20T06:41:38.688680Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"mnist = pd.read_csv('/kaggle/input/competitions/digit-recognizer/train.csv')\nX = mnist.drop('label', axis =1 )\ny  = mnist['label']\nprint(X.shape, y.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T06:42:24.030447Z","iopub.execute_input":"2026-05-20T06:42:24.031127Z","iopub.status.idle":"2026-05-20T06:42:26.738452Z","shell.execute_reply.started":"2026-05-20T06:42:24.031093Z","shell.execute_reply":"2026-05-20T06:42:26.737531Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib as mpl\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nsome_digit = X.loc[1].to_numpy()\nsome_digit_image = some_digit.reshape(28,28)\nplt.imshow(some_digit_image, cmap=mpl.cm.binary)\nplt.axis('off')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T05:47:12.716964Z","iopub.execute_input":"2026-05-20T05:47:12.717385Z","iopub.status.idle":"2026-05-20T05:47:12.849947Z","shell.execute_reply.started":"2026-05-20T05:47:12.717341Z","shell.execute_reply":"2026-05-20T05:47:12.848586Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Basic Model Testing\n","metadata":{}},{"cell_type":"code","source":"from sklearn.linear_model import SGDClassifier\nsgd_clf = SGDClassifier(random_state=42)    \nsgd_clf.fit(X, y)\nsgd_clf.predict([some_digit])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T05:47:12.851227Z","iopub.execute_input":"2026-05-20T05:47:12.851491Z","iopub.status.idle":"2026-05-20T05:49:03.576928Z","shell.execute_reply.started":"2026-05-20T05:47:12.851465Z","shell.execute_reply":"2026-05-20T05:49:03.575947Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import cross_val_score\ncross_val_score(sgd_clf, X, y, cv=3)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T05:49:03.578552Z","iopub.execute_input":"2026-05-20T05:49:03.579430Z","iopub.status.idle":"2026-05-20T05:52:04.202823Z","shell.execute_reply.started":"2026-05-20T05:49:03.579395Z","shell.execute_reply":"2026-05-20T05:52:04.202063Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from  sklearn.model_selection import cross_val_predict\ny_pred = cross_val_predict(sgd_clf, X, y, cv=3)\ny_pred.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T05:52:04.203750Z","iopub.execute_input":"2026-05-20T05:52:04.204055Z","iopub.status.idle":"2026-05-20T05:55:03.708108Z","shell.execute_reply.started":"2026-05-20T05:52:04.204020Z","shell.execute_reply":"2026-05-20T05:55:03.707336Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport seaborn as sns\nfrom sklearn.metrics import confusion_matrix\nfrom sklearn.metrics import precision_score, recall_score\n\n# Create confusion matrix\ncm = confusion_matrix(y, y_pred)\n\n# Plot\nplt.figure(figsize=(10,8))\nsns.heatmap(\n    cm,\n    annot=True,\n    fmt='d',\n    cmap='Blues',\n    xticklabels=range(10),\n    yticklabels=range(10)\n)\n\nplt.xlabel(\"Predicted Label\")\nplt.ylabel(\"True Label\")\nplt.title(\"Confusion Matrix\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T05:55:03.709671Z","iopub.execute_input":"2026-05-20T05:55:03.710323Z","iopub.status.idle":"2026-05-20T05:55:04.748193Z","shell.execute_reply.started":"2026-05-20T05:55:03.710277Z","shell.execute_reply":"2026-05-20T05:55:04.747176Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# First Basic test with 80 % Accuracy\nimport pandas as pd\n\n# Load test data\ntest_df = pd.read_csv(\"/kaggle/input/competitions/digit-recognizer/test.csv\")\n\n# Predict using your trained model\n# Replace 'model' with your actual trained model variable\npredictions = sgd_clf.predict(test_df)\n\n# If using neural networks / probabilities\n# predictions = predictions.argmax(axis=1)\n\n# Create submission dataframe\nsubmission = pd.DataFrame({\n    \"ImageId\": range(1, len(predictions) + 1),\n    \"Label\": predictions\n})\n\n# Save submission file\nsubmission.to_csv(\"submission_simple.csv\", index=False)\n\nprint(submission.head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T05:55:04.749628Z","iopub.execute_input":"2026-05-20T05:55:04.749917Z","iopub.status.idle":"2026-05-20T05:55:06.485588Z","shell.execute_reply.started":"2026-05-20T05:55:04.749891Z","shell.execute_reply":"2026-05-20T05:55:06.484859Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Testing Different Models ","metadata":{}},{"cell_type":"code","source":"import pandas as pd\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nfrom sklearn.pipeline import make_pipeline\nfrom sklearn.preprocessing import StandardScaler\n\n# Models\nfrom sklearn.linear_model import SGDClassifier, LogisticRegression\nfrom sklearn.neighbors import KNeighborsClassifier\nfrom sklearn.ensemble import RandomForestClassifier\nfrom sklearn.svm import SVC\n\n# Train-test split\nX_train, X_valid, y_train, y_valid = train_test_split(\n    X,\n    y,\n    test_size=0.2,\n    random_state=42,\n    stratify=y\n)\n\n# Dictionary of models\nmodels = {\n    \"SGD\": make_pipeline(\n        StandardScaler(),\n        SGDClassifier(random_state=42)\n    ),\n\n    \"Logistic Regression\": make_pipeline(\n        StandardScaler(),\n        LogisticRegression(max_iter=1000)\n    ),\n\n    \"KNN\": KNeighborsClassifier(),\n\n    \"Random Forest\": RandomForestClassifier(\n        n_estimators=100,\n        random_state=42\n    ),\n\n    \"SVM\": make_pipeline(\n        StandardScaler(),\n        SVC()\n    )\n}\n\n# Store results\nresults = []\n\n# Train and evaluate\nfor name, model in models.items():\n\n    print(f\"Training {name}...\")\n\n    model.fit(X_train, y_train)\n\n    y_pred = model.predict(X_valid)\n\n    accuracy = accuracy_score(y_valid, y_pred)\n\n    results.append({\n        \"Model\": name,\n        \"Accuracy\": accuracy\n    })\n\n# Create dataframe\nresults_df = pd.DataFrame(results)\n\n# Sort by accuracy\nresults_df = results_df.sort_values(\n    by=\"Accuracy\",\n    ascending=False\n)\n\nprint(results_df)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T05:56:08.404607Z","iopub.execute_input":"2026-05-20T05:56:08.405055Z","iopub.status.idle":"2026-05-20T06:05:14.348425Z","shell.execute_reply.started":"2026-05-20T05:56:08.405020Z","shell.execute_reply":"2026-05-20T06:05:14.347218Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\n\ndef create_submission(model, filename=\"submission.csv\"):\n\n    # Load test data\n    test_df = pd.read_csv(\n        \"/kaggle/input/competitions/digit-recognizer/test.csv\"\n    )\n\n    # Predict\n    predictions = model.predict(test_df)\n\n    # Create submission dataframe\n    submission = pd.DataFrame({\n        \"ImageId\": range(1, len(predictions) + 1),\n        \"Label\": predictions\n    })\n\n    # Save CSV\n    submission.to_csv(filename, index=False)\n\n    print(f\"Submission file saved as: {filename}\")\n\n    return submission.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T06:19:39.401529Z","iopub.execute_input":"2026-05-20T06:19:39.402713Z","iopub.status.idle":"2026-05-20T06:19:39.409281Z","shell.execute_reply.started":"2026-05-20T06:19:39.402672Z","shell.execute_reply":"2026-05-20T06:19:39.407770Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"create_submission(models[\"KNN\"], \"knn_submission.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T06:20:35.261499Z","iopub.execute_input":"2026-05-20T06:20:35.262581Z","iopub.status.idle":"2026-05-20T06:21:10.727682Z","shell.execute_reply.started":"2026-05-20T06:20:35.262539Z","shell.execute_reply":"2026-05-20T06:21:10.726823Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Testing with CNN ","metadata":{}},{"cell_type":"code","source":"# Features and labels\nX = mnist.drop(\"label\", axis=1).values\ny = mnist[\"label\"].values\n\n# Normalize pixel values\nX = X / 255.0\n\n# Reshape for CNN\nX = X.reshape(-1, 28, 28, 1)\nX.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T06:24:30.520052Z","iopub.execute_input":"2026-05-20T06:24:30.521207Z","iopub.status.idle":"2026-05-20T06:24:30.743188Z","shell.execute_reply.started":"2026-05-20T06:24:30.521119Z","shell.execute_reply":"2026-05-20T06:24:30.742208Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\nX_train, X_valid, y_train, y_valid = train_test_split(\n    X,\n    y,\n    test_size=0.2,\n    random_state=42,\n    stratify=y\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T06:24:38.514843Z","iopub.execute_input":"2026-05-20T06:24:38.515866Z","iopub.status.idle":"2026-05-20T06:24:38.973662Z","shell.execute_reply.started":"2026-05-20T06:24:38.515824Z","shell.execute_reply":"2026-05-20T06:24:38.972604Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\n\nmodel = keras.Sequential([\n\n    layers.Conv2D(\n        32,\n        (3,3),\n        activation='relu',\n        input_shape=(28,28,1)\n    ),\n\n    layers.MaxPooling2D((2,2)),\n\n    layers.Conv2D(\n        64,\n        (3,3),\n        activation='relu'\n    ),\n\n    layers.MaxPooling2D((2,2)),\n\n    layers.Flatten(),\n\n    layers.Dense(128, activation='relu'),\n\n    layers.Dropout(0.3),\n\n    layers.Dense(10, activation='softmax')\n])\n\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T06:24:47.659774Z","iopub.execute_input":"2026-05-20T06:24:47.660638Z","iopub.status.idle":"2026-05-20T06:25:22.012555Z","shell.execute_reply.started":"2026-05-20T06:24:47.660592Z","shell.execute_reply":"2026-05-20T06:25:22.011623Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.compile(\n    optimizer='adam',\n    loss='sparse_categorical_crossentropy',\n    metrics=['accuracy']\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T06:26:38.743865Z","iopub.execute_input":"2026-05-20T06:26:38.744205Z","iopub.status.idle":"2026-05-20T06:26:38.754643Z","shell.execute_reply.started":"2026-05-20T06:26:38.744166Z","shell.execute_reply":"2026-05-20T06:26:38.753713Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history = model.fit(\n    X_train,\n    y_train,\n    epochs=5,\n    batch_size=32,\n    validation_data=(X_valid, y_valid)\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T06:26:45.556954Z","iopub.execute_input":"2026-05-20T06:26:45.557916Z","iopub.status.idle":"2026-05-20T06:28:19.210404Z","shell.execute_reply.started":"2026-05-20T06:26:45.557870Z","shell.execute_reply":"2026-05-20T06:28:19.209431Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"loss, accuracy = model.evaluate(X_valid, y_valid)\n\nprint(\"Validation Accuracy:\", accuracy)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T06:28:56.844016Z","iopub.execute_input":"2026-05-20T06:28:56.844835Z","iopub.status.idle":"2026-05-20T06:28:58.544846Z","shell.execute_reply.started":"2026-05-20T06:28:56.844796Z","shell.execute_reply":"2026-05-20T06:28:58.543526Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def create_cnn_submission(model, filename=\"cnn_submission.csv\"):\n\n    test_df = pd.read_csv(\n        \"/kaggle/input/competitions/digit-recognizer/test.csv\"\n    )\n\n    # Normalize\n    X_test = test_df.values / 255.0\n\n    # Reshape\n    X_test = X_test.reshape(-1, 28, 28, 1)\n\n    # Predict probabilities\n    predictions = model.predict(X_test)\n\n    # Convert probabilities to labels\n    predictions = np.argmax(predictions, axis=1)\n\n    submission = pd.DataFrame({\n        \"ImageId\": range(1, len(predictions)+1),\n        \"Label\": predictions\n    })\n\n    submission.to_csv(filename, index=False)\n\n    print(f\"Saved: {filename}\")\n\n    return submission.head()\ncreate_cnn_submission(model, \"cnn_submission.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T06:29:10.251523Z","iopub.execute_input":"2026-05-20T06:29:10.251844Z","iopub.status.idle":"2026-05-20T06:29:16.911222Z","shell.execute_reply.started":"2026-05-20T06:29:10.251814Z","shell.execute_reply":"2026-05-20T06:29:16.910428Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Complex CNN ","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# TensorFlow / Keras\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\n\n# Sklearn\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import confusion_matrix, classification_report\n\n\nX = mnist.drop(\"label\", axis=1).values\ny = mnist[\"label\"].values\n\nprint(\"Original Shape:\", X.shape)\n\n# ================================\n# NORMALIZE\n# ================================\n\nX = X / 255.0\n\n# ================================\n# RESHAPE FOR CNN\n# ================================\n\nX = X.reshape(-1, 28, 28, 1)\n\nprint(\"CNN Shape:\", X.shape)\n\n# ================================\n# TRAIN VALID SPLIT\n# ================================\n\nX_train, X_valid, y_train, y_valid = train_test_split(\n    X,\n    y,\n    test_size=0.2,\n    random_state=42,\n    stratify=y\n)\n\nprint(X_train.shape, X_valid.shape)\n\n# ================================\n# DATA AUGMENTATION\n# ================================\n\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\ndatagen = ImageDataGenerator(\n    rotation_range=10,\n    zoom_range=0.10,\n    width_shift_range=0.1,\n    height_shift_range=0.1\n)\n\ndatagen.fit(X_train)\n\n# ================================\n# BUILD CNN MODEL\n# ================================\n\nmodel = keras.Sequential([\n\n    # Block 1\n    layers.Conv2D(\n        32,\n        (3,3),\n        activation='relu',\n        padding='same',\n        input_shape=(28,28,1)\n    ),\n\n    layers.BatchNormalization(),\n\n    layers.Conv2D(\n        32,\n        (3,3),\n        activation='relu',\n        padding='same'\n    ),\n\n    layers.BatchNormalization(),\n\n    layers.MaxPooling2D((2,2)),\n\n    layers.Dropout(0.25),\n\n    # Block 2\n    layers.Conv2D(\n        64,\n        (3,3),\n        activation='relu',\n        padding='same'\n    ),\n\n    layers.BatchNormalization(),\n\n    layers.Conv2D(\n        64,\n        (3,3),\n        activation='relu',\n        padding='same'\n    ),\n\n    layers.BatchNormalization(),\n\n    layers.MaxPooling2D((2,2)),\n\n    layers.Dropout(0.25),\n\n    # Dense Layers\n    layers.Flatten(),\n\n    layers.Dense(256, activation='relu'),\n\n    layers.Dropout(0.5),\n\n    layers.Dense(10, activation='softmax')\n])\n\n# ================================\n# MODEL SUMMARY\n# ================================\n\nmodel.summary()\n\n# ================================\n# COMPILE MODEL\n# ================================\n\nmodel.compile(\n    optimizer='adam',\n    loss='sparse_categorical_crossentropy',\n    metrics=['accuracy']\n)\n\n# ================================\n# CALLBACKS\n# ================================\n\nfrom tensorflow.keras.callbacks import (\n    EarlyStopping,\n    ReduceLROnPlateau\n)\n\nearly_stop = EarlyStopping(\n    monitor='val_loss',\n    patience=5,\n    restore_best_weights=True\n)\n\nlr_scheduler = ReduceLROnPlateau(\n    monitor='val_loss',\n    factor=0.5,\n    patience=2,\n    verbose=1\n)\n\n# ================================\n# TRAIN MODEL\n# ================================\n\nhistory = model.fit(\n    datagen.flow(X_train, y_train, batch_size=32),\n    epochs=30,\n    validation_data=(X_valid, y_valid),\n    callbacks=[early_stop, lr_scheduler]\n)\n\n# ================================\n# EVALUATE MODEL\n# ================================\n\nloss, accuracy = model.evaluate(X_valid, y_valid)\n\nprint(\"\\nValidation Accuracy:\", accuracy)\n\n# ================================\n# PREDICTIONS\n# ================================\n\ny_pred_probs = model.predict(X_valid)\n\ny_pred = np.argmax(y_pred_probs, axis=1)\n\n# ================================\n# CLASSIFICATION REPORT\n# ================================\n\nprint(\"\\nClassification Report:\\n\")\n\nprint(classification_report(y_valid, y_pred))\n\n# ================================\n# CONFUSION MATRIX\n# ================================\n\nimport seaborn as sns\n\ncm = confusion_matrix(y_valid, y_pred)\n\nplt.figure(figsize=(10,8))\n\nsns.heatmap(\n    cm,\n    annot=True,\n    fmt='d',\n    cmap='Blues',\n    xticklabels=range(10),\n    yticklabels=range(10)\n)\n\nplt.xlabel(\"Predicted Label\")\nplt.ylabel(\"True Label\")\nplt.title(\"CNN Confusion Matrix\")\n\nplt.show()\n\n# ================================\n# PLOT ACCURACY\n# ================================\n\nplt.figure(figsize=(10,5))\n\nplt.plot(history.history['accuracy'], label='Train Accuracy')\nplt.plot(history.history['val_accuracy'], label='Validation Accuracy')\n\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Accuracy\")\nplt.title(\"Training vs Validation Accuracy\")\n\nplt.legend()\n\nplt.show()\n\n# ================================\n# CREATE SUBMISSION FILE\n# ================================\n\ndef create_cnn_submission(\n    model,\n    filename=\"cnn_submission.csv\"\n):\n\n    # Load test data\n    test_df = pd.read_csv(\n        \"/kaggle/input/competitions/digit-recognizer/test.csv\"\n    )\n\n    # Normalize\n    X_test = test_df.values / 255.0\n\n    # Reshape\n    X_test = X_test.reshape(-1, 28, 28, 1)\n\n    # Predict probabilities\n    predictions = model.predict(X_test)\n\n    # Convert to labels\n    predictions = np.argmax(predictions, axis=1)\n\n    # Create submission dataframe\n    submission = pd.DataFrame({\n        \"ImageId\": range(1, len(predictions) + 1),\n        \"Label\": predictions\n    })\n\n    # Save CSV\n    submission.to_csv(filename, index=False)\n\n    print(f\"\\nSubmission file saved as: {filename}\")\n\n    return submission.head()\n\n# ================================\n# GENERATE SUBMISSION\n# ================================\n\ncreate_cnn_submission(\n    model,\n    \"cnn_high_accuracy_submission.csv\"\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-20T06:43:08.588346Z","iopub.execute_input":"2026-05-20T06:43:08.588645Z","iopub.status.idle":"2026-05-20T06:49:21.786190Z","shell.execute_reply.started":"2026-05-20T06:43:08.588619Z","shell.execute_reply":"2026-05-20T06:49:21.785596Z"}},"outputs":[],"execution_count":null}]}