{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. Продажи домов\n",
    "2. Данные о населении \n",
    "3. Набор данных для анализа и прогнозирования сердечного приступа"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h4>Продажа домов</h4>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 262,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Index(['date', 'price', 'bedrooms', 'bathrooms', 'sqft_living', 'sqft_lot',\n",
      "       'floors', 'waterfront', 'view', 'condition', 'grade', 'sqft_above',\n",
      "       'sqft_basement', 'yr_built', 'yr_renovated', 'zipcode', 'lat', 'long',\n",
      "       'sqft_living15', 'sqft_lot15'],\n",
      "      dtype='object') \n",
      "\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd \n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "\n",
    "df = pd.read_csv(\"..//static//csv//House.csv\", index_col=\"id\")\n",
    "\n",
    "print(df.columns, \"\\n\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Столбцы для русских:<br>\n",
    "<br>\n",
    "<span style=\"color: #189FFF;\">id:</span> Идентификатор объекта<br>\n",
    "<span style=\"color: #189FFF;\">date:</span> Дата продажи<br>\n",
    "<span style=\"color: #189FFF;\">price:</span> Цена недвижимости<br>\n",
    "<span style=\"color: #189FFF;\">bedrooms:</span> Количество спален<br>\n",
    "<span style=\"color: #189FFF;\">bathrooms:</span> Количество ванных комнат<br>\n",
    "<span style=\"color: #189FFF;\">sqft_living:</span> Жилая площадь<br>\n",
    "<span style=\"color: #189FFF;\">sqft_lot:</span> Площадь участка<br>\n",
    "<span style=\"color: #189FFF;\">floors:</span> Количество этажей<br>\n",
    "<span style=\"color: #189FFF;\">waterfront:</span> Признак наличия вида на водоем<br>\n",
    "<span style=\"color: #189FFF;\">view:</span> Оценка вида<br>\n",
    "<span style=\"color: #189FFF;\">condition:</span> Состояние дома<br>\n",
    "<span style=\"color: #189FFF;\">grade:</span> Оценка конструкции<br>\n",
    "<span style=\"color: #189FFF;\">sqft_above:</span> Площадь надземных помещений<br>\n",
    "<span style=\"color: #189FFF;\">sqft_basement:</span> Площадь подвала<br>\n",
    "<span style=\"color: #189FFF;\">yr_built:</span> Год постройки<br>\n",
    "<span style=\"color: #189FFF;\">yr_renovated:</span> Год последнего ремонта<br>\n",
    "<span style=\"color: #189FFF;\">zipcode:</span> Почтовый индекс<br>\n",
    "<span style=\"color: #189FFF;\">lat:</span> Широта<br>\n",
    "<span style=\"color: #189FFF;\">long:</span> Долгота<br>\n",
    "<span style=\"color: #189FFF;\">sqft_living15:</span> Жилая площадь соседних домов<br>\n",
    "<span style=\"color: #189FFF;\">sqft_lot15:</span> Площадь участка соседних домов<br>\n",
    "<br>\n",
    "Проблемная область: Прогнозирование стоимости недвижимости в зависимости от характеристик дома.<br>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 263,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<bound method DataFrame.info of                        date     price  bedrooms  bathrooms  sqft_living  \\\n",
      "id                                                                        \n",
      "7129300520  20141013T000000  221900.0         3       1.00         1180   \n",
      "6414100192  20141209T000000  538000.0         3       2.25         2570   \n",
      "5631500400  20150225T000000  180000.0         2       1.00          770   \n",
      "2487200875  20141209T000000  604000.0         4       3.00         1960   \n",
      "1954400510  20150218T000000  510000.0         3       2.00         1680   \n",
      "...                     ...       ...       ...        ...          ...   \n",
      "263000018   20140521T000000  360000.0         3       2.50         1530   \n",
      "6600060120  20150223T000000  400000.0         4       2.50         2310   \n",
      "1523300141  20140623T000000  402101.0         2       0.75         1020   \n",
      "291310100   20150116T000000  400000.0         3       2.50         1600   \n",
      "1523300157  20141015T000000  325000.0         2       0.75         1020   \n",
      "\n",
      "            sqft_lot  floors  waterfront  view  condition  grade  sqft_above  \\\n",
      "id                                                                             \n",
      "7129300520      5650     1.0           0     0          3      7        1180   \n",
      "6414100192      7242     2.0           0     0          3      7        2170   \n",
      "5631500400     10000     1.0           0     0          3      6         770   \n",
      "2487200875      5000     1.0           0     0          5      7        1050   \n",
      "1954400510      8080     1.0           0     0          3      8        1680   \n",
      "...              ...     ...         ...   ...        ...    ...         ...   \n",
      "263000018       1131     3.0           0     0          3      8        1530   \n",
      "6600060120      5813     2.0           0     0          3      8        2310   \n",
      "1523300141      1350     2.0           0     0          3      7        1020   \n",
      "291310100       2388     2.0           0     0          3      8        1600   \n",
      "1523300157      1076     2.0           0     0          3      7        1020   \n",
      "\n",
      "            sqft_basement  yr_built  yr_renovated  zipcode      lat     long  \\\n",
      "id                                                                             \n",
      "7129300520              0      1955             0    98178  47.5112 -122.257   \n",
      "6414100192            400      1951          1991    98125  47.7210 -122.319   \n",
      "5631500400              0      1933             0    98028  47.7379 -122.233   \n",
      "2487200875            910      1965             0    98136  47.5208 -122.393   \n",
      "1954400510              0      1987             0    98074  47.6168 -122.045   \n",
      "...                   ...       ...           ...      ...      ...      ...   \n",
      "263000018               0      2009             0    98103  47.6993 -122.346   \n",
      "6600060120              0      2014             0    98146  47.5107 -122.362   \n",
      "1523300141              0      2009             0    98144  47.5944 -122.299   \n",
      "291310100               0      2004             0    98027  47.5345 -122.069   \n",
      "1523300157              0      2008             0    98144  47.5941 -122.299   \n",
      "\n",
      "            sqft_living15  sqft_lot15  \n",
      "id                                     \n",
      "7129300520           1340        5650  \n",
      "6414100192           1690        7639  \n",
      "5631500400           2720        8062  \n",
      "2487200875           1360        5000  \n",
      "1954400510           1800        7503  \n",
      "...                   ...         ...  \n",
      "263000018            1530        1509  \n",
      "6600060120           1830        7200  \n",
      "1523300141           1020        2007  \n",
      "291310100            1410        1287  \n",
      "1523300157           1020        1357  \n",
      "\n",
      "[21613 rows x 20 columns]> \n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(df.info, \"\\n\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Объектом наблюдения является - Недвижимость<br>\n",
    "Атрибуты - содержит набор информации о продаже дома, такие как:<br>\n",
    "цену продажи, дата продажи, количество спален, ванных комнат, общую площадь дома, площадь участка, местоположение.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 264,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 109332 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10, 6))\n",
    "\n",
    "plt.scatter(df['sqft_living'], df['price'], c=df['price'], alpha=0.6)\n",
    "plt.colorbar(label='Price')\n",
    "\n",
    "plt.title(\"Номер 1\")\n",
    "plt.ylabel(\"Price\")\n",
    "plt.xlabel(\"Living Area\")\n",
    "plt.grid(visible='true')\n",
    "\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 265,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 64100 characters]",
      "text/plain": [
       "<Figure size 1200x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "year_condition = df.groupby('yr_built')['condition'].mean().reset_index()\n",
    "\n",
    "plt.figure(figsize=(12, 6))\n",
    "\n",
    "plt.plot(year_condition['yr_built'], year_condition['condition'], marker='.')\n",
    "\n",
    "plt.title(\"Номер 2\")\n",
    "plt.xlabel(\"Year Built\")\n",
    "plt.ylabel(\"Condition\")\n",
    "\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Связь между объектами есть. Цена связана почти со всеми характиристиками дома.<br> Например на графике номер один показана зависимоость между ценой и размером дома.<br> А на графике номер 2 показа зависимость состояния домов с годами."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3>Примеры бизнес целей</h3>\n",
    "\n",
    "1. Прогнозирование стоимости недвижимости на основе характиристик дома.\n",
    "2. Наблюдение за изменениями характиристик дома с годами.\n",
    "\n",
    "Эффект для бизнеса: Оценка и оптимизация цен, Оценка и планирование затрат, выявление тенденции на рынке, стратегия планирования."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3>Цели технического проекта</h3>\n",
    "<ul>Для первой цели:</ul>\n",
    "        <li>Вход: Характеристики недвижимости</li>\n",
    "        <li>Целевой признак: Цена.</li>\n",
    "<ul>Для второй цели:</ul>\n",
    "        <li>Вход: оценка конструкции, Состояние дома</li>\n",
    "        <li>Целевой признак: Год постройки</li>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3>Код ниже нужен для определения проблем данных</h3>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 266,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "date             20150527T000000\n",
      "price                  7700000.0\n",
      "bedrooms                      33\n",
      "bathrooms                    8.0\n",
      "sqft_living                13540\n",
      "sqft_lot                 1651359\n",
      "floors                       3.5\n",
      "waterfront                     1\n",
      "view                           4\n",
      "condition                      5\n",
      "grade                         13\n",
      "sqft_above                  9410\n",
      "sqft_basement               4820\n",
      "yr_built                    2015\n",
      "yr_renovated                2015\n",
      "zipcode                    98199\n",
      "lat                      47.7776\n",
      "long                    -121.315\n",
      "sqft_living15               6210\n",
      "sqft_lot15                871200\n",
      "dtype: object \n",
      "\n",
      "Index(['bedrooms', 'bathrooms', 'waterfront', 'view', 'sqft_basement',\n",
      "       'yr_renovated'],\n",
      "      dtype='object') \n",
      "\n",
      "Признаки с низкой дисперсией:\n",
      " waterfront    0.007485\n",
      "lat           0.019200\n",
      "long          0.019833\n",
      "dtype: float64 \n",
      "\n",
      "id\n",
      "7129300520    1955\n",
      "6414100192    1951\n",
      "5631500400    1933\n",
      "2487200875    1965\n",
      "1954400510    1987\n",
      "              ... \n",
      "263000018     2009\n",
      "6600060120    2014\n",
      "1523300141    2009\n",
      "291310100     2004\n",
      "1523300157    2008\n",
      "Name: yr_built, Length: 21613, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "max_value = df.max(axis=0)\n",
    "\n",
    "columns_with_zero = df.columns[(df == 0).any()]\n",
    "\n",
    "numeric_data = df.select_dtypes(include='number')\n",
    "shum = numeric_data.var()\n",
    "low_dispers = 0.1\n",
    "low_var_columns = shum[shum < low_dispers]\n",
    "\n",
    "\n",
    "year = df['yr_built']\n",
    "\n",
    "print(max_value, \"\\n\")\n",
    "print(columns_with_zero, \"\\n\")\n",
    "print(\"Признаки с низкой дисперсией:\\n\", low_var_columns, \"\\n\")\n",
    "print(year)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<ul><h4>Из полученных данных выяснилось:</h4></ul>\n",
    "    <li>признаки bedrooms, bathrooms, waterfront, view, sqft_basement и yr_renovated имеют в себе нулевые поля, что может создать смещение если искать по этим полям</li>\n",
    "    <li>признаки bedrooms, bathrooms и price имеют аномально высокие значения, и это указывает на наличие выбросов</li>\n",
    "    <li>признаки waterfront, view, condition имеют низкие значения дисперсии, что может привести к снижению значимости этих признаков</li>\n",
    "    <li>признак yr_built варьируется от 1900 до 2015. Это может быть актуальной информацией для анализа старых зданий, но актуальность данных по ремонту и реконструкции (это призгак yr_renovated) может быть ниже, так как 0 указывает на отсутствие ремонта</li>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<ol><h3>Примеры решения проблем для набора данных</h3></ol>\n",
    "    <li>Удаление выбросов на основе значения или bathrooms > 5</li>\n",
    "    <li>Замена 0 на год постройки (это признак yr_built), если дом не подвергался ремонту</li>\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3>Оценка качества данных</h3>\n",
    "1. Информативность. Набор данных предоставляет достаточную информацию для анализа цен на недвижимость.\n",
    "2. Степень покрытия. Набор данных затрагивает только один райно, не включая информацию о других райнов.\n",
    "3. Соответствие реальным данным. Данные вполне кажутся реальными, не считая некоторых редких выбросов.\n",
    "4. Согласованность меток. Метки состояние и оценка вида, имеют четкие значения."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3>Разбиение данных на обучающую, контрольную и тестовую выборки</h3>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 267,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Исходный размер строк: 21613 строк\n",
      "Размер обучающей выборки: 15129 строк\n",
      "Размер валидационной выборки: 3242 строк\n",
      "Размер тестовой выборки: 3242 строк\n"
     ]
    }
   ],
   "source": [
    "df_numeric = df.select_dtypes(include='number')\n",
    "\n",
    "x = df_numeric.drop(['price'], axis=1)\n",
    "y = df_numeric['price']\n",
    "\n",
    "x_train, x_temp, y_train, y_temp = train_test_split(x, y, test_size=0.3, random_state=14)\n",
    "\n",
    "x_val, x_test, y_val, y_test = train_test_split(x_temp, y_temp, test_size=0.5, random_state=14)\n",
    "\n",
    "print(f\"Исходный размер строк: {df_numeric.shape[0]} строк\")\n",
    "print(f\"Размер обучающей выборки: {x_train.shape[0]} строк\")\n",
    "print(f\"Размер валидационной выборки: {x_val.shape[0]} строк\")\n",
    "print(f\"Размер тестовой выборки: {x_test.shape[0]} строк\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 268,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 54040 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 52172 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 51712 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Статистические показатели для обучающей выборки:\n",
      "Среднее значение: 13.05\n",
      "Стандартное отклонение: 0.52\n",
      "Минимальное значение: 11.23\n",
      "Максимальное значение: 15.86\n",
      "Количество наблюдений: 15129\n",
      "\n",
      "Статистические показатели для валидационной выборки:\n",
      "Среднее значение: 13.05\n",
      "Стандартное отклонение: 0.53\n",
      "Минимальное значение: 11.26\n",
      "Максимальное значение: 15.49\n",
      "Количество наблюдений: 3242\n",
      "\n",
      "Статистические показатели для тестовой выборки:\n",
      "Среднее значение: 13.06\n",
      "Стандартное отклонение: 0.54\n",
      "Минимальное значение: 11.35\n",
      "Максимальное значение: 15.53\n",
      "Количество наблюдений: 3242\n",
      "\n"
     ]
    }
   ],
   "source": [
    "import seaborn as sns\n",
    "\n",
    "df['price_log'] = np.log(df['price'])\n",
    "\n",
    "X = df.drop(['price', 'price_log'], axis=1)\n",
    "y = df['price_log']\n",
    "\n",
    "X = X.select_dtypes(include='number')\n",
    "\n",
    "X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.3, random_state=42)\n",
    "\n",
    "X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)\n",
    "def plot_distribution(data, title):\n",
    "    \"\"\"Построение гистограммы распределения целевого признака\"\"\"\n",
    "    plt.figure(figsize=(10, 6))\n",
    "    sns.histplot(data, kde=True, bins=30, color='skyblue')\n",
    "    plt.title(title)\n",
    "    plt.xlabel('Logarithm of Price')\n",
    "    plt.ylabel('Count')\n",
    "    plt.grid(True)\n",
    "    plt.show()\n",
    "\n",
    "plot_distribution(y_train, 'Распределение логарифма цены в обучающей выборке')\n",
    "plot_distribution(y_val, 'Распределение логарифма цены в валидационной выборке')\n",
    "plot_distribution(y_test, 'Распределение логарифма цены в тестовой выборке')\n",
    "\n",
    "def get_statistics(df, name):\n",
    "    print(f\"Статистические показатели для {name} выборки:\")\n",
    "    print(f\"Среднее значение: {df.mean():.2f}\")\n",
    "    print(f\"Стандартное отклонение: {df.std():.2f}\")\n",
    "    print(f\"Минимальное значение: {df.min():.2f}\")\n",
    "    print(f\"Максимальное значение: {df.max():.2f}\")\n",
    "    print(f\"Количество наблюдений: {df.count()}\\n\")\n",
    "\n",
    "get_statistics(y_train, \"обучающей\")\n",
    "\n",
    "get_statistics(y_val, \"валидационной\")\n",
    "\n",
    "get_statistics(y_test, \"тестовой\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3>Oversampling и undersampling</h3>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 269,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Распределение классов после SMOTE (oversampling):\n",
      "price_category\n",
      "0    3054\n",
      "1    3054\n",
      "2    3054\n",
      "3    3054\n",
      "4    3054\n",
      "Name: count, dtype: int64\n",
      "Распределение классов после RandomUnderSampler (undersampling):\n",
      "price_category\n",
      "0    2993\n",
      "1    2993\n",
      "2    2993\n",
      "3    2993\n",
      "4    2993\n",
      "Name: count, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "from imblearn.over_sampling import SMOTE\n",
    "from imblearn.under_sampling import RandomUnderSampler\n",
    "\n",
    "\n",
    "if 'date' in df.columns:\n",
    "    df['year'] = pd.to_datetime(df['date'], errors='coerce').dt.year\n",
    "    df = df.drop(['date'], axis=1)\n",
    "\n",
    "df['price_log'] = np.log(df['price'])\n",
    "\n",
    "df['price_category'] = pd.qcut(df['price_log'], q=5, labels=[0, 1, 2, 3, 4])\n",
    "\n",
    "X = df.drop(['price', 'price_log', 'price_category'], axis=1)\n",
    "y = df['price_category']\n",
    "\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)\n",
    "\n",
    "smote = SMOTE(random_state=42)\n",
    "X_train_smote, y_train_smote = smote.fit_resample(X_train, y_train)\n",
    "\n",
    "print(\"Распределение классов после SMOTE (oversampling):\")\n",
    "print(pd.Series(y_train_smote).value_counts())\n",
    "\n",
    "undersampler = RandomUnderSampler(random_state=42)\n",
    "X_train_under, y_train_under = undersampler.fit_resample(X_train, y_train)\n",
    "\n",
    "print(\"Распределение классов после RandomUnderSampler (undersampling):\")\n",
    "print(pd.Series(y_train_under).value_counts())\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3>Оценка сбалансированности выборок</h3>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Оценка необходимости аугментации данных\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'y_train' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[1], line 18\u001b[0m\n\u001b[0;32m     15\u001b[0m     \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m     16\u001b[0m         \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mВыборка \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mname\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m сбалансирована, аугментация не требуется.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m---> 18\u001b[0m check_augmentation_need(\u001b[43my_train\u001b[49m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mобучающей\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m     19\u001b[0m check_augmentation_need(y_val, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mвалидационной\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m     20\u001b[0m check_augmentation_need(y_test, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mтестовой\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
      "\u001b[1;31mNameError\u001b[0m: name 'y_train' is not defined"
     ]
    }
   ],
   "source": [
    "def check_augmentation_need(data, name):\n",
    "    \"\"\"Проверка необходимости аугментации данных\"\"\"\n",
    "    quantiles = data.quantile([0.25, 0.5, 0.75])\n",
    "    mean = data.mean()\n",
    "    std = data.std()\n",
    "    \n",
    "    print(f\"Проверка необходимости аугментации для {name} выборки:\")\n",
    "    print(f\"Среднее значение: {mean:.2f}, Стандартное отклонение: {std:.2f}\")\n",
    "    print(f\"25-й квантиль: {quantiles[0.25]:.2f}\")\n",
    "    print(f\"50-й квантиль (медиана): {quantiles[0.5]:.2f}\")\n",
    "    print(f\"75-й квантиль: {quantiles[0.75]:.2f}\")\n",
    "    \n",
    "    if std > mean * 0.5:\n",
    "        print(f\"Выборка {name} несбалансирована, рекомендуется аугментация.\\n\")\n",
    "    else:\n",
    "        print(f\"Выборка {name} сбалансирована, аугментация не требуется.\\n\")\n",
    "\n",
    "check_augmentation_need(y_train, \"обучающей\")\n",
    "check_augmentation_need(y_val, \"валидационной\")\n",
    "check_augmentation_need(y_test, \"тестовой\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Поскольку все выборки демонстрируют одинаковое распределение целевого признака и сбалансированное распределение значений, применение методов аугментации не требуется."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 192,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Распределение 'condition' в обучающей выборке:\n",
      " condition\n",
      "3    9837\n",
      "4    3958\n",
      "5    1189\n",
      "2     121\n",
      "1      24\n",
      "Name: count, dtype: int64\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\salih\\AppData\\Local\\Temp\\ipykernel_8140\\3337968062.py:11: FutureWarning: \n",
      "\n",
      "Passing `palette` without assigning `hue` is deprecated and will be removed in v0.14.0. Assign the `x` variable to `hue` and set `legend=False` for the same effect.\n",
      "\n",
      "  sns.barplot(x=condition_counts.index, y=condition_counts.values, palette='viridis')\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 29156 characters]",
      "text/plain": [
       "<Figure size 800x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Распределение 'condition' в валидационной выборке:\n",
      " condition\n",
      "3    2125\n",
      "4     830\n",
      "5     256\n",
      "2      27\n",
      "1       4\n",
      "Name: count, dtype: int64\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\salih\\AppData\\Local\\Temp\\ipykernel_8140\\3337968062.py:11: FutureWarning: \n",
      "\n",
      "Passing `palette` without assigning `hue` is deprecated and will be removed in v0.14.0. Assign the `x` variable to `hue` and set `legend=False` for the same effect.\n",
      "\n",
      "  sns.barplot(x=condition_counts.index, y=condition_counts.values, palette='viridis')\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 31892 characters]",
      "text/plain": [
       "<Figure size 800x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Распределение 'condition' в тестовой выборке:\n",
      " condition\n",
      "3    2069\n",
      "4     891\n",
      "5     256\n",
      "2      24\n",
      "1       2\n",
      "Name: count, dtype: int64\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\salih\\AppData\\Local\\Temp\\ipykernel_8140\\3337968062.py:11: FutureWarning: \n",
      "\n",
      "Passing `palette` without assigning `hue` is deprecated and will be removed in v0.14.0. Assign the `x` variable to `hue` and set `legend=False` for the same effect.\n",
      "\n",
      "  sns.barplot(x=condition_counts.index, y=condition_counts.values, palette='viridis')\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 31280 characters]",
      "text/plain": [
       "<Figure size 800x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Проверка необходимости аугментации для признака 'condition' в обучающей выборке:\n",
      "Минимальное количество наблюдений в классе: 24\n",
      "Максимальное количество наблюдений в классе: 9837\n",
      "Выборка 'обучающей' несбалансирована, рекомендуется аугментация.\n",
      "\n",
      "Проверка необходимости аугментации для признака 'condition' в валидационной выборке:\n",
      "Минимальное количество наблюдений в классе: 4\n",
      "Максимальное количество наблюдений в классе: 2125\n",
      "Выборка 'валидационной' несбалансирована, рекомендуется аугментация.\n",
      "\n",
      "Проверка необходимости аугментации для признака 'condition' в тестовой выборке:\n",
      "Минимальное количество наблюдений в классе: 2\n",
      "Максимальное количество наблюдений в классе: 2069\n",
      "Выборка 'тестовой' несбалансирована, рекомендуется аугментация.\n",
      "\n",
      "Распределение классов после SMOTE (oversampling):\n",
      "condition\n",
      "3    9837\n",
      "5    9837\n",
      "4    9837\n",
      "2    9837\n",
      "1    9837\n",
      "Name: count, dtype: int64\n",
      "Распределение классов после RandomUnderSampler (undersampling):\n",
      "condition\n",
      "1    24\n",
      "2    24\n",
      "3    24\n",
      "4    24\n",
      "5    24\n",
      "Name: count, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "if 'condition' in df.columns:\n",
    "    X_train, X_temp, y_train, y_temp = train_test_split(df.drop(['price'], axis=1), df['condition'], test_size=0.3, random_state=42)\n",
    "    X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)\n",
    "\n",
    "    def analyze_condition_distribution(data, name):\n",
    "        \"\"\"Проверка и визуализация распределения признака 'condition'\"\"\"\n",
    "        condition_counts = data.value_counts()\n",
    "        print(f\"Распределение 'condition' в {name} выборке:\\n\", condition_counts)\n",
    "        \n",
    "        plt.figure(figsize=(8, 6))\n",
    "        sns.barplot(x=condition_counts.index, y=condition_counts.values, palette='viridis')\n",
    "        plt.title(f\"Распределение признака 'condition' в {name} выборке\")\n",
    "        plt.xlabel('Condition')\n",
    "        plt.ylabel('Count')\n",
    "        plt.grid(True)\n",
    "        plt.show()\n",
    "\n",
    "    analyze_condition_distribution(y_train, 'обучающей')\n",
    "    analyze_condition_distribution(y_val, 'валидационной')\n",
    "    analyze_condition_distribution(y_test, 'тестовой')\n",
    "\n",
    "    def check_condition_augmentation(data, name):\n",
    "        print(f\"Проверка необходимости аугментации для признака 'condition' в {name} выборке:\")\n",
    "        min_count = data.value_counts().min()\n",
    "        max_count = data.value_counts().max()\n",
    "        print(f\"Минимальное количество наблюдений в классе: {min_count}\")\n",
    "        print(f\"Максимальное количество наблюдений в классе: {max_count}\")\n",
    "        \n",
    "        if max_count > min_count * 1.5:\n",
    "            print(f\"Выборка '{name}' несбалансирована, рекомендуется аугментация.\\n\")\n",
    "        else:\n",
    "            print(f\"Выборка '{name}' сбалансирована, аугментация не требуется.\\n\")\n",
    "\n",
    "    check_condition_augmentation(y_train, 'обучающей')\n",
    "    check_condition_augmentation(y_val, 'валидационной')\n",
    "    check_condition_augmentation(y_test, 'тестовой')\n",
    "else:\n",
    "    print(\"Признак 'condition' отсутствует в данных.\")\n",
    "\n",
    "smote = SMOTE(random_state=42)\n",
    "X_train_smote, y_train_smote = smote.fit_resample(X_train, y_train)\n",
    "\n",
    "print(\"Распределение классов после SMOTE (oversampling):\")\n",
    "print(pd.Series(y_train_smote).value_counts())\n",
    "\n",
    "undersampler = RandomUnderSampler(random_state=42)\n",
    "X_train_under, y_train_under = undersampler.fit_resample(X_train, y_train)\n",
    "\n",
    "print(\"Распределение классов после RandomUnderSampler (undersampling):\")\n",
    "print(pd.Series(y_train_under).value_counts())\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "В этом исследование данные не сбалансированы, поэтому требуется аугментация."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2>Данные о населении</h2>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   Country (or dependency) Population 2020 Yearly Change  Net Change  \\\n",
      "no                                                                     \n",
      "1                    China   1,439,323,776         0.39%   5,540,090   \n",
      "2                    India   1,380,004,385         0.99%  13,586,631   \n",
      "3            United States     331,002,651         0.59%   1,937,734   \n",
      "4                Indonesia     273,523,615         1.07%   2,898,047   \n",
      "5                 Pakistan     220,892,340         2.00%   4,327,022   \n",
      "\n",
      "   Density  (P/Km²) Land Area (Km²) Migrants (net) Fert. Rate Med. Age  \\\n",
      "no                                                                       \n",
      "1               153       9,388,211       -348,399        1.7       38   \n",
      "2               464       2,973,190       -532,687        2.2       28   \n",
      "3                36       9,147,420        954,806        1.8       38   \n",
      "4               151       1,811,570        -98,955        2.3       30   \n",
      "5               287         770,880       -233,379        3.6       23   \n",
      "\n",
      "   Urban Pop % World Share  \n",
      "no                          \n",
      "1          61%      18.47%  \n",
      "2          35%      17.70%  \n",
      "3          83%       4.25%  \n",
      "4          56%       3.51%  \n",
      "5          35%       2.83%   \n",
      "\n",
      "Country (or dependency)\n",
      "Population 2020\n",
      "Yearly Change\n",
      "Net Change\n",
      "Density  (P/Km²)\n",
      "Land Area (Km²)\n",
      "Migrants (net)\n",
      "Fert. Rate\n",
      "Med. Age\n",
      "Urban Pop %\n",
      "World Share\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd \n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "df2 = pd.read_csv(\"..//static//csv//WorldPopulation.csv\", index_col=\"no\")\n",
    "\n",
    "print(df2.head(), \"\\n\")\n",
    "print(*list(df2.columns), sep='\\n')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Объектом наблюдения является страны и информация о их наслении.<br>\n",
    "Атрибуты объекта: Страна, Население, Годовое изменение, NetChange, Плотность, Площадь суши, Мигранты, Fert.Rate, Средний возраст, UrbanPop%, Доля в мире;<br>\n",
    "Связь между объектами: имеется связь между атрибутами, например между Коэффициент фертильности и Плотностю населения.<br>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\salih\\AppData\\Local\\Temp\\ipykernel_13360\\2445382032.py:10: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  df_clean['Density  (P/Km²)'] = pd.cut(df2['Density  (P/Km²)'], bins=range(0, 1000, 100))\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 48724 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "df2['Fert. Rate'] = pd.to_numeric(df2['Fert. Rate'], errors='coerce')\n",
    "\n",
    "\n",
    "df2['Fert. Rate'] = pd.to_numeric(df2['Fert. Rate'], errors='coerce')\n",
    "\n",
    "df_clean = df2.dropna(subset=['Fert. Rate', 'Density  (P/Km²)'])\n",
    "    \n",
    "## correlation = df_clean[['Density  (P/Km²)', 'Fert. Rate']].corr().iloc[0, 1] ## использовать только один раз потом удалить\n",
    "\n",
    "df_clean['Density  (P/Km²)'] = pd.cut(df2['Density  (P/Km²)'], bins=range(0, 1000, 100))\n",
    "plt.figure(figsize=(10, 6))\n",
    "sns.boxplot(data=df_clean, x='Density  (P/Km²)', y='Fert. Rate')\n",
    "plt.title('Распределение уровня рождаемости по плотности населения')\n",
    "plt.xlabel('Плотность (чел./км²)')\n",
    "plt.ylabel('Уровень рождаемости')\n",
    "plt.xticks(rotation=45)\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "В регионах с низкой плотностью населения рождаемость значительно варьируется, в то время как в регионах с плотностью более 400 чел./км² наблюдается более стабильная и высокая рождаемость."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3>Бизнес-цели</h3>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. **Бизнес-цель**: Определение наилучших стран для выхода на рынок товаров и услуг, связанных с материнством и детством.<br>\n",
    "    Эффект для бизнеса: Возможность выбора стран с высоким уровнем рождаемости и значительным числом молодых семей для запуска маркетинговых кампаний и открытия новых филиалов.\n",
    "- **Цели технического проекта**:\n",
    "  - Построить модель для определения стран с высоким потенциалом развития рынка товаров для детей и матерей.\n",
    "  - **Входные признаки**: Плотность населения, Уровень рождаемости, Средний возраст, Доля городского населения.\n",
    "  - **Целевой признак**: Страна с высоким или низким потенциалом для выхода на рынок.\n",
    "2. **Бизнес-цель**: Оптимизация стратегий миграционной политики.\n",
    "    Эффект для бизнеса: Компании, предоставляющие услуги в области миграции, найма и адаптации, могут использовать эти данные для выбора мест, где их услуги будут наиболее востребованы.\n",
    "- **Цели технического проекта**:\n",
    "  - Построить модель, определяющую страны с наибольшим оттоком мигрантов и прогнозировать влияние миграции на рынок труда.\n",
    "  - **Входные признаки**: Годовое изменение населения, Плотность населения, Доля городского населения.\n",
    "  - **Целевой признак**: Уровень чистой миграции.\n",
    "3. **Бизнес-цель**: Определение экономического потенциала стран на основе плотности населения и уровня урбанизации.\n",
    "    Эффект для бизнеса: Компании могут определить страны с высоким уровнем урбанизации и значительной плотностью населения для открытия новых офисов, производств или филиалов.\n",
    "- **Цели технического проекта**:\n",
    "  - Создать модель для ранжирования стран по их экономическому потенциалу на основе демографических данных.\n",
    "  - **Входные признаки**: Плотность населения, Уровень урбанизации, Средний возраст, Доля городского населения.\n",
    "  - **Целевой признак**: Оценка экономического потенциала."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**<h3>Поиск проблем</h3>**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 145,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Количество пропущеных ячеек: \n",
      " Country (or dependency)     0\n",
      "Population 2020             0\n",
      "Yearly Change               0\n",
      "Net Change                  0\n",
      "Density  (P/Km²)           12\n",
      "Land Area (Km²)             0\n",
      "Migrants (net)             34\n",
      "Fert. Rate                 34\n",
      "Med. Age                   34\n",
      "Urban Pop %                13\n",
      "World Share                 0\n",
      "dtype: int64\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 29072 characters]",
      "text/plain": [
       "<Figure size 1200x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Количество выбросов (по Z-оценке): 7\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 70656 characters]",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from scipy import stats\n",
    "\n",
    "missing_val = df2.isnull().sum()\n",
    "print(\"Количество пропущеных ячеек: \\n\", missing_val)\n",
    "\n",
    "df2['Population 2020'] = pd.to_numeric(df2['Population 2020'].astype(str).str.replace(',', ''), errors='coerce')\n",
    "df2['Density  (P/Km²)'] = pd.to_numeric(df2['Density  (P/Km²)'].astype(str).str.replace(',', ''), errors='coerce')\n",
    "df2['Fert. Rate'] = pd.to_numeric(df2['Fert. Rate'], errors='coerce')\n",
    "df2['Med. Age'] = pd.to_numeric(df2['Med. Age'], errors='coerce')\n",
    "df2['Urban Pop %'] = pd.to_numeric(df2['Urban Pop %'].astype(str).str.replace('%', ''), errors='coerce')\n",
    "df2['World Share'] = pd.to_numeric(df2['World Share'].astype(str).str.replace('%', ''), errors='coerce')\n",
    "\n",
    "# Удаление пропусков для корректного анализа\n",
    "data = df2.dropna()\n",
    "\n",
    "# 1. Визуализация распределения данных (помогает выявить выбросы)\n",
    "plt.figure(figsize=(12, 6))\n",
    "sns.boxplot(data=data[['Fert. Rate', 'Density  (P/Km²)', 'Med. Age']])\n",
    "plt.title('Поиск выбросов с помощью Boxplot')\n",
    "plt.show()\n",
    "\n",
    "z_scrore = np.abs(stats.zscore(data[['Fert. Rate', 'Density  (P/Km²)', 'Med. Age', 'Urban Pop %', 'World Share']]))\n",
    "outliers = np.where(z_scrore > 3)\n",
    "print(f\"Количество выбросов (по Z-оценке): {len(outliers[0])}\")\n",
    "\n",
    "# Построение корреляционной матрицы для поиска зашумленности\n",
    "corr_matrix = data[['Population 2020', 'Density  (P/Km²)', 'Fert. Rate', 'Med. Age', 'Urban Pop %', 'World Share']].corr()\n",
    "sns.heatmap(corr_matrix, annot=True, cmap='coolwarm')\n",
    "plt.title('Корреляционная матрица')\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Из матрицы корреляции можно сделать выводы отностительно зависимости между атрибутами и выявит наиболее бесполезные их них. Признаки с низкими корреляциями, такие как Density (P/Km²), Population 2020, и World Share, могут содержать шум или не являться значимыми для текущей задачи демографического анализа. Это не обязательно означает, что эти переменные всегда шумны, но в контексте анализа они могут оказаться несущественными."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Проведем анализа остаточных ошибок, чтобы убедиться в том, что выше упомянутые атрибуты действиельно бесполезны в данном контексе."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "По итогу вышло больше количество шумов"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 37876 characters]",
      "text/plain": [
       "<Figure size 1200x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Среднее значение населения: 39877695.56842105\n",
      "Медиана населения: 8976711.0\n"
     ]
    }
   ],
   "source": [
    "plt.figure(figsize=(12, 6))\n",
    "sns.histplot(data=data['Population 2020'], kde=True, bins=30)\n",
    "plt.title('Распределение населения по странам в 2020 году')\n",
    "plt.xlabel('Население')\n",
    "plt.ylabel('Количество стран')\n",
    "plt.show()\n",
    "\n",
    "mean_population = data['Population 2020'].mean()\n",
    "median_population = data['Population 2020'].median()\n",
    "print(f\"Среднее значение населения: {mean_population}\")\n",
    "print(f\"Медиана населения: {median_population}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Определяем смещение. Если разница между средним и медианным значениями существенна, это может указывать на смещение. В данном случаем имеется смещение."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Просачивания данных в столбце 'Net Change' не обнаружено.\n",
      "Просачивания данных в столбце 'Migrants (net)' не обнаружено.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\salih\\AppData\\Local\\Temp\\ipykernel_13360\\2903715557.py:2: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  data['Net Change'] = pd.to_numeric(data['Net Change'].astype(str).str.replace(',', ''), errors='coerce')\n",
      "C:\\Users\\salih\\AppData\\Local\\Temp\\ipykernel_13360\\2903715557.py:3: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  data['Migrants (net)'] = pd.to_numeric(data['Migrants (net)'].astype(str).str.replace(',', ''), errors='coerce')\n",
      "C:\\Users\\salih\\AppData\\Local\\Temp\\ipykernel_13360\\2903715557.py:4: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  data['Population 2020'] = pd.to_numeric(data['Population 2020'].astype(str).str.replace(',', ''), errors='coerce')\n"
     ]
    }
   ],
   "source": [
    "# Приведение столбцов к числовым значениям\n",
    "data['Net Change'] = pd.to_numeric(data['Net Change'].astype(str).str.replace(',', ''), errors='coerce')\n",
    "data['Migrants (net)'] = pd.to_numeric(data['Migrants (net)'].astype(str).str.replace(',', ''), errors='coerce')\n",
    "data['Population 2020'] = pd.to_numeric(data['Population 2020'].astype(str).str.replace(',', ''), errors='coerce')\n",
    "\n",
    "invalid_net_change = data[data['Net Change'] > data['Population 2020']]\n",
    "invalid_migrants = data[data['Migrants (net)'] > data['Population 2020']]\n",
    "\n",
    "if not invalid_net_change.empty:\n",
    "    print(\"Просачивание данных: Прирост населения превышает текущее население в следующих строках:\")\n",
    "    print(invalid_net_change)\n",
    "else:\n",
    "    print(\"Просачивания данных в столбце 'Net Change' не обнаружено.\")\n",
    "\n",
    "if not invalid_migrants.empty:\n",
    "    print(\"Просачивание данных: Мигранты превышают текущее население в следующих строках:\")\n",
    "    print(invalid_migrants)\n",
    "else:\n",
    "    print(\"Просачивания данных в столбце 'Migrants (net)' не обнаружено.\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Тут я хочу выявить просачивание данных. Для этого хочу сравнить прирост населения и количество мигрантов с численности населения в 2020 году. Логично, если они окажутся больше общий численности населения это окажется странным. В данном случае все оказалось нормально и не какие данные не просачились."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 155,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Размер данных после удаления выбросов: (183, 11)\n",
      "Обрабатываем столбец: Fert. Rate, медианное значение: 2.3\n",
      "Обрабатываем столбец: Density  (P/Km²), медианное значение: 83.0\n",
      "Обрабатываем столбец: Med. Age, медианное значение: 30.0\n",
      "Обрабатываем столбец: Urban Pop %, медианное значение: 60.0\n",
      "Обрабатываем столбец: World Share, медианное значение: 0.11499999999999999\n",
      "Выбросы заменены медианными значениями.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\salih\\AppData\\Local\\Temp\\ipykernel_13360\\3365745342.py:18: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  data[column] = np.where(col_z_score > 3, median_value, data[column])\n",
      "C:\\Users\\salih\\AppData\\Local\\Temp\\ipykernel_13360\\3365745342.py:18: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  data[column] = np.where(col_z_score > 3, median_value, data[column])\n",
      "C:\\Users\\salih\\AppData\\Local\\Temp\\ipykernel_13360\\3365745342.py:18: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  data[column] = np.where(col_z_score > 3, median_value, data[column])\n",
      "C:\\Users\\salih\\AppData\\Local\\Temp\\ipykernel_13360\\3365745342.py:18: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  data[column] = np.where(col_z_score > 3, median_value, data[column])\n",
      "C:\\Users\\salih\\AppData\\Local\\Temp\\ipykernel_13360\\3365745342.py:18: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  data[column] = np.where(col_z_score > 3, median_value, data[column])\n"
     ]
    }
   ],
   "source": [
    "data_no_outliers = data[(z_scores < 3).all(axis=1)]\n",
    "print(f\"Размер данных после удаления выбросов: {data_no_outliers.shape}\")\n",
    "\n",
    "columns_to_check = ['Fert. Rate', 'Density  (P/Km²)', 'Med. Age', 'Urban Pop %', 'World Share']\n",
    "\n",
    "for column in columns_to_check:\n",
    "    col_z_score = np.abs(stats.zscore(data[column]))\n",
    "    \n",
    "    median_value = data[column].median()\n",
    "    \n",
    "    print(f\"Обрабатываем столбец: {column}, медианное значение: {median_value}\")\n",
    "    \n",
    "    data[column] = np.where(col_z_score > 3, median_value, data[column])\n",
    "\n",
    "print(\"Выбросы заменены медианными значениями.\")\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Решили проблему с выбрасами "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3>Оценка качества набора данных:</h3>\n",
    "\n",
    "**Информативность:** Набор данных содержит информацию о населении стран мира на 2020 год, включая демографические показатели, такие как плотность населения, прирост населения, уровень урбанизации и другие. Колонки достаточно подробные и содержат ключевые метрики.\n",
    "\n",
    "**Степень покрытия:** В наборе данных представлены 235 стран и зависимых территорий, что охватывает практически весь мир. Это достаточно полный охват для анализа глобального населения.\n",
    "\n",
    "**Соответствие реальным данным:** Данные взяты из показателей 2020 года.\n",
    "\n",
    "**Согласованность меток:** Имена колонок не всегда очевидны (например, \"Density (P/Km²)\", \"World Share\"). Также данные представлены в разных форматах, что требует предобработки, так как числовые значения сохранены как строки."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3>Устранение проблемы пропущенных данных</h3>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 162,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Данные после заполнения средним значением: 0 пропущенных значений осталось\n"
     ]
    }
   ],
   "source": [
    "data_filled_mean = data.copy()\n",
    "\n",
    "data_filled_mean[\"Migrants (net)\"] = pd.to_numeric(data_filled_mean[\"Migrants (net)\"], errors='coerce')\n",
    "\n",
    "mean_value = data_filled_mean[\"Migrants (net)\"].mean()\n",
    "data_filled_mean[\"Migrants (net)\"] = data_filled_mean[\"Migrants (net)\"].fillna(mean_value)\n",
    "print(f\"Данные после заполнения средним значением: {data_filled_mean['Migrants (net)'].isnull().sum()} пропущенных значений осталось\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 167,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Обучающая выборка: 114 строк\n",
      "Валидационная выборка: 38 строк\n",
      "Тестовая выборка: 38 строк\n"
     ]
    }
   ],
   "source": [
    "columns_to_drop = [\"Population 2020\", \"no\", \"Country (or dependency)\"]\n",
    "columns_to_drop = [col for col in columns_to_drop if col in data_filled_mean.columns]\n",
    "\n",
    "X = data_filled_mean.drop(columns=columns_to_drop)\n",
    "y = data_filled_mean[\"Population 2020\"]\n",
    "\n",
    "X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.4, random_state=42)\n",
    "X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)\n",
    "\n",
    "print(f\"Обучающая выборка: {X_train.shape[0]} строк\")\n",
    "print(f\"Валидационная выборка: {X_val.shape[0]} строк\")\n",
    "print(f\"Тестовая выборка: {X_test.shape[0]} строк\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 168,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Распределение в обучающей выборке:\n",
      " count    1.140000e+02\n",
      "mean     4.809021e+07\n",
      "std      1.880257e+08\n",
      "min      9.792900e+04\n",
      "25%      1.400362e+06\n",
      "50%      9.272022e+06\n",
      "75%      2.615868e+07\n",
      "max      1.439324e+09\n",
      "Name: Population 2020, dtype: float64\n",
      "Распределение в валидационной выборке:\n",
      " count    3.800000e+01\n",
      "mean     2.704393e+07\n",
      "std      4.201158e+07\n",
      "min      1.640930e+05\n",
      "25%      4.895855e+06\n",
      "50%      1.052552e+07\n",
      "75%      3.117359e+07\n",
      "max      2.125594e+08\n",
      "Name: Population 2020, dtype: float64\n",
      "Распределение в тестовой выборке:\n",
      " count    3.800000e+01\n",
      "mean     2.807392e+07\n",
      "std      5.746454e+07\n",
      "min      1.067660e+05\n",
      "25%      9.193338e+05\n",
      "50%      5.568913e+06\n",
      "75%      3.241794e+07\n",
      "max      3.310027e+08\n",
      "Name: Population 2020, dtype: float64\n"
     ]
    }
   ],
   "source": [
    "# Проверка распределения целевой переменной в обучающей, валидационной и тестовой выборках\n",
    "print(\"Распределение в обучающей выборке:\\n\", y_train.describe())\n",
    "print(\"Распределение в валидационной выборке:\\n\", y_val.describe())\n",
    "print(\"Распределение в тестовой выборке:\\n\", y_test.describe())\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Дисбаланс данных:\n",
    "\n",
    "В обучающей выборке среднее значение численности населения составляет около 48 миллионов, однако максимальное значение достигает 1.44 миллиарда, что указывает на значительный разброс данных.\n",
    "Стандартное отклонение в обучающей выборке очень велико (188 миллионов), что указывает на присутствие значительного числа стран с огромным населением (например, Китай и Индия), наряду с малонаселёнными странами.\n",
    "В валидационной и тестовой выборках также наблюдается высокий разброс, хотя их максимальные значения намного ниже (212 и 331 миллионов соответственно)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Методы приращения данных могут быть полезный, поэтому я ими воспользуюсь"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 172,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Размер обучающей выборки после Oversampling: 114 строк\n",
      "Размер обучающей выборки после Undersampling: 114 строк\n"
     ]
    }
   ],
   "source": [
    "from imblearn.over_sampling import RandomOverSampler\n",
    "from imblearn.under_sampling import RandomUnderSampler\n",
    "\n",
    "# Oversampling (увеличение выборки) для обучающих данных\n",
    "ros = RandomOverSampler(random_state=42)\n",
    "X_train_res, y_train_res = ros.fit_resample(X_train, y_train)\n",
    "print(f\"Размер обучающей выборки после Oversampling: {X_train_res.shape[0]} строк\")\n",
    "\n",
    "# Undersampling (уменьшение выборки) для обучающих данных\n",
    "rus = RandomUnderSampler(random_state=42)\n",
    "X_train_res_under, y_train_res_under = rus.fit_resample(X_train, y_train)\n",
    "print(f\"Размер обучающей выборки после Undersampling: {X_train_res_under.shape[0]} строк\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h1>3 Датасет - Данные о миллионерах</h1>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 189,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Index(['Name', 'Networth', 'Age', 'Country', 'Source', 'Industry'], dtype='object') \n",
      "\n"
     ]
    }
   ],
   "source": [
    "df3 = pd.read_csv(\"..//static//csv//Forbes Billionaires.csv\", index_col=\"Rank \")\n",
    "\n",
    "print(df3.columns, \"\\n\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Основные столбцы:</br>\n",
    "**Rank:** Ранг миллиардера</br>\n",
    "**Name:** Имя миллиардера</br>\n",
    "**Networth:** Состояние миллиардера (в миллиардах долларов)</br>\n",
    "**Age:** Возраст миллиардера</br>\n",
    "**Country:** Страна проживания миллиардера</br>\n",
    "**Source:** Основной источник дохода</br>\n",
    "**Industry:** Отрасль, к которой относится основная деятельность миллиардера</br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2>Проблемная область<h2>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Данный набор данных относится к анализу благосостояния, его распределению по возрастам, странам и отраслям. Проблемная область связана с миллионерами и с изучением неравенства богатства, выявлением тенденций в источниках доходов и влиянии различных факторов на накопление капитала."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3> Анализ содержимого<h3>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **Объекты наблюдения:** Миллиардеры\n",
    "- **Атрибуты объектов:** Ранг, имя, состояние, возраст, страна, источник дохода, отрасль\n",
    "- **Связи между объектами:** Можно выявить связи между возрастом и состоянием, страной проживания и источником дохода, а также отраслью и уровнем благосостояния."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 206,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 144464 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 4 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import seaborn as sns\n",
    "\n",
    "plt.figure(figsize=(10, 6))\n",
    "\n",
    "# Связь между возрастом и состоянием\n",
    "plt.subplot(2, 2, 1)\n",
    "sns.scatterplot(data=df3, x='Age', y='Networth')\n",
    "plt.title('Связь между возрастом и состоянием')\n",
    "plt.xlabel('Возраст')\n",
    "plt.ylabel('Состояние (млрд)')\n",
    "\n",
    "# Связь между страной проживания и состоянием (топ-10 стран)\n",
    "plt.subplot(2, 2, 2)\n",
    "top_countries = df3['Country'].value_counts().index[:10]\n",
    "sns.boxplot(data=df3[df3['Country'].isin(top_countries)], x='Country', y='Networth')\n",
    "plt.title('Связь между страной проживания и состоянием')\n",
    "plt.xticks(rotation=90)\n",
    "plt.xlabel('Страна')\n",
    "plt.ylabel('Состояние (млрд)')\n",
    "\n",
    "# Связь между источником дохода и состоянием (топ-10 источников дохода)\n",
    "plt.subplot(2, 2, 3)\n",
    "top_sources = df3['Source'].value_counts().index[:10]\n",
    "sns.boxplot(data=df3[df3['Source'].isin(top_sources)], x='Source', y='Networth')\n",
    "plt.title('Связь между источником дохода и состоянием')\n",
    "plt.xticks(rotation=90)\n",
    "plt.xlabel('Источник дохода')\n",
    "plt.ylabel('Состояние (млрд)')\n",
    "\n",
    "# Связь между отраслью и состоянием (топ-10 отраслей)\n",
    "plt.subplot(2, 2, 4)\n",
    "top_industries = df3['Industry'].value_counts().index[:10]\n",
    "sns.boxplot(data=df3[df3['Industry'].isin(top_industries)], x='Industry', y='Networth')\n",
    "plt.title('Связь между отраслью и состоянием')\n",
    "plt.xticks(rotation=90)\n",
    "plt.xlabel('Отрасль')\n",
    "plt.ylabel('Состояние (млрд)')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Тут для наглядности вывел графики зависимостей"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3>Примеры бизнес-целей<h3>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " 1. Бизнес может использовать эти данные для анализа того, какие отрасли являются наиболее прибыльными и перспективными.\n",
    " 2. Компании могут использовать эти данные для анализа возрастных моделей накопления капитала, что помогает лучше планировать инвестиции и маркетинг.\n",
    " 3. Бизнес может понять, какие страны являются наиболее подходящими для инвестиций и предпринимательства."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3>Цели технического проекта<h3>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. Вход: Данные по состоянию и источникам доходов.<br>\n",
    "Целевой признак: Отрасль, состояние.\n",
    "\n",
    "2. Вход: Данные по возрасту и состоянию.<br>\n",
    "Целевой признак: Возраст, состояние.\n",
    "\n",
    "3. Вход: Данные по странам и состоянию.<br>\n",
    "Целевой признак: Страна, состояние."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h3>Выявляем проблемы(и решаем их)<h3>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 225,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 25636 characters]",
      "text/plain": [
       "<Figure size 1500x500 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Размер данных до удаления выбросов:  (2600, 6)\n",
      "Размер данных после удаления выбросов:  (2366, 6)\n"
     ]
    }
   ],
   "source": [
    "fig, axs = plt.subplots(1, 2, figsize=(15, 5))\n",
    "\n",
    "sns.boxplot(data=df3, x='Networth', ax=axs[0])\n",
    "axs[0].set_title(\"Выбросы по состоянию\")\n",
    "\n",
    "sns.boxplot(data=df3, x='Age', ax=axs[1])\n",
    "axs[1].set_title(\"Выбросы по возрасту\")\n",
    "\n",
    "plt.show()\n",
    "print(\"Размер данных до удаления выбросов: \", df3.shape)\n",
    "\n",
    "# Функция для удаления выбросов с помощью IQR\n",
    "def remove_outliers(df, column):\n",
    "    Q1 = df[column].quantile(0.25)\n",
    "    Q3 = df[column].quantile(0.75)\n",
    "    IQR = Q3 - Q1\n",
    "    return df[~((df[column] < (Q1 - 1.5 * IQR)) | (df[column] > (Q3 + 1.5 * IQR)))]\n",
    "\n",
    "df3_cleaned = remove_outliers(df3, 'Networth')\n",
    "df3_cleaned = remove_outliers(df3_cleaned, 'Age')\n",
    "\n",
    "print(\"Размер данных после удаления выбросов: \", df3_cleaned.shape)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 241,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\salih\\AppData\\Local\\Temp\\ipykernel_13360\\2893838167.py:3: FutureWarning: \n",
      "\n",
      "Passing `palette` without assigning `hue` is deprecated and will be removed in v0.14.0. Assign the `y` variable to `hue` and set `legend=False` for the same effect.\n",
      "\n",
      "  sns.barplot(x=country_dist.values, y=country_dist.index, palette='coolwarm')\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 33376 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\salih\\AppData\\Local\\Temp\\ipykernel_13360\\2893838167.py:9: FutureWarning: \n",
      "\n",
      "Passing `palette` without assigning `hue` is deprecated and will be removed in v0.14.0. Assign the `y` variable to `hue` and set `legend=False` for the same effect.\n",
      "\n",
      "  sns.barplot(x=industry_dist.values, y=industry_dist.index, palette='coolwarm')\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 45220 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "(Country\n",
       " United States    27.653846\n",
       " China            19.807692\n",
       " India             6.192308\n",
       " Germany           5.000000\n",
       " Russia            3.115385\n",
       " Hong Kong         2.576923\n",
       " Canada            2.461538\n",
       " Brazil            2.307692\n",
       " Italy             2.000000\n",
       " Taiwan            1.961538\n",
       " Name: proportion, dtype: float64,\n",
       " Industry\n",
       " Finance & Investments     14.846154\n",
       " Technology                12.653846\n",
       " Manufacturing             12.384615\n",
       " Fashion & Retail           9.461538\n",
       " Healthcare                 8.153846\n",
       " Food & Beverage            7.730769\n",
       " Real Estate                7.269231\n",
       " diversified                6.846154\n",
       " Media & Entertainment      3.653846\n",
       " Energy                     3.576923\n",
       " Name: proportion, dtype: float64)"
      ]
     },
     "execution_count": 241,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "plt.figure(figsize=(10, 6))\n",
    "country_dist = df3['Country'].value_counts().head(10)  # Топ-10 стран\n",
    "sns.barplot(x=country_dist.values, y=country_dist.index, palette='coolwarm')\n",
    "plt.title('Распределение миллиардеров по странам (Топ-10)')\n",
    "plt.show()\n",
    "\n",
    "plt.figure(figsize=(10, 6))\n",
    "industry_dist = df3['Industry'].value_counts().head(10)  # Топ-10 отраслей\n",
    "sns.barplot(x=industry_dist.values, y=industry_dist.index, palette='coolwarm')\n",
    "plt.title('Распределение миллиардеров по отраслям (Топ-10)')\n",
    "plt.show()\n",
    "\n",
    "# Процентное распределение по странам и отраслям(для наглядности)\n",
    "country_percentage = df3['Country'].value_counts(normalize=True) * 100\n",
    "industry_percentage = df3['Industry'].value_counts(normalize=True) * 100\n",
    "\n",
    "country_percentage.head(10), industry_percentage.head(10)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Хотел проверить смещение. В данном случае имеется смещение по регионам или отраслям. Но думаю это особенность данного датасета, а не самих данных."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 246,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2598, 75, 18, np.int64(0))"
      ]
     },
     "execution_count": 246,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 1. Проверим уникальность по ключевым столбцам\n",
    "unique_names = df3['Name'].nunique()\n",
    "unique_countries = df3['Country'].nunique()\n",
    "unique_industries = df3['Industry'].nunique()\n",
    "\n",
    "# 2. Проверка дубликатов\n",
    "duplicates_count = df3.duplicated().sum()\n",
    "\n",
    "unique_names, unique_countries, unique_industries, duplicates_count\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Проверка оценки информативности. Тут все нормально"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 248,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\salih\\AppData\\Local\\Temp\\ipykernel_13360\\1549126591.py:7: FutureWarning: \n",
      "\n",
      "Passing `palette` without assigning `hue` is deprecated and will be removed in v0.14.0. Assign the `y` variable to `hue` and set `legend=False` for the same effect.\n",
      "\n",
      "  sns.countplot(data=df3, y='Industry', order=df3['Industry'].value_counts().index, palette='coolwarm')\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 60400 characters]",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Проверка на согласованность категорий\n",
    "unique_sources = df3['Source'].unique()\n",
    "unique_industries = df3['Industry'].unique()\n",
    "\n",
    "# Пример для визуального анализа\n",
    "plt.figure(figsize=(10, 5))\n",
    "sns.countplot(data=df3, y='Industry', order=df3['Industry'].value_counts().index, palette='coolwarm')\n",
    "plt.title('Распределение по отраслям')\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Для оценки покрытия мы смотрим на то, насколько разнообразны данные по странам, отраслям и возрастам."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Устранение проблемы пропущенных данных"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 249,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\salih\\AppData\\Local\\Temp\\ipykernel_13360\\207427758.py:9: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method.\n",
      "The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy.\n",
      "\n",
      "For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object.\n",
      "\n",
      "\n",
      "  df_fillna_mean[column].fillna(df_fillna_mean[column].mean(), inplace=True)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(Name        0\n",
       " Networth    0\n",
       " Age         0\n",
       " Country     0\n",
       " Source      0\n",
       " Industry    0\n",
       " dtype: int64,\n",
       " (2600, 6),\n",
       " (2600, 6),\n",
       " (2600, 6))"
      ]
     },
     "execution_count": 249,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "missing_values = df3.isnull().sum()\n",
    "\n",
    "df_dropna = df3.dropna()\n",
    "\n",
    "df_fillna_const = df3.fillna(0)\n",
    "\n",
    "df_fillna_mean = df3.copy()\n",
    "for column in df_fillna_mean.select_dtypes(include=['float64', 'int64']):\n",
    "    df_fillna_mean[column].fillna(df_fillna_mean[column].mean(), inplace=True)\n",
    "\n",
    "missing_values, df_dropna.shape, df_fillna_const.shape, df_fillna_mean.shape\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Разбиение набора данных на обучающую, контрольную и тестовую выборки"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 251,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((1560, 5), (520, 5), (520, 5))"
      ]
     },
     "execution_count": 251,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "# Разделим набор данных на признаки (X) и целевой признак (y)\n",
    "X = df3.drop(columns=['Networth'])\n",
    "y = df3['Networth']\n",
    "\n",
    "# Разделение на обучающую, контрольную и тестовую выборки\n",
    "X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.4, random_state=42)\n",
    "X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)\n",
    "\n",
    "# Проверка размера выборок\n",
    "(X_train.shape, X_val.shape, X_test.shape)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Оценка сбалансированности выборок\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 252,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(count    1560.000000\n",
       " mean        5.208173\n",
       " std        12.653032\n",
       " min         1.000000\n",
       " 25%         1.500000\n",
       " 50%         2.400000\n",
       " 75%         4.300000\n",
       " max       219.000000\n",
       " Name: Networth, dtype: float64,\n",
       " count    520.000000\n",
       " mean       4.443654\n",
       " std        7.267615\n",
       " min        1.000000\n",
       " 25%        1.500000\n",
       " 50%        2.400000\n",
       " 75%        4.825000\n",
       " max       91.400000\n",
       " Name: Networth, dtype: float64,\n",
       " count    520.000000\n",
       " mean       4.235577\n",
       " std        5.861496\n",
       " min        1.000000\n",
       " 25%        1.600000\n",
       " 50%        2.500000\n",
       " 75%        4.500000\n",
       " max       60.000000\n",
       " Name: Networth, dtype: float64)"
      ]
     },
     "execution_count": 252,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Проверка распределения целевого признака по выборкам\n",
    "train_dist = y_train.describe()\n",
    "val_dist = y_val.describe()\n",
    "test_dist = y_test.describe()\n",
    "\n",
    "train_dist, val_dist, test_dist\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 273,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Размеры после oversampling: (15270, 19) (15270,)\n",
      "Размеры после undersampling: (14965, 19) (14965,)\n"
     ]
    }
   ],
   "source": [
    "oversampler = RandomOverSampler(random_state=12)\n",
    "X_train_over, y_train_over = oversampler.fit_resample(X_train, y_train)\n",
    "\n",
    "undersampler = RandomUnderSampler(random_state=12)\n",
    "X_train_under, y_train_under = undersampler.fit_resample(X_train, y_train)\n",
    "\n",
    "print(\"Размеры после oversampling:\", X_train_over.shape, y_train_over.shape)\n",
    "print(\"Размеры после undersampling:\", X_train_under.shape, y_train_under.shape)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "aimenv",
   "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.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
