{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "2595518b",
   "metadata": {},
   "source": [
    "# Possum – Dimensionality Reduction"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "275d751a",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.decomposition import PCA, TruncatedSVD, FactorAnalysis\n",
    "from sklearn.metrics import mean_squared_error\n",
    "from sklearn.impute import SimpleImputer\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "4c1020af",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(104, 14)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>case</th>\n",
       "      <th>site</th>\n",
       "      <th>Pop</th>\n",
       "      <th>sex</th>\n",
       "      <th>age</th>\n",
       "      <th>hdlngth</th>\n",
       "      <th>skullw</th>\n",
       "      <th>totlngth</th>\n",
       "      <th>taill</th>\n",
       "      <th>footlgth</th>\n",
       "      <th>earconch</th>\n",
       "      <th>eye</th>\n",
       "      <th>chest</th>\n",
       "      <th>belly</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>Vic</td>\n",
       "      <td>m</td>\n",
       "      <td>8.0</td>\n",
       "      <td>94.1</td>\n",
       "      <td>60.4</td>\n",
       "      <td>89.0</td>\n",
       "      <td>36.0</td>\n",
       "      <td>74.5</td>\n",
       "      <td>54.5</td>\n",
       "      <td>15.2</td>\n",
       "      <td>28.0</td>\n",
       "      <td>36.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>Vic</td>\n",
       "      <td>f</td>\n",
       "      <td>6.0</td>\n",
       "      <td>92.5</td>\n",
       "      <td>57.6</td>\n",
       "      <td>91.5</td>\n",
       "      <td>36.5</td>\n",
       "      <td>72.5</td>\n",
       "      <td>51.2</td>\n",
       "      <td>16.0</td>\n",
       "      <td>28.5</td>\n",
       "      <td>33.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "      <td>Vic</td>\n",
       "      <td>f</td>\n",
       "      <td>6.0</td>\n",
       "      <td>94.0</td>\n",
       "      <td>60.0</td>\n",
       "      <td>95.5</td>\n",
       "      <td>39.0</td>\n",
       "      <td>75.4</td>\n",
       "      <td>51.9</td>\n",
       "      <td>15.5</td>\n",
       "      <td>30.0</td>\n",
       "      <td>34.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>1</td>\n",
       "      <td>Vic</td>\n",
       "      <td>f</td>\n",
       "      <td>6.0</td>\n",
       "      <td>93.2</td>\n",
       "      <td>57.1</td>\n",
       "      <td>92.0</td>\n",
       "      <td>38.0</td>\n",
       "      <td>76.1</td>\n",
       "      <td>52.2</td>\n",
       "      <td>15.2</td>\n",
       "      <td>28.0</td>\n",
       "      <td>34.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>1</td>\n",
       "      <td>Vic</td>\n",
       "      <td>f</td>\n",
       "      <td>2.0</td>\n",
       "      <td>91.5</td>\n",
       "      <td>56.3</td>\n",
       "      <td>85.5</td>\n",
       "      <td>36.0</td>\n",
       "      <td>71.0</td>\n",
       "      <td>53.2</td>\n",
       "      <td>15.1</td>\n",
       "      <td>28.5</td>\n",
       "      <td>33.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   case  site  Pop sex  age  hdlngth  skullw  totlngth  taill  footlgth  \\\n",
       "0     1     1  Vic   m  8.0     94.1    60.4      89.0   36.0      74.5   \n",
       "1     2     1  Vic   f  6.0     92.5    57.6      91.5   36.5      72.5   \n",
       "2     3     1  Vic   f  6.0     94.0    60.0      95.5   39.0      75.4   \n",
       "3     4     1  Vic   f  6.0     93.2    57.1      92.0   38.0      76.1   \n",
       "4     5     1  Vic   f  2.0     91.5    56.3      85.5   36.0      71.0   \n",
       "\n",
       "   earconch   eye  chest  belly  \n",
       "0      54.5  15.2   28.0   36.0  \n",
       "1      51.2  16.0   28.5   33.0  \n",
       "2      51.9  15.5   30.0   34.0  \n",
       "3      52.2  15.2   28.0   34.0  \n",
       "4      53.2  15.1   28.5   33.0  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\n",
    "df=pd.read_csv(\"possum.csv\")\n",
    "df.columns=df.columns.str.strip()\n",
    "\n",
    "print(df.shape)\n",
    "display(df.head())\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "37f9e5e0",
   "metadata": {},
   "source": [
    "## Remove non‑informative variables"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "09ab7414",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "df=df.drop(columns=[\"case\",\"site\"])\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dec851c8",
   "metadata": {},
   "source": [
    "## Dummy encode categorical variables"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "68c6309d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(104, 12)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>age</th>\n",
       "      <th>hdlngth</th>\n",
       "      <th>skullw</th>\n",
       "      <th>totlngth</th>\n",
       "      <th>taill</th>\n",
       "      <th>footlgth</th>\n",
       "      <th>earconch</th>\n",
       "      <th>eye</th>\n",
       "      <th>chest</th>\n",
       "      <th>belly</th>\n",
       "      <th>Pop_other</th>\n",
       "      <th>sex_m</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>8.0</td>\n",
       "      <td>94.1</td>\n",
       "      <td>60.4</td>\n",
       "      <td>89.0</td>\n",
       "      <td>36.0</td>\n",
       "      <td>74.5</td>\n",
       "      <td>54.5</td>\n",
       "      <td>15.2</td>\n",
       "      <td>28.0</td>\n",
       "      <td>36.0</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>6.0</td>\n",
       "      <td>92.5</td>\n",
       "      <td>57.6</td>\n",
       "      <td>91.5</td>\n",
       "      <td>36.5</td>\n",
       "      <td>72.5</td>\n",
       "      <td>51.2</td>\n",
       "      <td>16.0</td>\n",
       "      <td>28.5</td>\n",
       "      <td>33.0</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>6.0</td>\n",
       "      <td>94.0</td>\n",
       "      <td>60.0</td>\n",
       "      <td>95.5</td>\n",
       "      <td>39.0</td>\n",
       "      <td>75.4</td>\n",
       "      <td>51.9</td>\n",
       "      <td>15.5</td>\n",
       "      <td>30.0</td>\n",
       "      <td>34.0</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>6.0</td>\n",
       "      <td>93.2</td>\n",
       "      <td>57.1</td>\n",
       "      <td>92.0</td>\n",
       "      <td>38.0</td>\n",
       "      <td>76.1</td>\n",
       "      <td>52.2</td>\n",
       "      <td>15.2</td>\n",
       "      <td>28.0</td>\n",
       "      <td>34.0</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2.0</td>\n",
       "      <td>91.5</td>\n",
       "      <td>56.3</td>\n",
       "      <td>85.5</td>\n",
       "      <td>36.0</td>\n",
       "      <td>71.0</td>\n",
       "      <td>53.2</td>\n",
       "      <td>15.1</td>\n",
       "      <td>28.5</td>\n",
       "      <td>33.0</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   age  hdlngth  skullw  totlngth  taill  footlgth  earconch   eye  chest  \\\n",
       "0  8.0     94.1    60.4      89.0   36.0      74.5      54.5  15.2   28.0   \n",
       "1  6.0     92.5    57.6      91.5   36.5      72.5      51.2  16.0   28.5   \n",
       "2  6.0     94.0    60.0      95.5   39.0      75.4      51.9  15.5   30.0   \n",
       "3  6.0     93.2    57.1      92.0   38.0      76.1      52.2  15.2   28.0   \n",
       "4  2.0     91.5    56.3      85.5   36.0      71.0      53.2  15.1   28.5   \n",
       "\n",
       "   belly  Pop_other  sex_m  \n",
       "0   36.0      False   True  \n",
       "1   33.0      False  False  \n",
       "2   34.0      False  False  \n",
       "3   34.0      False  False  \n",
       "4   33.0      False  False  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\n",
    "df=pd.get_dummies(df,columns=[\"Pop\",\"sex\"],drop_first=True)\n",
    "\n",
    "print(df.shape)\n",
    "display(df.head())\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "266e5ad6",
   "metadata": {},
   "source": [
    "## Handle missing values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "920fa0df",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "imputer=SimpleImputer(strategy=\"median\")\n",
    "X=imputer.fit_transform(df)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "639f05a6",
   "metadata": {},
   "source": [
    "## Scaling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "f1fb3ae6",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "scaler=StandardScaler()\n",
    "X=scaler.fit_transform(X)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3cf0bd49",
   "metadata": {},
   "source": [
    "## Dimensionality reduction methods"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "14b52777",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "results=[]\n",
    "reduced={}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "4cd9b8e8",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "# PCA\n",
    "pca=PCA(n_components=2)\n",
    "Xp=pca.fit_transform(X)\n",
    "\n",
    "recon=pca.inverse_transform(Xp)\n",
    "mse=mean_squared_error(X,recon)\n",
    "\n",
    "results.append({\n",
    "\"method\":\"PCA\",\n",
    "\"explained_variance\":pca.explained_variance_ratio_.sum(),\n",
    "\"reconstruction_mse\":mse\n",
    "})\n",
    "\n",
    "reduced[\"PCA\"]=Xp\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "cc6cd1d7",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "# SVD\n",
    "svd=TruncatedSVD(n_components=2)\n",
    "Xs=svd.fit_transform(X)\n",
    "\n",
    "recon=np.dot(Xs,svd.components_)\n",
    "mse=mean_squared_error(X,recon)\n",
    "\n",
    "results.append({\n",
    "\"method\":\"TruncatedSVD\",\n",
    "\"explained_variance\":svd.explained_variance_ratio_.sum(),\n",
    "\"reconstruction_mse\":mse\n",
    "})\n",
    "\n",
    "reduced[\"SVD\"]=Xs\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "a44cc5ef",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "# Factor Analysis\n",
    "fa=FactorAnalysis(n_components=2)\n",
    "Xf=fa.fit_transform(X)\n",
    "\n",
    "recon=np.dot(Xf,fa.components_)\n",
    "mse=mean_squared_error(X,recon)\n",
    "\n",
    "results.append({\n",
    "\"method\":\"FactorAnalysis\",\n",
    "\"explained_variance\":np.nan,\n",
    "\"reconstruction_mse\":mse\n",
    "})\n",
    "\n",
    "reduced[\"FA\"]=Xf\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "48d33b4b",
   "metadata": {},
   "source": [
    "## Compare methods"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "098e8cc7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>method</th>\n",
       "      <th>explained_variance</th>\n",
       "      <th>reconstruction_mse</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>TruncatedSVD</td>\n",
       "      <td>0.584029</td>\n",
       "      <td>0.415971</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>PCA</td>\n",
       "      <td>0.584029</td>\n",
       "      <td>0.415971</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>FactorAnalysis</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.435009</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           method  explained_variance  reconstruction_mse\n",
       "1    TruncatedSVD            0.584029            0.415971\n",
       "0             PCA            0.584029            0.415971\n",
       "2  FactorAnalysis                 NaN            0.435009"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\n",
    "results_df=pd.DataFrame(results)\n",
    "results_df=results_df.sort_values([\"explained_variance\",\"reconstruction_mse\"],ascending=[False,True])\n",
    "\n",
    "display(results_df)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dfb6b193",
   "metadata": {},
   "source": [
    "## Best method"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "956a04de",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Best method: TruncatedSVD\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Comp1</th>\n",
       "      <th>Comp2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2.617769</td>\n",
       "      <td>-1.567141</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1.804442</td>\n",
       "      <td>-1.246078</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3.423580</td>\n",
       "      <td>-0.955736</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2.188869</td>\n",
       "      <td>-1.536748</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.263640</td>\n",
       "      <td>-1.979382</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      Comp1     Comp2\n",
       "0  2.617769 -1.567141\n",
       "1  1.804442 -1.246078\n",
       "2  3.423580 -0.955736\n",
       "3  2.188869 -1.536748\n",
       "4  0.263640 -1.979382"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\n",
    "best_method=results_df.iloc[0][\"method\"]\n",
    "print(\"Best method:\",best_method)\n",
    "\n",
    "X_best=reduced[\"PCA\"] if best_method==\"PCA\" else reduced[\"SVD\"] if best_method==\"TruncatedSVD\" else reduced[\"FA\"]\n",
    "\n",
    "X_best=pd.DataFrame(X_best,columns=[\"Comp1\",\"Comp2\"])\n",
    "display(X_best.head())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "0234468b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjUAAAHHCAYAAABHp6kXAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAASdlJREFUeJzt3Xl0VGW29/FfBSGBAIFAIAEiQ0A0RKFBQQYREARFBq+As+CALQIqXFvAFiNONFcXYtOIQyvY4gjoBbttbBQQbUF4RdSA2A0NgiGMkQqiBEyd9w9uxRSpSg2pqjPU97MWa5lTpyq7TsqcnefZz35chmEYAgAAsLkkswMAAACIBpIaAADgCCQ1AADAEUhqAACAI5DUAAAARyCpAQAAjkBSAwAAHIGkBgAAOAJJDQAAcASSGsDGFi5cKJfLpV27dpkdSkAul0sPPfRQ0PP279+vESNGqFGjRnK5XJozZ07MYwPgLCQ1QJR5Ew3vvzPOOEPNmzfXmDFjVFhYaHZ4ljVp0iS9//77mjZtml555RUNGjQoJt/n8ccf1//+7//G5LUBmOsMswMAnOrhhx9W69atdfz4ca1fv14LFy7UJ598ooKCAqWkpJgdnuWsWrVKw4YN07333hvT7/P4449rxIgRGj58eEy/D4D4I6kBYuSyyy7T+eefL0m67bbb1LhxY82aNUvLly/XqFGjTI7Oeg4cOKAGDRqYHUZEPB6PTpw4QbIKmIzpJyBOLrroIknSjh07fI5v27ZNI0aMUHp6ulJSUnT++edr+fLllZ6/ZcsW9evXT7Vr11aLFi306KOPyuPxVDovUA1Lq1atNGbMGJ9jR44c0aRJk9SqVSslJyerRYsWuummm3To0KHyc0pLS5Wfn6+2bdsqOTlZ2dnZuu+++1RaWurzWqWlpZo0aZIyMjJUr149DR06VN9//33Q6+KdrjMMQ/PmzSuftqsY4z333KPs7GwlJyerbdu2mjVrVqX3/uSTT6pHjx5q1KiRateurS5dumjJkiWVrs2xY8f08ssvl38f7zUZM2aMWrVqVSm+hx56yCce7+tMmDBBr776qjp06KDk5GStWLFCklRYWKhbbrlFTZs2VXJysjp06KCXXnop6HWQpJUrV6pXr15q0KCB6tatq/bt2+v+++8vf3zNmjVyuVx68803df/99yszM1OpqakaOnSo9uzZ4/NaH3/8sUaOHKkzzzyz/Oc2adIk/fzzz5W+77Zt2zRq1ChlZGSodu3aat++vX7/+9/7nFOd9wXECyM1QJx4i3kbNmxYfmzLli3q2bOnmjdvrqlTpyo1NVVvvfWWhg8frqVLl+rKK6+UJO3bt099+/bVL7/8Un7e888/r9q1a0ccz48//qiLLrpI33zzjW655RZ17txZhw4d0vLly/X999+rcePG8ng8Gjp0qD755BPdfvvtOuecc/T111/rqaee0r/+9S+f2pTbbrtNixYt0nXXXacePXpo1apVGjx4cNA4evfurVdeeUU33nijBgwYoJtuuqn8sZ9++kkXX3yxCgsL9dvf/lZnnnmmPv30U02bNk1FRUU+xcRPP/20hg4dquuvv14nTpzQG2+8oZEjR+qvf/1reRyvvPKKbrvtNnXt2lW33367JCknJyei67dq1Sq99dZbmjBhgho3bqxWrVpp//79uvDCC8uTnoyMDP3973/XrbfeqpKSEt1zzz0BX2/Lli264oordN555+nhhx9WcnKytm/frn/+85+Vzn3sscfkcrk0ZcoUHThwQHPmzFH//v21efPm8s/E4sWL9dNPP2ncuHFq1KiRNmzYoLlz5+r777/X4sWLy1/rq6++0kUXXaSaNWvq9ttvV6tWrbRjxw69++67euyxxySpWu8LiCsDQFQtWLDAkGR88MEHxsGDB409e/YYS5YsMTIyMozk5GRjz5495edecsklxrnnnmscP368/JjH4zF69OhhtGvXrvzYPffcY0gyPvvss/JjBw4cMNLS0gxJxs6dO8uPSzLy8/MrxdWyZUtj9OjR5V8/+OCDhiTj7bffrnSux+MxDMMwXnnlFSMpKcn4+OOPfR5/9tlnDUnGP//5T8MwDGPz5s2GJOPOO+/0Oe+6664LGM/pJBnjx4/3OfbII48Yqampxr/+9S+f41OnTjVq1Khh7N69u/zYTz/95HPOiRMnjLy8PKNfv34+x1NTU32ug9fo0aONli1bVjqen59vnP6rUpKRlJRkbNmyxef4rbfeamRlZRmHDh3yOX7NNdcYaWlplWKs6KmnnjIkGQcPHgx4zurVqw1JRvPmzY2SkpLy42+99ZYhyXj66afLj/n7XjNnzjRcLpfx3XfflR/r3bu3Ua9ePZ9jhvHrZ6C67wuIJ6afgBjp37+/MjIylJ2drREjRig1NVXLly9XixYtJEnFxcVatWqVRo0apaNHj+rQoUM6dOiQDh8+rIEDB+rf//53+Wqp9957TxdeeKG6du1a/voZGRm6/vrrI45v6dKl6tixY/loUEXe6ZbFixfrnHPO0dlnn10e36FDh9SvXz9J0urVq8vjk6S77rrL53Wq+xf84sWLddFFF6lhw4Y+379///4qKyvT2rVry8+tOGr1ww8/yO1266KLLtKmTZuqFUMgF198sXJzc8u/NgxDS5cu1ZAhQ2QYhk+8AwcOlNvtrjIWbz3RsmXL/E4rVnTTTTepXr165V+PGDFCWVlZ5T8Hyfd6HDt2TIcOHVKPHj1kGIa++OILSdLBgwe1du1a3XLLLTrzzDN9vof3M1Dd9wXEE9NPQIzMmzdPZ511ltxut1566SWtXbtWycnJ5Y9v375dhmFo+vTpmj59ut/XOHDggJo3b67vvvtO3bp1q/R4+/btI45vx44duuqqq6o859///re++eYbZWRkBIxPkr777jslJSVVmsqpTnze7//VV18F/f6S9Ne//lWPPvqoNm/e7FPvc3o9TLS0bt3a5+uDBw/qyJEjev755/X8888Hjfd0V199tf785z/rtttu09SpU3XJJZfov/7rvzRixAglJfn+/dmuXTufr10ul9q2bevTr2j37t168MEHtXz5cv3www8+57vdbknSf/7zH0lSXl5ewLiq+76AeCKpAWKka9eu5aufhg8frl69eum6667Tt99+q7p165b/NX7vvfdq4MCBfl+jbdu2UYunrKws7Od4PB6de+65mj17tt/Hs7OzqxtW0O8/YMAA3XfffX4fP+ussySdKoodOnSoevfurWeeeUZZWVmqWbOmFixYoNdeey2k7xUo+Ql03U6vZ/L+PG+44QaNHj3a73POO++8gN+/du3aWrt2rVavXq2//e1vWrFihd58803169dP//jHP1SjRo1Q3kZ5zAMGDFBxcbGmTJmis88+W6mpqSosLNSYMWOCjgRF830B8URSA8RBjRo1NHPmTPXt21d/+tOfNHXqVLVp00aSVLNmTfXv37/K57ds2VL//ve/Kx3/9ttvKx1r2LChjhw54nPsxIkTKioq8jmWk5OjgoKCKr9vTk6OvvzyS11yySVVjni0bNlSHo9HO3bs8Bmd8RdfOHJycvTjjz8GvT5Lly5VSkqK3n//fZ/RsAULFlQ6N9D78HfdpFOjUKHwrvoqKysLGm8gSUlJuuSSS3TJJZdo9uzZevzxx/X73/9eq1ev9nnN0z8LhmFo+/bt5cnF119/rX/96196+eWXfQqvV65c6fM872ewqs9BNN4XEC/U1ABx0qdPH3Xt2lVz5szR8ePH1aRJE/Xp00fPPfdcpYRDOjXs73X55Zdr/fr12rBhg8/jr776aqXn5eTk+NSaSNLzzz9facThqquu0pdffql33nmn0msYhiFJGjVqlAoLC/XCCy9UOufnn3/WsWPHJJ3qySNJf/zjH33Oqe5WB6NGjdK6dev0/vvvV3rsyJEj+uWXXySdShpdLpfPe9y1a5ffzsGpqal+k5ecnBy53W599dVX5ceKior8Xh9/atSooauuukpLly71myRU/Hn6U1xcXOlYp06dJKnS8vm//OUvOnr0aPnXS5YsUVFRUfnPwTuq4/05ev/76aef9nmdjIwM9e7dWy+99JJ2797t85j3udV9X0A8MVIDxNHvfvc7jRw5UgsXLtQdd9yhefPmqVevXjr33HM1duxYtWnTRvv379e6dev0/fff68svv5Qk3XfffeVbB9x9993lS7pbtmzpcxOWTi2tvuOOO3TVVVdpwIAB+vLLL/X++++rcePGlWJZsmSJRo4cqVtuuUVdunRRcXGxli9frmeffVYdO3bUjTfeqLfeekt33HGHVq9erZ49e6qsrEzbtm3TW2+9pffff1/nn3++OnXqpGuvvVbPPPOM3G63evTooQ8//FDbt2+v9vVavny5rrjiCo0ZM0ZdunTRsWPH9PXXX2vJkiXatWuXGjdurMGDB2v27NkaNGiQrrvuOh04cEDz5s1T27ZtK12fLl266IMPPtDs2bPVrFkztW7dWt26ddM111yjKVOm6Morr9Rdd92ln376SfPnz9dZZ50VciHsH/7wB61evVrdunXT2LFjlZubq+LiYm3atEkffPCB38TF6+GHH9batWs1ePBgtWzZUgcOHNAzzzyjFi1aqFevXj7npqenq1evXrr55pu1f/9+zZkzR23bttXYsWMlSWeffbZycnJ07733qrCwUPXr19fSpUsr1dZIpxLRXr16qXPnzrr99tvVunVr7dq1S3/729+0efPmar8vIK5MWnUFOJZ3SffGjRsrPVZWVmbk5OQYOTk5xi+//GIYhmHs2LHDuOmm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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\n",
    "plt.scatter(X_best[\"Comp1\"],X_best[\"Comp2\"])\n",
    "plt.xlabel(\"Comp1\")\n",
    "plt.ylabel(\"Comp2\")\n",
    "plt.title(\"Reduced feature space\")\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a49842a7",
   "metadata": {},
   "source": [
    "Итог\n",
    "\n",
    "Из датафрейма были удалены несодержательные переменные case и site.\n",
    "Факторные переменные Pop и sex были даммифицированы. После подготовки данных использовано 12 признаков.\n",
    "\n",
    "Снижение размерности\n",
    "\n",
    "Были протестированы методы:\n",
    "\n",
    "PCA\n",
    "\n",
    "Truncated SVD\n",
    "\n",
    "Factor Analysis\n",
    "\n",
    "Качество методов:\n",
    "\n",
    "| Метод        | Explained Variance | Reconstruction MSE |\n",
    "|--------------|--------------------|--------------------|\n",
    "| TruncatedSVD | 0.584              | 0.416              |\n",
    "| PCA          | 0.584              | 0.416              |\n",
    "\n",
    "FactorAnalysis\t—\t0.435\n",
    "Лучший метод\n",
    "\n",
    "Лучший результат показал TruncatedSVD, так как он обеспечивает максимальную объяснённую дисперсию и минимальную ошибку восстановления.\n",
    "\n",
    "Вывод\n",
    "\n",
    "Метод TruncatedSVD признан лучшим методом снижения размерности для данного датасета.\n",
    "После применения метода были сформированы две новые переменные (Comp1, Comp2), которые сохраняют большую часть информации исходных признаков и могут использоваться для дальнейшего анализа данных. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a369297f",
   "metadata": {},
   "source": []
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
