{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "155c56dc",
   "metadata": {},
   "source": [
    "# Q9: Data Cleaning and Preparation\n",
    "\n",
    "**Problem Statement:** Analyzing Customer Churn in a Telecommunications Company"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "1f4eea6f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Original shape: (241, 8)\n",
      "CustomerID Gender  SeniorCitizen  Tenure       Contract  MonthlyCharges  TotalCharges Churn\n",
      "    TC0001   Male              0      38 Month-to-month           53.62       2113.97    No\n",
      "    TC0002 Female              0      39 Month-to-month           46.31       1818.96   Yes\n",
      "    TC0003 Female              1      21 Month-to-month           72.14       1565.46   Yes\n",
      "    TC0004   Male              0      30 Month-to-month          100.92       3172.79    No\n",
      "    TC0005   Male              1      42       One year           95.11       4009.03    No\n",
      "Missing values:\n",
      " CustomerID        0\n",
      "Gender            0\n",
      "SeniorCitizen     0\n",
      "Tenure            0\n",
      "Contract          0\n",
      "MonthlyCharges    1\n",
      "TotalCharges      1\n",
      "Churn             0\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "customers = pd.read_csv(\"Telecom_Customer_Churn.csv\")\n",
    "print(\"Original shape:\", customers.shape)\n",
    "print(customers.head().to_string(index=False))\n",
    "print(\"Missing values:\\n\", customers.isna().sum().to_string())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "ea8f985e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "After cleaning: (240, 8)\n",
      "Remaining missing values: 0\n"
     ]
    }
   ],
   "source": [
    "# Remove duplicate customers and standardize inconsistent categorical values.\n",
    "customers = customers.drop_duplicates(subset=\"CustomerID\").copy()\n",
    "customers[\"Gender\"] = customers[\"Gender\"].astype(\"string\").str.strip().str.title()\n",
    "customers[\"Contract\"] = customers[\"Contract\"].astype(\"string\").str.strip().str.title()\n",
    "customers[\"Churn\"] = customers[\"Churn\"].astype(\"string\").str.strip().str.title()\n",
    "for column in [\"Tenure\", \"MonthlyCharges\", \"TotalCharges\"]:\n",
    "    customers[column] = pd.to_numeric(customers[column], errors=\"coerce\")\n",
    "    customers[column] = customers[column].fillna(customers[column].median())\n",
    "for column in [\"Gender\", \"Contract\"]:\n",
    "    customers[column] = customers[column].fillna(customers[column].mode().iloc[0])\n",
    "print(\"After cleaning:\", customers.shape)\n",
    "print(\"Remaining missing values:\", int(customers.isna().sum().sum()))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "3902fcfc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " Tenure TenureGroup  AverageCharge Churn\n",
      "     38 Established      55.630789    No\n",
      "     39 Established      46.640000   Yes\n",
      "     21     Growing      74.545714   Yes\n",
      "     30 Established     105.759667    No\n",
      "     42 Established      95.453095    No\n"
     ]
    }
   ],
   "source": [
    "# Cap extreme numeric values using IQR bounds.\n",
    "for column in [\"MonthlyCharges\", \"TotalCharges\"]:\n",
    "    q1, q3 = customers[column].quantile([0.25, 0.75])\n",
    "    iqr = q3 - q1\n",
    "    customers[column] = customers[column].clip(q1 - 1.5 * iqr, q3 + 1.5 * iqr)\n",
    "customers[\"AverageCharge\"] = customers[\"TotalCharges\"] / customers[\"Tenure\"].clip(lower=1)\n",
    "customers[\"TenureGroup\"] = pd.cut(customers[\"Tenure\"], bins=[0, 12, 24, 48, 100], labels=[\"New\", \"Growing\", \"Established\", \"Long-term\"])\n",
    "print(customers[[\"Tenure\", \"TenureGroup\", \"AverageCharge\", \"Churn\"]].head().to_string(index=False))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "73c2950b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train/test rows: 192 48\n",
      "Churn rate in train/test: 0.286 0.292\n",
      "Saved Telecom_Customer_Churn_Cleaned.csv\n"
     ]
    }
   ],
   "source": [
    "# Export the cleaned records before encoding or scaling them for modeling.\n",
    "customers.to_csv(\"Telecom_Customer_Churn_Cleaned.csv\", index=False)\n",
    "X = pd.get_dummies(customers.drop(columns=[\"CustomerID\", \"Churn\"]), drop_first=True, dtype=int)\n",
    "y = customers[\"Churn\"].eq(\"Yes\").astype(int)\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)\n",
    "numeric_columns = [\"Tenure\", \"MonthlyCharges\", \"TotalCharges\", \"AverageCharge\"]\n",
    "scaler = StandardScaler()\n",
    "X_train[numeric_columns] = scaler.fit_transform(X_train[numeric_columns])\n",
    "X_test[numeric_columns] = scaler.transform(X_test[numeric_columns])\n",
    "print(\"Train/test rows:\", len(X_train), len(X_test))\n",
    "print(\"Churn rate in train/test:\", round(y_train.mean(), 3), round(y_test.mean(), 3))\n",
    "print(\"Saved Telecom_Customer_Churn_Cleaned.csv\")\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "file_extension": ".py",
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
