{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 110
        },
        "id": "XsAtYaGC5hbB",
        "outputId": "31da3b57-efd3-4d8b-a678-f552fc316552"
      },
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ],
            "text/html": [
              "\n",
              "     <input type=\"file\" id=\"files-01116811-b2d2-4c6e-bad9-96e7e1680b84\" name=\"files[]\" multiple disabled\n",
              "        style=\"border:none\" />\n",
              "     <output id=\"result-01116811-b2d2-4c6e-bad9-96e7e1680b84\">\n",
              "      Upload widget is only available when the cell has been executed in the\n",
              "      current browser session. Please rerun this cell to enable.\n",
              "      </output>\n",
              "      <script>// Copyright 2017 Google LLC\n",
              "//\n",
              "// Licensed under the Apache License, Version 2.0 (the \"License\");\n",
              "// you may not use this file except in compliance with the License.\n",
              "// You may obtain a copy of the License at\n",
              "//\n",
              "//      http://www.apache.org/licenses/LICENSE-2.0\n",
              "//\n",
              "// Unless required by applicable law or agreed to in writing, software\n",
              "// distributed under the License is distributed on an \"AS IS\" BASIS,\n",
              "// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
              "// See the License for the specific language governing permissions and\n",
              "// limitations under the License.\n",
              "\n",
              "/**\n",
              " * @fileoverview Helpers for google.colab Python module.\n",
              " */\n",
              "(function(scope) {\n",
              "function span(text, styleAttributes = {}) {\n",
              "  const element = document.createElement('span');\n",
              "  element.textContent = text;\n",
              "  for (const key of Object.keys(styleAttributes)) {\n",
              "    element.style[key] = styleAttributes[key];\n",
              "  }\n",
              "  return element;\n",
              "}\n",
              "\n",
              "// Max number of bytes which will be uploaded at a time.\n",
              "const MAX_PAYLOAD_SIZE = 100 * 1024;\n",
              "\n",
              "function _uploadFiles(inputId, outputId) {\n",
              "  const steps = uploadFilesStep(inputId, outputId);\n",
              "  const outputElement = document.getElementById(outputId);\n",
              "  // Cache steps on the outputElement to make it available for the next call\n",
              "  // to uploadFilesContinue from Python.\n",
              "  outputElement.steps = steps;\n",
              "\n",
              "  return _uploadFilesContinue(outputId);\n",
              "}\n",
              "\n",
              "// This is roughly an async generator (not supported in the browser yet),\n",
              "// where there are multiple asynchronous steps and the Python side is going\n",
              "// to poll for completion of each step.\n",
              "// This uses a Promise to block the python side on completion of each step,\n",
              "// then passes the result of the previous step as the input to the next step.\n",
              "function _uploadFilesContinue(outputId) {\n",
              "  const outputElement = document.getElementById(outputId);\n",
              "  const steps = outputElement.steps;\n",
              "\n",
              "  const next = steps.next(outputElement.lastPromiseValue);\n",
              "  return Promise.resolve(next.value.promise).then((value) => {\n",
              "    // Cache the last promise value to make it available to the next\n",
              "    // step of the generator.\n",
              "    outputElement.lastPromiseValue = value;\n",
              "    return next.value.response;\n",
              "  });\n",
              "}\n",
              "\n",
              "/**\n",
              " * Generator function which is called between each async step of the upload\n",
              " * process.\n",
              " * @param {string} inputId Element ID of the input file picker element.\n",
              " * @param {string} outputId Element ID of the output display.\n",
              " * @return {!Iterable<!Object>} Iterable of next steps.\n",
              " */\n",
              "function* uploadFilesStep(inputId, outputId) {\n",
              "  const inputElement = document.getElementById(inputId);\n",
              "  inputElement.disabled = false;\n",
              "\n",
              "  const outputElement = document.getElementById(outputId);\n",
              "  outputElement.innerHTML = '';\n",
              "\n",
              "  const pickedPromise = new Promise((resolve) => {\n",
              "    inputElement.addEventListener('change', (e) => {\n",
              "      resolve(e.target.files);\n",
              "    });\n",
              "  });\n",
              "\n",
              "  const cancel = document.createElement('button');\n",
              "  inputElement.parentElement.appendChild(cancel);\n",
              "  cancel.textContent = 'Cancel upload';\n",
              "  const cancelPromise = new Promise((resolve) => {\n",
              "    cancel.onclick = () => {\n",
              "      resolve(null);\n",
              "    };\n",
              "  });\n",
              "\n",
              "  // Wait for the user to pick the files.\n",
              "  const files = yield {\n",
              "    promise: Promise.race([pickedPromise, cancelPromise]),\n",
              "    response: {\n",
              "      action: 'starting',\n",
              "    }\n",
              "  };\n",
              "\n",
              "  cancel.remove();\n",
              "\n",
              "  // Disable the input element since further picks are not allowed.\n",
              "  inputElement.disabled = true;\n",
              "\n",
              "  if (!files) {\n",
              "    return {\n",
              "      response: {\n",
              "        action: 'complete',\n",
              "      }\n",
              "    };\n",
              "  }\n",
              "\n",
              "  for (const file of files) {\n",
              "    const li = document.createElement('li');\n",
              "    li.append(span(file.name, {fontWeight: 'bold'}));\n",
              "    li.append(span(\n",
              "        `(${file.type || 'n/a'}) - ${file.size} bytes, ` +\n",
              "        `last modified: ${\n",
              "            file.lastModifiedDate ? file.lastModifiedDate.toLocaleDateString() :\n",
              "                                    'n/a'} - `));\n",
              "    const percent = span('0% done');\n",
              "    li.appendChild(percent);\n",
              "\n",
              "    outputElement.appendChild(li);\n",
              "\n",
              "    const fileDataPromise = new Promise((resolve) => {\n",
              "      const reader = new FileReader();\n",
              "      reader.onload = (e) => {\n",
              "        resolve(e.target.result);\n",
              "      };\n",
              "      reader.readAsArrayBuffer(file);\n",
              "    });\n",
              "    // Wait for the data to be ready.\n",
              "    let fileData = yield {\n",
              "      promise: fileDataPromise,\n",
              "      response: {\n",
              "        action: 'continue',\n",
              "      }\n",
              "    };\n",
              "\n",
              "    // Use a chunked sending to avoid message size limits. See b/62115660.\n",
              "    let position = 0;\n",
              "    do {\n",
              "      const length = Math.min(fileData.byteLength - position, MAX_PAYLOAD_SIZE);\n",
              "      const chunk = new Uint8Array(fileData, position, length);\n",
              "      position += length;\n",
              "\n",
              "      const base64 = btoa(String.fromCharCode.apply(null, chunk));\n",
              "      yield {\n",
              "        response: {\n",
              "          action: 'append',\n",
              "          file: file.name,\n",
              "          data: base64,\n",
              "        },\n",
              "      };\n",
              "\n",
              "      let percentDone = fileData.byteLength === 0 ?\n",
              "          100 :\n",
              "          Math.round((position / fileData.byteLength) * 100);\n",
              "      percent.textContent = `${percentDone}% done`;\n",
              "\n",
              "    } while (position < fileData.byteLength);\n",
              "  }\n",
              "\n",
              "  // All done.\n",
              "  yield {\n",
              "    response: {\n",
              "      action: 'complete',\n",
              "    }\n",
              "  };\n",
              "}\n",
              "\n",
              "scope.google = scope.google || {};\n",
              "scope.google.colab = scope.google.colab || {};\n",
              "scope.google.colab._files = {\n",
              "  _uploadFiles,\n",
              "  _uploadFilesContinue,\n",
              "};\n",
              "})(self);\n",
              "</script> "
            ]
          },
          "metadata": {}
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Saving customer_purchase_data.csv to customer_purchase_data (4).csv\n",
            "['.config', 'customer_purchase_data (3).csv', 'archive (1).zip', 'archive (1) (2).zip', 'customer_purchase_data (4).csv', 'customer_purchase_data.csv', 'customer_purchase_data (1).csv', 'archive (1) (1).zip', 'customer_purchase_data (2).csv', 'sample_data']\n"
          ]
        }
      ],
      "source": [
        "from google.colab import files\n",
        "\n",
        "uploaded = files.upload()\n",
        "\n",
        "import os\n",
        "print(os.listdir())"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Loading and Preparing the Dataset\n",
        "import pandas as pd\n",
        "\n",
        "df = pd.read_csv(\"customer_purchase_data (3).csv\")\n",
        "\n",
        "print(df.head())\n",
        "\n",
        "# Data Summary\n",
        "print(df.info())\n",
        "\n",
        "print(df.describe(include='all'))\n",
        "\n",
        "# Data Cleaning\n",
        "print(df.isnull().sum())\n",
        "\n",
        "df = df.dropna()\n",
        "\n",
        "print(df.isnull().sum())"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "LJt4AKM76ScW",
        "outputId": "fc5900b7-df0e-4af6-8600-4b6cd4fa8992"
      },
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "   Age  Gender   AnnualIncome  NumberOfPurchases  ProductCategory  \\\n",
            "0   40       1   66120.267939                  8                0   \n",
            "1   20       1   23579.773583                  4                2   \n",
            "2   27       1  127821.306432                 11                2   \n",
            "3   24       1  137798.623120                 19                3   \n",
            "4   31       1   99300.964220                 19                1   \n",
            "\n",
            "   TimeSpentOnWebsite  LoyaltyProgram  DiscountsAvailed  PurchaseStatus  \n",
            "0           30.568601               0                 5               1  \n",
            "1           38.240097               0                 5               0  \n",
            "2           31.633212               1                 0               1  \n",
            "3           46.167059               0                 4               1  \n",
            "4           19.823592               0                 0               1  \n",
            "<class 'pandas.core.frame.DataFrame'>\n",
            "RangeIndex: 1500 entries, 0 to 1499\n",
            "Data columns (total 9 columns):\n",
            " #   Column              Non-Null Count  Dtype  \n",
            "---  ------              --------------  -----  \n",
            " 0   Age                 1500 non-null   int64  \n",
            " 1   Gender              1500 non-null   int64  \n",
            " 2   AnnualIncome        1500 non-null   float64\n",
            " 3   NumberOfPurchases   1500 non-null   int64  \n",
            " 4   ProductCategory     1500 non-null   int64  \n",
            " 5   TimeSpentOnWebsite  1500 non-null   float64\n",
            " 6   LoyaltyProgram      1500 non-null   int64  \n",
            " 7   DiscountsAvailed    1500 non-null   int64  \n",
            " 8   PurchaseStatus      1500 non-null   int64  \n",
            "dtypes: float64(2), int64(7)\n",
            "memory usage: 105.6 KB\n",
            "None\n",
            "               Age       Gender   AnnualIncome  NumberOfPurchases  \\\n",
            "count  1500.000000  1500.000000    1500.000000        1500.000000   \n",
            "mean     44.298667     0.504667   84249.164338          10.420000   \n",
            "std      15.537259     0.500145   37629.493078           5.887391   \n",
            "min      18.000000     0.000000   20001.512518           0.000000   \n",
            "25%      31.000000     0.000000   53028.979155           5.000000   \n",
            "50%      45.000000     1.000000   83699.581476          11.000000   \n",
            "75%      57.000000     1.000000  117167.772858          15.000000   \n",
            "max      70.000000     1.000000  149785.176481          20.000000   \n",
            "\n",
            "       ProductCategory  TimeSpentOnWebsite  LoyaltyProgram  DiscountsAvailed  \\\n",
            "count      1500.000000         1500.000000     1500.000000       1500.000000   \n",
            "mean          2.012667           30.469040        0.326667          2.555333   \n",
            "std           1.428005           16.984392        0.469151          1.705152   \n",
            "min           0.000000            1.037023        0.000000          0.000000   \n",
            "25%           1.000000           16.156700        0.000000          1.000000   \n",
            "50%           2.000000           30.939516        0.000000          3.000000   \n",
            "75%           3.000000           44.369863        1.000000          4.000000   \n",
            "max           4.000000           59.991105        1.000000          5.000000   \n",
            "\n",
            "       PurchaseStatus  \n",
            "count      1500.00000  \n",
            "mean          0.43200  \n",
            "std           0.49552  \n",
            "min           0.00000  \n",
            "25%           0.00000  \n",
            "50%           0.00000  \n",
            "75%           1.00000  \n",
            "max           1.00000  \n",
            "Age                   0\n",
            "Gender                0\n",
            "AnnualIncome          0\n",
            "NumberOfPurchases     0\n",
            "ProductCategory       0\n",
            "TimeSpentOnWebsite    0\n",
            "LoyaltyProgram        0\n",
            "DiscountsAvailed      0\n",
            "PurchaseStatus        0\n",
            "dtype: int64\n",
            "Age                   0\n",
            "Gender                0\n",
            "AnnualIncome          0\n",
            "NumberOfPurchases     0\n",
            "ProductCategory       0\n",
            "TimeSpentOnWebsite    0\n",
            "LoyaltyProgram        0\n",
            "DiscountsAvailed      0\n",
            "PurchaseStatus        0\n",
            "dtype: int64\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Feature Encoding\n",
        "import pandas as pd\n",
        "from sklearn.preprocessing import LabelEncoder\n",
        "\n",
        "# Convert continuous features into categorical bins\n",
        "df[\"Age\"] = pd.cut(\n",
        "    df[\"Age\"],\n",
        "    bins=[18, 30, 45, 60, 80],\n",
        "    labels=[\"18-30\", \"31-45\", \"46-60\", \"60+\"]\n",
        ")\n",
        "\n",
        "df[\"AnnualIncome\"] = pd.qcut(\n",
        "    df[\"AnnualIncome\"],\n",
        "    q=4,\n",
        "    labels=[\"Low\", \"Medium\", \"High\", \"Very High\"]\n",
        ")\n",
        "\n",
        "# Encode categorical variables\n",
        "le = LabelEncoder()\n",
        "\n",
        "categorical_features = [\n",
        "    \"Gender\",\n",
        "    \"Age\",\n",
        "    \"AnnualIncome\",\n",
        "    \"ProductCategory\"\n",
        "]\n",
        "\n",
        "for feature in categorical_features:\n",
        "    df[feature] = le.fit_transform(df[feature])\n",
        "\n",
        "# Encode target variable\n",
        "df[\"Purchase\"] = le.fit_transform(df[\"PurchaseStatus\"])\n",
        "\n",
        "print(df[categorical_features + [\"Purchase\"]].head())"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Y3oM19s55pSY",
        "outputId": "53d9d5b6-59be-4308-a522-bb90394c9fe9"
      },
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "   Gender  Age  AnnualIncome  ProductCategory  Purchase\n",
            "0       1    1             2                0         1\n",
            "1       1    0             1                2         0\n",
            "2       1    0             3                2         1\n",
            "3       1    0             3                3         1\n",
            "4       1    1             0                1         1\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Applying the Chi-Square Test\n",
        "from sklearn.feature_selection import SelectKBest, chi2\n",
        "\n",
        "X = df[categorical_features]\n",
        "y = df[\"Purchase\"]\n",
        "\n",
        "selector = SelectKBest(score_func=chi2, k=2)\n",
        "\n",
        "X_new = selector.fit_transform(X, y)\n",
        "\n",
        "feature_scores = selector.scores_\n",
        "\n",
        "selected_features = X.columns[selector.get_support()]\n",
        "\n",
        "print(\"Feature Scores:\", feature_scores)\n",
        "print(\"Selected Features:\", selected_features)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "r2BN3mrX5sGu",
        "outputId": "a556631f-7829-44f0-ab35-e431f1a9c75c"
      },
      "execution_count": 4,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Feature Scores: [5.12827934e-03 3.96569167e+01 1.32610594e-02 8.19601401e-02]\n",
            "Selected Features: Index(['Age', 'ProductCategory'], dtype='object')\n"
          ]
        }
      ]
    }
  ]
}