{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "97cdd781-ae8f-4f27-b9e8-5760b1e69121",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "\n",
    "# Assuming 'df' is your DataFrame and 'Housing.csv' is already loaded\n",
    "df = pd.read_csv(\"Housing.csv\")\n",
    "\n",
    "# Handling missing values based on column data types\n",
    "for column in df.columns:\n",
    "    if df[column].dtype == 'object':  # For categorical data\n",
    "        df[column] = df[column].fillna(df[column].mode()[0])\n",
    "    else:  # For numerical data\n",
    "        df[column] = df[column].fillna(df[column].median())\n",
    "\n",
    "# Check for missing values to ensure they are filled\n",
    "print(\"Missing values per column:\\n\", df.isnull().sum())\n",
    "\n",
    "# Define a function for Z-score method\n",
    "def remove_outliers_zscore(data, threshold=3):\n",
    "    z_scores = np.abs((data - data.mean()) / data.std())\n",
    "    return data[(z_scores < threshold).all(axis=1)]\n",
    "\n",
    "# Define a function for IQR method\n",
    "def remove_outliers_iqr(data):\n",
    "    Q1 = data.quantile(0.25)\n",
    "    Q3 = data.quantile(0.75)\n",
    "    IQR = Q3 - Q1\n",
    "    return data[~((data < (Q1 - 1.5 * IQR)) | (data > (Q3 + 1.5 * IQR))).any(axis=1)]\n",
    "\n",
    "# Apply outlier handling on numerical columns only\n",
    "numerical_df = df.select_dtypes(include=[np.number])\n",
    "\n",
    "# Using Z-score Method\n",
    "df_no_outliers_z = remove_outliers_zscore(numerical_df)\n",
    "\n",
    "# Using IQR Method\n",
    "df_no_outliers_iqr = remove_outliers_iqr(numerical_df)\n",
    "\n",
    "print(f\"Original shape: {df.shape}\")\n",
    "print(f\"Shape after removing outliers (Z-score): {df_no_outliers_z.shape}\")\n",
    "print(f\"Shape after removing outliers (IQR): {df_no_outliers_iqr.shape}\")\n",
    "\n",
    "# Set up the plotting aesthetics\n",
    "sns.set(style=\"whitegrid\")\n",
    "\n",
    "# Histogram for numerical features\n",
    "numerical_features = df.select_dtypes(include=[np.number]).columns\n",
    "df[numerical_features].hist(bins=15, figsize=(15, 10), color='skyblue', edgecolor='black')\n",
    "plt.suptitle(\"Histograms of Numerical Features\", fontsize=16)\n",
    "plt.show()\n",
    "\n",
    "# Box plot for each numerical feature to check for outliers\n",
    "plt.figure(figsize=(15, 10))\n",
    "for i, column in enumerate(numerical_features, 1):\n",
    "    plt.subplot(3, 3, i)\n",
    "    sns.boxplot(y=df[column], color='salmon')\n",
    "    plt.title(f'Box plot of {column}')\n",
    "plt.tight_layout()\n",
    "plt.show()\n",
    "\n",
    "# Scatter plot to identify potential relationships between features\n",
    "plt.figure(figsize=(10, 6))\n",
    "if 'price' in df.columns and 'sqft' in df.columns:\n",
    "    sns.scatterplot(data=df, x='sqft', y='price', color='blue', alpha=0.6)\n",
    "    plt.title(\"Square Footage vs. Price\")\n",
    "    plt.xlabel(\"Square Footage\")\n",
    "    plt.ylabel(\"Price\")\n",
    "    plt.show()\n",
    "\n",
    "# Correlation heatmap for numerical features\n",
    "plt.figure(figsize=(10, 8))\n",
    "sns.heatmap(df[numerical_features].corr(), annot=True, cmap='coolwarm', fmt=\".2f\")\n",
    "plt.title(\"Correlation Heatmap of Numerical Features\")\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
