{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Набор данных \"Ближайшие к Земле объекты\" "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "#  Наборе данных \"Ближайшие к Земле объекты\" \n",
    "#   \n",
    "#  1. Анализ сведений о наборе данных \n",
    "#      Набор данных о \"ближайших к Земле объектах\" относится к области астрофизики и исследования космических угроз. Проблемная область — мониторинг околоземных  объектов (Near-Earth  Objects, NEO), которые могут представлять потенциальную опасность для Земли. Цель анализа — оценить характеристики объектов, их орбиты,  скорость, и расстояние до Земли, чтобы предсказать возможность столкновения. \n",
    "#   \n",
    "#  2. Анализ содержимого набора данных \n",
    "#      Объекты наблюдения: \n",
    "#          Космические тела, которые классифицируются как \"околоземные объекты\". \n",
    "#      Атрибуты объектов: \n",
    "#          id — идентификатор объекта. \n",
    "#          name — название объекта. \n",
    "#          est_diameter_min и est_diameter_max — оценочные минимальный и максимальный диаметры. \n",
    "#          relative_velocity — относительная скорость объекта. \n",
    "#          miss_distance — минимальное расстояние до Земли. \n",
    "#          orbiting_body — небесное тело, вокруг которого объект совершает движение (обычно Солнце). \n",
    "#          sentry_object — булевый признак, указывающий, находится ли объект в базе наблюдения системы Sentry. \n",
    "#          absolute_magnitude — абсолютная звёздная величина объекта. \n",
    "#          hazardous — булевый признак опасности объекта. \n",
    "#      Связи между объектами: \n",
    "#          Объекты могут быть связаны через общее орбитальное тело или группироваться по характеристикам орбит. \n",
    "#   \n",
    "#  3. Примеры бизнес-целей \n",
    "#      Уведомление о космических угрозах: \n",
    "#          Построение системы прогнозирования опасных объектов для оперативного предупреждения. \n",
    "#          Эффект: повышение безопасности через своевременные предупреждения. \n",
    "#   \n",
    "#      Оптимизация миссий для изучения астероидов: \n",
    "#          Идентификация объектов, подходящих для изучения (на основе характеристик орбиты и размера). \n",
    "#          Эффект: снижение затрат и повышение научной ценности миссий. \n",
    "#   \n",
    "#  4. Примеры целей технического проекта \n",
    "#      Бизнес-цель: Предсказание опасности объекта. \n",
    "#          Входные данные: атрибуты объекта (диаметр, скорость, расстояние). \n",
    "#          Целевой признак: hazardous. \n",
    "#       \n",
    "#      Бизнес-цель: Классификация объектов по характеристикам. \n",
    "#          Входные данные: абсолютная звёздная величина, диаметр, скорость. \n",
    "#          Целевой признак: принадлежность к определённой группе объектов. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "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>id</th>\n",
       "      <th>name</th>\n",
       "      <th>est_diameter_min</th>\n",
       "      <th>est_diameter_max</th>\n",
       "      <th>relative_velocity</th>\n",
       "      <th>miss_distance</th>\n",
       "      <th>orbiting_body</th>\n",
       "      <th>sentry_object</th>\n",
       "      <th>absolute_magnitude</th>\n",
       "      <th>hazardous</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2162635</td>\n",
       "      <td>162635 (2000 SS164)</td>\n",
       "      <td>1.198271</td>\n",
       "      <td>2.679415</td>\n",
       "      <td>13569.249224</td>\n",
       "      <td>5.483974e+07</td>\n",
       "      <td>Earth</td>\n",
       "      <td>False</td>\n",
       "      <td>16.73</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2277475</td>\n",
       "      <td>277475 (2005 WK4)</td>\n",
       "      <td>0.265800</td>\n",
       "      <td>0.594347</td>\n",
       "      <td>73588.726663</td>\n",
       "      <td>6.143813e+07</td>\n",
       "      <td>Earth</td>\n",
       "      <td>False</td>\n",
       "      <td>20.00</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2512244</td>\n",
       "      <td>512244 (2015 YE18)</td>\n",
       "      <td>0.722030</td>\n",
       "      <td>1.614507</td>\n",
       "      <td>114258.692129</td>\n",
       "      <td>4.979872e+07</td>\n",
       "      <td>Earth</td>\n",
       "      <td>False</td>\n",
       "      <td>17.83</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3596030</td>\n",
       "      <td>(2012 BV13)</td>\n",
       "      <td>0.096506</td>\n",
       "      <td>0.215794</td>\n",
       "      <td>24764.303138</td>\n",
       "      <td>2.543497e+07</td>\n",
       "      <td>Earth</td>\n",
       "      <td>False</td>\n",
       "      <td>22.20</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>3667127</td>\n",
       "      <td>(2014 GE35)</td>\n",
       "      <td>0.255009</td>\n",
       "      <td>0.570217</td>\n",
       "      <td>42737.733765</td>\n",
       "      <td>4.627557e+07</td>\n",
       "      <td>Earth</td>\n",
       "      <td>False</td>\n",
       "      <td>20.09</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        id                 name  est_diameter_min  est_diameter_max  \\\n",
       "0  2162635  162635 (2000 SS164)          1.198271          2.679415   \n",
       "1  2277475    277475 (2005 WK4)          0.265800          0.594347   \n",
       "2  2512244   512244 (2015 YE18)          0.722030          1.614507   \n",
       "3  3596030          (2012 BV13)          0.096506          0.215794   \n",
       "4  3667127          (2014 GE35)          0.255009          0.570217   \n",
       "\n",
       "   relative_velocity  miss_distance orbiting_body  sentry_object  \\\n",
       "0       13569.249224   5.483974e+07         Earth          False   \n",
       "1       73588.726663   6.143813e+07         Earth          False   \n",
       "2      114258.692129   4.979872e+07         Earth          False   \n",
       "3       24764.303138   2.543497e+07         Earth          False   \n",
       "4       42737.733765   4.627557e+07         Earth          False   \n",
       "\n",
       "   absolute_magnitude  hazardous  \n",
       "0               16.73      False  \n",
       "1               20.00       True  \n",
       "2               17.83      False  \n",
       "3               22.20      False  \n",
       "4               20.09       True  "
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "\n",
    "df = pd.read_csv('../../datasets/neo.csv')\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Количество пропущенных значений в каждом столбце:\n",
      "id                    0\n",
      "est_diameter_min      0\n",
      "est_diameter_max      0\n",
      "relative_velocity     0\n",
      "miss_distance         0\n",
      "absolute_magnitude    0\n",
      "hazardous             0\n",
      "dtype: int64\n",
      "Количество выбросов в столбце 'est_diameter_min': 8306\n",
      "Количество выбросов в столбце 'est_diameter_max': 8306\n",
      "Количество выбросов в столбце 'relative_velocity': 1574\n",
      "Количество выбросов в столбце 'miss_distance': 0\n",
      "Количество выбросов в столбце 'absolute_magnitude': 101\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 132844 characters]",
      "text/plain": [
       "<Figure size 1500x1000 with 5 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Количество выбросов в столбце 'est_diameter_min': 8306\n",
      "Количество выбросов в столбце 'est_diameter_max': 8306\n",
      "Количество выбросов в столбце 'relative_velocity': 1574\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 65792 characters]",
      "text/plain": [
       "<Figure size 1500x1000 with 3 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Обучающая выборка:  (63585, 7)\n",
      "hazardous\n",
      "False    57399\n",
      "True      6186\n",
      "Name: count, dtype: int64\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 21112 characters]",
      "text/plain": [
       "<Figure size 200x200 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Контрольная выборка:  (13625, 7)\n",
      "hazardous\n",
      "False    12315\n",
      "True      1310\n",
      "Name: count, dtype: int64\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 20928 characters]",
      "text/plain": [
       "<Figure size 200x200 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Тестовая выборка:  (13626, 7)\n",
      "hazardous\n",
      "False    12282\n",
      "True      1344\n",
      "Name: count, dtype: int64\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 19784 characters]",
      "text/plain": [
       "<Figure size 200x200 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Обучающая выборка после оверсемплинга:  (115214, 7)\n",
      "hazardous\n",
      "True     57815\n",
      "False    57399\n",
      "Name: count, dtype: int64\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 23168 characters]",
      "text/plain": [
       "<Figure size 200x200 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Обучающая выборка после андерсемплинга:  (12372, 7)\n",
      "hazardous\n",
      "False    6186\n",
      "True     6186\n",
      "Name: count, dtype: int64\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 23028 characters]",
      "text/plain": [
       "<Figure size 200x200 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "import numpy as np\n",
    "\n",
    "df = pd.read_csv('../../datasets/neo.csv')\n",
    "df = df.drop(columns=['name', 'orbiting_body', 'sentry_object'])\n",
    "\n",
    "\n",
    "#5. Устранение пропущенных данных\n",
    "    \n",
    "#Сведения о пропущенных данных\n",
    "print(\"Количество пропущенных значений в каждом столбце:\")\n",
    "print(df.isnull().sum())\n",
    "\n",
    "# Процент пропущенных значений признаков\n",
    "for i in df.columns:\n",
    "    null_rate = df[i].isnull().sum() / len(df) * 100\n",
    "    if null_rate > 0:\n",
    "        print(f'{i} Процент пустых значений: %{null_rate:.2f}')\n",
    "\n",
    "\n",
    "#Пропущенных данных в датасете нет\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "#6. Проблемы набора данных\n",
    "    #5.1Выбросы: Возможны аномалии в значениях скорости или расстояния.\n",
    "    #Смещение: Данные могут быть смещены в сторону объектов, которые легче обнаружить (крупные, близкие).\n",
    "\n",
    "#7. Решения для обнаруженных проблем\n",
    "    #Выбросы: Идентификация и обработка выбросов через методы (например, IQR или Z-оценка).\n",
    "    #Смещение: Использование методов балансировки данных, таких как oversampling.\n",
    "\n",
    "#7.1 Проверка набора данных на выбросы\n",
    "# Выбираем столбцы для анализа\n",
    "columns_to_check = ['est_diameter_min', 'est_diameter_max', 'relative_velocity', 'miss_distance', 'absolute_magnitude']\n",
    "def Emissions(columns_to_check):\n",
    "\n",
    "    # Функция для подсчета выбросов\n",
    "    def count_outliers(df, columns):\n",
    "        outliers_count = {}\n",
    "        for col in columns:\n",
    "            Q1 = df[col].quantile(0.25)\n",
    "            Q3 = df[col].quantile(0.75)\n",
    "            IQR = Q3 - Q1\n",
    "            lower_bound = Q1 - 1.5 * IQR\n",
    "            upper_bound = Q3 + 1.5 * IQR\n",
    "            \n",
    "            # Считаем количество выбросов\n",
    "            outliers = df[(df[col] < lower_bound) | (df[col] > upper_bound)]\n",
    "            outliers_count[col] = len(outliers)\n",
    "        \n",
    "        return outliers_count\n",
    "\n",
    "    # Подсчитываем выбросы\n",
    "    outliers_count = count_outliers(df, columns_to_check)\n",
    "\n",
    "    # Выводим количество выбросов для каждого столбца\n",
    "    for col, count in outliers_count.items():\n",
    "        print(f\"Количество выбросов в столбце '{col}': {count}\")\n",
    "        \n",
    "    # Создаем гистограммы\n",
    "    plt.figure(figsize=(15, 10))\n",
    "    for i, col in enumerate(columns_to_check, 1):\n",
    "        plt.subplot(2, 3, i)\n",
    "        sns.histplot(df[col], kde=True)\n",
    "        plt.title(f'Histogram of {col}')\n",
    "    plt.tight_layout()\n",
    "    plt.show()\n",
    "Emissions(columns_to_check)\n",
    "\n",
    "#Признак miss_distance не имеет выбросов, \n",
    "#признак absolute_magnitude имеет количество выбросов в приемлемом диапазоне\n",
    "#для признаков est_diameter_min, est_diameter_max и relative_velocity необходимо использовать метод решения проблемы выбросов. \n",
    "#Воспользуемся методом усреднения значений:\n",
    "columns_to_fix = ['est_diameter_min', 'est_diameter_max', 'relative_velocity']\n",
    "# Замена нулей и пропущенных значений средним\n",
    "for column in columns_to_fix:\n",
    "    # Расчет среднего, исключая 0 и NaN\n",
    "    mean_value = df[df[column] > 0][column].mean()\n",
    "    # Замена NaN и нулей на среднее\n",
    "    df[column] = df[column].replace(0, np.nan).fillna(mean_value)\n",
    "\n",
    "#Оценим выбросы в выборке после усреднения:\n",
    "Emissions(columns_to_fix)\n",
    "\n",
    "#Удалось избавиться от выбросов в соответствующих признаках как видно на диаграммах.\n",
    "\n",
    "\n",
    "\n",
    "#8. Разбиение данных на выборки\n",
    "\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "train_data, temp_data = train_test_split(df, test_size=0.3, random_state=42)\n",
    "val_data, test_data = train_test_split(temp_data, test_size=0.5, random_state=42)\n",
    "\n",
    "print(\"Обучающая выборка: \", train_data.shape)\n",
    "print(train_data.hazardous.value_counts())\n",
    "hazardous_counts = train_data['hazardous'].value_counts()\n",
    "plt.figure(figsize=(2, 2))\n",
    "plt.pie(hazardous_counts, labels=hazardous_counts.index, autopct='%1.1f%%', startangle=90)\n",
    "plt.title('Распределение классов hazardous в обучающей выборке')\n",
    "plt.show()\n",
    "\n",
    "print(\"Контрольная выборка: \", val_data.shape)\n",
    "print(val_data.hazardous.value_counts())\n",
    "hazardous_counts = val_data['hazardous'].value_counts()\n",
    "plt.figure(figsize=(2, 2))\n",
    "plt.pie(hazardous_counts, labels=hazardous_counts.index, autopct='%1.1f%%', startangle=90)\n",
    "plt.title('Распределение классов hazardous в контрольной выборке')\n",
    "plt.show()\n",
    "\n",
    "print(\"Тестовая выборка: \", test_data.shape)\n",
    "print(test_data.hazardous.value_counts())\n",
    "hazardous_counts = test_data['hazardous'].value_counts()\n",
    "plt.figure(figsize=(2, 2))\n",
    "plt.pie(hazardous_counts, labels=hazardous_counts.index, autopct='%1.1f%%', startangle=90)\n",
    "plt.title('Распределение классов hazardous в тестовой выборке')\n",
    "plt.show()\n",
    "\n",
    "\n",
    "#9. Оценить  сбалансированность  выборок  для  каждого  набора  данных.  Оценить необходимость использования методов приращения (аугментации) данных. \n",
    "#Выводы по сбалансированности\n",
    "#Если распределение классов примерно равно (например, 50%/50%), выборка считается сбалансированной, и аугментация данных не требуется.\n",
    "#Если один из классов сильно доминирует (например, 90%/10%), выборка несбалансированная, и может потребоваться аугментация данных.\n",
    "\n",
    "#Данная сборка несбалансированная, и требуется аугментация данных.\n",
    "\n",
    "\n",
    "#10. Выполнить приращение данных методами выборки с избытком (oversampling) и выборки  с  недостатком  (undersampling).  Должны  быть  представлены  примеры реализации обоих методов для выборок набора данных. \n",
    "\n",
    "#10.1\n",
    "#Аугментация данных методом оверсемплинга¶\n",
    "#Этот метод увеличивает количество примеров меньшинства.\n",
    "\n",
    "from imblearn.over_sampling import ADASYN\n",
    "\n",
    "# Создание экземпляра ADASYN\n",
    "ada = ADASYN()\n",
    "\n",
    "# Применение ADASYN\n",
    "X_resampled, y_resampled = ada.fit_resample(train_data.drop(columns=['hazardous']), train_data['hazardous'])\n",
    "\n",
    "# Создание нового DataFrame\n",
    "df_train_adasyn = pd.DataFrame(X_resampled)\n",
    "df_train_adasyn['hazardous'] = y_resampled  # Добавление целевой переменной\n",
    "\n",
    "# Вывод информации о новой выборке\n",
    "print(\"Обучающая выборка после оверсемплинга: \", df_train_adasyn.shape)\n",
    "print(df_train_adasyn['hazardous'].value_counts())\n",
    "hazardous_counts = df_train_adasyn['hazardous'].value_counts()\n",
    "plt.figure(figsize=(2, 2))\n",
    "plt.pie(hazardous_counts, labels=hazardous_counts.index, autopct='%1.1f%%', startangle=90)\n",
    "plt.title('Распределение классов hazardous в обучающей выборке после оверсемплинга')\n",
    "plt.show()\n",
    "\n",
    "\n",
    "#10.2\n",
    "#Аугментация данных методом андерсемплинга\n",
    "#Этот метод помогает сбалансировать выборку, уменьшая количество экземпляров класса большинства, чтобы привести его в соответствие с классом меньшинства\n",
    "\n",
    "from imblearn.under_sampling import RandomUnderSampler\n",
    "\n",
    "rus = RandomUnderSampler()\n",
    "\n",
    "# Применение RandomUnderSampler\n",
    "X_resampled, y_resampled = rus.fit_resample(train_data.drop(columns=['hazardous']), train_data['hazardous'])\n",
    "\n",
    "# Создание нового DataFrame\n",
    "df_train_undersampled = pd.DataFrame(X_resampled)\n",
    "df_train_undersampled['hazardous'] = y_resampled  # Добавление целевой переменной\n",
    "\n",
    "# Вывод информации о новой выборке\n",
    "print(\"Обучающая выборка после андерсемплинга: \", df_train_undersampled.shape)\n",
    "print(df_train_undersampled['hazardous'].value_counts())\n",
    "\n",
    "# Визуализация распределения классов\n",
    "hazardous_counts = df_train_undersampled['hazardous'].value_counts()\n",
    "plt.figure(figsize=(2, 2))\n",
    "plt.pie(hazardous_counts, labels=hazardous_counts.index, autopct='%1.1f%%', startangle=90)\n",
    "plt.title('Распределение классов hazardous в обучающей выборке после андерсемплинга')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Набор данных \"Продажа домов в округе Кинг, США\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "#  1. Анализ сведений о наборе данных \"Продажа домов в округе Кинг, США\"\n",
    "#  Данный набор данных содержит информацию о работе филиалов супермаркетов. Проблемная область связана с анализом производительности магазинов, оптимизацией их #  работы и улучшением ключевых показателей, таких как продажи и привлечение клиентов. Основные вопросы, которые могут возникнуть:\n",
    "#  \n",
    "#  2. Анализ содержимого набора данных\n",
    "#      Объекты наблюдения\n",
    "#          Каждая строка представляет собой данные о конкретном магазине.\n",
    "#  \n",
    "#      Атрибуты объектов\n",
    "#          Store ID (идентификатор магазина): уникальный номер, однозначно идентифицирующий магазин.\n",
    "#          Store_Area (площадь магазина): общая площадь магазина в квадратных метрах.\n",
    "#          Items_Available (количество доступных товаров): общее количество товаров в магазине.\n",
    "#          Daily_Customer_Count (ежедневное число покупателей): среднее число покупателей в день.\n",
    "#          Store_Sales (продажи магазина): общая выручка магазина.\n",
    "#  \n",
    "#      Связи между объектами\n",
    "#          Объекты (магазины) связаны общей бизнес-целью (рост прибыли) и схожими условиями работы (товары, покупатели,площади). Возможные связи:\n",
    "#              Прямая связь между числом покупателей и выручкой.\n",
    "#              Влияние площади и ассортимента на посещаемость и продажи.\n",
    "#  \n",
    "#  3. Примеры бизнес-целей и эффекты для бизнеса\n",
    "#      Бизнес-цели\n",
    "#          Оптимизация ассортимента: определить, как ассортимент товаров влияет на продажи.\n",
    "#          Увеличение посещаемости: найти факторы, повышающие интерес покупателей к магазину.\n",
    "#          Оптимизация площадей: выявить оптимальные площади магазинов для максимальной выручки.\n",
    "#          Анализ производительности филиалов: сравнить эффективность магазинов и выявить лучшие практики.\n",
    "#      Эффекты для бизнеса\n",
    "#          Повышение выручки за счет оптимизации ассортимента и улучшения опыта покупателей.\n",
    "#          Сокращение затрат на неэффективные площади.\n",
    "#          Более точное планирование при открытии новых магазинов.\n",
    "#  \n",
    "#  4. Примеры целей технического проекта\n",
    "#      Цель 1: Оптимизация ассортимента\n",
    "#          Входные данные: Store_Area, Items_Available, Store_Sales.\n",
    "#          Целевой признак: Store_Sales.\n",
    "#          Результат: рекомендации по увеличению или уменьшению ассортимента.\n",
    "#      Цель 2: Увеличение посещаемости\n",
    "#          Входные данные: Store_Area, Items_Available, Store_Sales.\n",
    "#          Целевой признак: Daily_Customer_Count.\n",
    "#          Результат: прогноз посещаемости на основе характеристик магазина.\n",
    "#      Цель 3: Оптимизация площадей\n",
    "#          Входные данные: Store_Area, Store_Sales.\n",
    "#          Целевой признак: Store_Sales.\n",
    "#          Результат: определение оптимальной площади для магазина.\n",
    "#      Цель 4: Анализ производительности филиалов\n",
    "#          Входные данные: Все атрибуты.\n",
    "#          Целевой признак: Store_Sales.\n",
    "#          Результат: классификация магазинов по эффективности и выявление отстающих филиалов."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "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>id</th>\n",
       "      <th>date</th>\n",
       "      <th>price</th>\n",
       "      <th>bedrooms</th>\n",
       "      <th>bathrooms</th>\n",
       "      <th>sqft_living</th>\n",
       "      <th>sqft_lot</th>\n",
       "      <th>floors</th>\n",
       "      <th>waterfront</th>\n",
       "      <th>view</th>\n",
       "      <th>...</th>\n",
       "      <th>grade</th>\n",
       "      <th>sqft_above</th>\n",
       "      <th>sqft_basement</th>\n",
       "      <th>yr_built</th>\n",
       "      <th>yr_renovated</th>\n",
       "      <th>zipcode</th>\n",
       "      <th>lat</th>\n",
       "      <th>long</th>\n",
       "      <th>sqft_living15</th>\n",
       "      <th>sqft_lot15</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>7129300520</td>\n",
       "      <td>20141013T000000</td>\n",
       "      <td>221900.0</td>\n",
       "      <td>3</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1180</td>\n",
       "      <td>5650</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>7</td>\n",
       "      <td>1180</td>\n",
       "      <td>0</td>\n",
       "      <td>1955</td>\n",
       "      <td>0</td>\n",
       "      <td>98178</td>\n",
       "      <td>47.5112</td>\n",
       "      <td>-122.257</td>\n",
       "      <td>1340</td>\n",
       "      <td>5650</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>6414100192</td>\n",
       "      <td>20141209T000000</td>\n",
       "      <td>538000.0</td>\n",
       "      <td>3</td>\n",
       "      <td>2.25</td>\n",
       "      <td>2570</td>\n",
       "      <td>7242</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>7</td>\n",
       "      <td>2170</td>\n",
       "      <td>400</td>\n",
       "      <td>1951</td>\n",
       "      <td>1991</td>\n",
       "      <td>98125</td>\n",
       "      <td>47.7210</td>\n",
       "      <td>-122.319</td>\n",
       "      <td>1690</td>\n",
       "      <td>7639</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>5631500400</td>\n",
       "      <td>20150225T000000</td>\n",
       "      <td>180000.0</td>\n",
       "      <td>2</td>\n",
       "      <td>1.00</td>\n",
       "      <td>770</td>\n",
       "      <td>10000</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>6</td>\n",
       "      <td>770</td>\n",
       "      <td>0</td>\n",
       "      <td>1933</td>\n",
       "      <td>0</td>\n",
       "      <td>98028</td>\n",
       "      <td>47.7379</td>\n",
       "      <td>-122.233</td>\n",
       "      <td>2720</td>\n",
       "      <td>8062</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2487200875</td>\n",
       "      <td>20141209T000000</td>\n",
       "      <td>604000.0</td>\n",
       "      <td>4</td>\n",
       "      <td>3.00</td>\n",
       "      <td>1960</td>\n",
       "      <td>5000</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>7</td>\n",
       "      <td>1050</td>\n",
       "      <td>910</td>\n",
       "      <td>1965</td>\n",
       "      <td>0</td>\n",
       "      <td>98136</td>\n",
       "      <td>47.5208</td>\n",
       "      <td>-122.393</td>\n",
       "      <td>1360</td>\n",
       "      <td>5000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1954400510</td>\n",
       "      <td>20150218T000000</td>\n",
       "      <td>510000.0</td>\n",
       "      <td>3</td>\n",
       "      <td>2.00</td>\n",
       "      <td>1680</td>\n",
       "      <td>8080</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>8</td>\n",
       "      <td>1680</td>\n",
       "      <td>0</td>\n",
       "      <td>1987</td>\n",
       "      <td>0</td>\n",
       "      <td>98074</td>\n",
       "      <td>47.6168</td>\n",
       "      <td>-122.045</td>\n",
       "      <td>1800</td>\n",
       "      <td>7503</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 21 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "           id             date     price  bedrooms  bathrooms  sqft_living  \\\n",
       "0  7129300520  20141013T000000  221900.0         3       1.00         1180   \n",
       "1  6414100192  20141209T000000  538000.0         3       2.25         2570   \n",
       "2  5631500400  20150225T000000  180000.0         2       1.00          770   \n",
       "3  2487200875  20141209T000000  604000.0         4       3.00         1960   \n",
       "4  1954400510  20150218T000000  510000.0         3       2.00         1680   \n",
       "\n",
       "   sqft_lot  floors  waterfront  view  ...  grade  sqft_above  sqft_basement  \\\n",
       "0      5650     1.0           0     0  ...      7        1180              0   \n",
       "1      7242     2.0           0     0  ...      7        2170            400   \n",
       "2     10000     1.0           0     0  ...      6         770              0   \n",
       "3      5000     1.0           0     0  ...      7        1050            910   \n",
       "4      8080     1.0           0     0  ...      8        1680              0   \n",
       "\n",
       "   yr_built  yr_renovated  zipcode      lat     long  sqft_living15  \\\n",
       "0      1955             0    98178  47.5112 -122.257           1340   \n",
       "1      1951          1991    98125  47.7210 -122.319           1690   \n",
       "2      1933             0    98028  47.7379 -122.233           2720   \n",
       "3      1965             0    98136  47.5208 -122.393           1360   \n",
       "4      1987             0    98074  47.6168 -122.045           1800   \n",
       "\n",
       "   sqft_lot15  \n",
       "0        5650  \n",
       "1        7639  \n",
       "2        8062  \n",
       "3        5000  \n",
       "4        7503  \n",
       "\n",
       "[5 rows x 21 columns]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv('../../datasets/kc_house_data.csv')\n",
    "df.head()\n",
    "#df.select_dtypes(include=np.number).columns.tolist()[1:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Количество пропущенных значений в каждом столбце:\n",
      "date             0\n",
      "price            0\n",
      "bedrooms         0\n",
      "bathrooms        0\n",
      "sqft_living      0\n",
      "sqft_lot         0\n",
      "floors           0\n",
      "waterfront       0\n",
      "view             0\n",
      "condition        0\n",
      "grade            0\n",
      "sqft_above       0\n",
      "sqft_basement    0\n",
      "yr_built         0\n",
      "yr_renovated     0\n",
      "zipcode          0\n",
      "lat              0\n",
      "long             0\n",
      "sqft_living15    0\n",
      "sqft_lot15       0\n",
      "dtype: int64\n",
      "Количество выбросов в столбце 'price': 1146\n",
      "Количество выбросов в столбце 'sqft_living': 572\n",
      "Количество выбросов в столбце 'bathrooms': 571\n",
      "Количество выбросов в столбце 'yr_built': 0\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 115676 characters]",
      "text/plain": [
       "<Figure size 1500x1000 with 4 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Количество удаленных строк: 1520\n",
      "Количество выбросов в столбце 'price': 211\n",
      "Количество выбросов в столбце 'sqft_living': 34\n",
      "Количество выбросов в столбце 'bathrooms': 0\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 94320 characters]",
      "text/plain": [
       "<Figure size 1500x1000 with 3 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Средняя цена в обучающей выборке: 470646.91546391754\n",
      "Средняя цена в контрольной выборке: 468579.52654280025\n",
      "Средняя цена в тестовой выборке: 471598.4402786994\n",
      "\n",
      "Стандартное отклонение цены в обучающей выборке: 202445.70321089853\n",
      "Стандартное отклонение цены в контрольной выборке: 202183.1175619316\n",
      "Стандартное отклонение цены в тестовой выборке: 206393.61053704965\n",
      "\n",
      "Распределение по квартилам (обучающая):\n",
      "0.25    313500.0\n",
      "0.50    435000.0\n",
      "0.75    594000.0\n",
      "Name: price, dtype: float64\n",
      "\n",
      "Распределение по квартилам (контрольная):\n",
      "0.25    313612.5\n",
      "0.50    429925.0\n",
      "0.75    595000.0\n",
      "Name: price, dtype: float64\n",
      "\n",
      "Распределение по квартилам (тестовая):\n",
      "0.25    312500.0\n",
      "0.50    428500.0\n",
      "0.75    595375.0\n",
      "Name: price, dtype: float64\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 87980 characters]",
      "text/plain": [
       "<Figure size 1200x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 94972 characters]",
      "text/plain": [
       "<Figure size 1200x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 89780 characters]",
      "text/plain": [
       "<Figure size 1200x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "import numpy as np\n",
    "\n",
    "df = pd.read_csv('../../datasets/kc_house_data.csv')\n",
    "df = df.drop(columns=['id'])\n",
    "\n",
    "\n",
    "#5. Устранение пропущенных данных\n",
    "    \n",
    "#Сведения о пропущенных данных\n",
    "print(\"Количество пропущенных значений в каждом столбце:\")\n",
    "print(df.isnull().sum())\n",
    "\n",
    "# Процент пропущенных значений признаков\n",
    "for i in df.columns:\n",
    "    null_rate = df[i].isnull().sum() / len(df) * 100\n",
    "    if null_rate > 0:\n",
    "        print(f'{i} Процент пустых значений: %{null_rate:.2f}')\n",
    "\n",
    "\n",
    "#Пропущенных данных в датасете нет\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "#6. Проблемы набора данных\n",
    "    #5.1Выбросы: Возможны аномалии в значениях скорости или расстояния.\n",
    "    #Смещение: Данные могут быть смещены в сторону объектов, которые легче обнаружить (крупные, близкие).\n",
    "\n",
    "#7. Решения для обнаруженных проблем\n",
    "    #Выбросы: Идентификация и обработка выбросов через методы (например, IQR или Z-оценка).\n",
    "    #Смещение: Использование методов балансировки данных, таких как oversampling.\n",
    "\n",
    "#7.1 Проверка набора данных на выбросы\n",
    "# Выбираем столбцы для анализа\n",
    "columns_to_check = ['price', 'sqft_living', 'bathrooms', 'yr_built']\n",
    "def Emissions(columns_to_check):\n",
    "\n",
    "    # Функция для подсчета выбросов\n",
    "    def count_outliers(df, columns):\n",
    "        outliers_count = {}\n",
    "        for col in columns:\n",
    "            Q1 = df[col].quantile(0.25)\n",
    "            Q3 = df[col].quantile(0.75)\n",
    "            IQR = Q3 - Q1\n",
    "            lower_bound = Q1 - 1.5 * IQR\n",
    "            upper_bound = Q3 + 1.5 * IQR\n",
    "            \n",
    "            # Считаем количество выбросов\n",
    "            outliers = df[(df[col] < lower_bound) | (df[col] > upper_bound)]\n",
    "            outliers_count[col] = len(outliers)\n",
    "        \n",
    "        return outliers_count\n",
    "\n",
    "    # Подсчитываем выбросы\n",
    "    outliers_count = count_outliers(df, columns_to_check)\n",
    "\n",
    "    # Выводим количество выбросов для каждого столбца\n",
    "    for col, count in outliers_count.items():\n",
    "        print(f\"Количество выбросов в столбце '{col}': {count}\")\n",
    "        \n",
    "    # Создаем гистограммы\n",
    "    plt.figure(figsize=(15, 10))\n",
    "    for i, col in enumerate(columns_to_check, 1):\n",
    "        plt.subplot(2, 3, i)\n",
    "        sns.histplot(df[col], kde=True)\n",
    "        plt.title(f'Histogram of {col}')\n",
    "    plt.tight_layout()\n",
    "    plt.show()\n",
    "Emissions(columns_to_check)\n",
    "\n",
    "#Признак yr_built не имеет выбросов, \n",
    "#для признаков 'price', 'sqft_living', 'bathrooms' необходимо использовать метод решения проблемы выбросов. \n",
    "#Воспользуемся методом удаления наблюдений с такими выбросами:\n",
    "# Выбираем столбцы для очистки\n",
    "columns_to_fix =  ['price', 'sqft_living', 'bathrooms']\n",
    "\n",
    "# Функция для удаления выбросов\n",
    "def remove_outliers(df, columns):\n",
    "    for col in columns:\n",
    "        Q1 = df[col].quantile(0.25)\n",
    "        Q3 = df[col].quantile(0.75)\n",
    "        IQR = Q3 - Q1\n",
    "        lower_bound = Q1 - 1.5 * IQR\n",
    "        upper_bound = Q3 + 1.5 * IQR\n",
    "        \n",
    "        # Удаляем строки, содержащие выбросы\n",
    "        df = df[(df[col] >= lower_bound) & (df[col] <= upper_bound)]\n",
    "    \n",
    "    return df\n",
    "\n",
    "# Удаляем выбросы\n",
    "df_cleaned = remove_outliers(df, columns_to_fix)\n",
    "\n",
    "# Выводим количество удаленных строк\n",
    "print(f\"Количество удаленных строк: {len(df) - len(df_cleaned)}\")\n",
    "\n",
    "df = df_cleaned\n",
    "\n",
    "#Оценим выбросы в выборке после усреднения:\n",
    "Emissions(columns_to_fix)\n",
    "\n",
    "#Удалось избавиться от выбросов в соответствующих признаках как видно на диаграммах.\n",
    "\n",
    "\n",
    "\n",
    "#8. Разбиение данных на выборки\n",
    "\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "train_data, temp_data = train_test_split(df, test_size=0.3, random_state=42)\n",
    "val_data, test_data = train_test_split(temp_data, test_size=0.5, random_state=42)\n",
    "\n",
    "# Средние значения цены\n",
    "print(\"Средняя цена в обучающей выборке:\", train_data['price'].mean())\n",
    "print(\"Средняя цена в контрольной выборке:\", val_data['price'].mean())\n",
    "print(\"Средняя цена в тестовой выборке:\", test_data['price'].mean())\n",
    "print()\n",
    "\n",
    "# Стандартное отклонение цены\n",
    "print(\"Стандартное отклонение цены в обучающей выборке:\", train_data['price'].std())\n",
    "print(\"Стандартное отклонение цены в контрольной выборке:\", val_data['price'].std())\n",
    "print(\"Стандартное отклонение цены в тестовой выборке:\", test_data['price'].std())\n",
    "print()\n",
    "\n",
    "# Проверка распределений по количеству объектов в диапазонах\n",
    "print(\"Распределение по квартилам (обучающая):\")\n",
    "print(train_data['price'].quantile([0.25, 0.5, 0.75]))\n",
    "print()\n",
    "print(\"Распределение по квартилам (контрольная):\")\n",
    "print(val_data['price'].quantile([0.25, 0.5, 0.75]))\n",
    "print()\n",
    "print(\"Распределение по квартилам (тестовая):\")\n",
    "print(test_data['price'].quantile([0.25, 0.5, 0.75]))\n",
    "\n",
    "# Построение гистограмм для каждой выборки\n",
    "plt.figure(figsize=(12, 6))\n",
    "\n",
    "sns.histplot(train_data['price'], color='blue', label='Train', kde=True)\n",
    "sns.histplot(val_data['price'], color='green', label='Validation', kde=True)\n",
    "sns.histplot(test_data['price'], color='red', label='Test', kde=True)\n",
    "\n",
    "plt.legend()\n",
    "plt.xlabel('price')\n",
    "plt.ylabel('Frequency')\n",
    "plt.title('Распределение цены в обучающей, контрольной и тестовой выборках')\n",
    "plt.show()\n",
    "\n",
    "\n",
    "#9. Оценить  сбалансированность  выборок  для  каждого  набора  данных.  Оценить необходимость использования методов приращения (аугментации) данных. \n",
    "#Выводы по сбалансированности\n",
    "#Если распределение классов примерно равно (например, 50%/50%), выборка считается сбалансированной, и аугментация данных не требуется.\n",
    "#Если один из классов сильно доминирует (например, 90%/10%), выборка несбалансированная, и может потребоваться аугментация данных.\n",
    "\n",
    "#Выборки оказались недостаточно сбалансированными. Используем методы приращения данных с избытком и с недостатком:\n",
    "\n",
    "\n",
    "#10. Выполнить приращение данных методами выборки с избытком (oversampling) и выборки  с  недостатком  (undersampling).  Должны  быть  представлены  примеры реализации обоих методов для выборок набора данных. \n",
    "\n",
    "#10.1\n",
    "#Аугментация данных методом оверсемплинга¶\n",
    "#Этот метод увеличивает количество примеров меньшинства.\n",
    "\n",
    "from imblearn.over_sampling import RandomOverSampler\n",
    "from imblearn.under_sampling import RandomUnderSampler\n",
    "\n",
    "def oversample(df, target_column):\n",
    "    X = df.drop(target_column, axis=1)\n",
    "    y = df[target_column]\n",
    "    \n",
    "    oversampler = RandomOverSampler(random_state=42)\n",
    "    x_resampled, y_resampled = oversampler.fit_resample(X, y)\n",
    "    \n",
    "    resampled_df = pd.concat([x_resampled, y_resampled], axis=1) \n",
    "    return resampled_df\n",
    "\n",
    "def undersample(df, target_column):\n",
    "    X = df.drop(target_column, axis=1)\n",
    "    y = df[target_column]\n",
    "    \n",
    "    undersampler = RandomUnderSampler(random_state=42)\n",
    "    x_resampled, y_resampled = undersampler.fit_resample(X, y)\n",
    "    \n",
    "    resampled_df = pd.concat([x_resampled, y_resampled], axis=1)\n",
    "    return resampled_df\n",
    "\n",
    "train_df_oversampled = oversample(train_data, 'price')\n",
    "val_df_oversampled = oversample(val_data, 'price')\n",
    "test_df_oversampled = oversample(test_data, 'price')\n",
    "\n",
    "train_df_undersampled = undersample(train_data, 'price')\n",
    "val_df_undersampled = undersample(val_data, 'price')\n",
    "test_df_undersampled = undersample(test_data, 'price')\n",
    "\n",
    "# Построение гистограмм для каждой выборки\n",
    "plt.figure(figsize=(12, 6))\n",
    "\n",
    "sns.histplot(train_df_undersampled['price'], color='blue', label='Train', kde=True)\n",
    "sns.histplot(val_df_undersampled['price'], color='green', label='Validation', kde=True)\n",
    "sns.histplot(test_df_undersampled['price'], color='red', label='Test', kde=True)\n",
    "\n",
    "plt.legend()\n",
    "plt.xlabel('price')\n",
    "plt.ylabel('Frequency')\n",
    "plt.title('Распределение цены в обучающей, контрольной и тестовой выборках (андерсемплинг)')\n",
    "plt.show()\n",
    "\n",
    "# Построение гистограмм для каждой выборки\n",
    "plt.figure(figsize=(12, 6))\n",
    "\n",
    "sns.histplot(train_df_oversampled['price'], color='blue', label='Train', kde=True)\n",
    "sns.histplot(val_df_oversampled['price'], color='green', label='Validation', kde=True)\n",
    "sns.histplot(test_df_oversampled['price'], color='red', label='Test', kde=True)\n",
    "\n",
    "plt.legend()\n",
    "plt.xlabel('price')\n",
    "plt.ylabel('Frequency')\n",
    "plt.title('Распределение цены в обучающей, контрольной и тестовой выборках (оверсемплинг)')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Набор данных \"Показатели сердечно-сосудистых заболеваний (за 2022 год)\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "#  1. Анализ сведений о наборе данных\n",
    "#      Этот набор данных из Kaggle, вероятно, относится к исследованию диагностики диабета у женщин индийского происхождения. Набор данных изначально был взят из Национального института диабета и болезней пищеварения и почек (Pima Indians Diabetes Database).\n",
    "#  \n",
    "#      Проблемная область\n",
    "#          Основная проблемная область — медицинская диагностика. Цель данных — предсказать наличие диабета у пациента на основе медицинских показателей (например, уровня глюкозы, давления, ИМТ) и других факторов.\n",
    "#  \n",
    "#  2. Анализ содержимого набора данных\n",
    "#      Объекты наблюдения\n",
    "#          Объектами наблюдения являются медицинские записи пациентов (768 строк). Каждая строка представляет собой данные о состоянии конкретного пациента.\n",
    "#  \n",
    "#      Атрибуты объектов\n",
    "#          Pregnancies (количество беременностей) — числовой признак.\n",
    "#          Glucose (уровень глюкозы в крови) — числовой признак.\n",
    "#          BloodPressure (артериальное давление) — числовой признак.\n",
    "#          SkinThickness (толщина кожной складки) — числовой признак.\n",
    "#          Insulin (уровень инсулина) — числовой признак.\n",
    "#          BMI (индекс массы тела) — вещественный признак.\n",
    "#          DiabetesPedigreeFunction (генетическая предрасположенность к диабету) — вещественный признак.\n",
    "#          Age (возраст) — числовой признак.\n",
    "#          Outcome (наличие диабета) — целевой бинарный признак (1 — диабет, 0 — нет).\n",
    "#          \n",
    "#      Связи между объектами\n",
    "#          Объекты наблюдения независимы друг от друга, так как каждый пациент представлен в одном экземпляре.\n",
    "#  \n",
    "#  3. Примеры бизнес-целей\n",
    "#      Улучшение диагностики диабета\n",
    "#          Создание инструмента для раннего выявления диабета на основе медицинских данных.\n",
    "#          Эффект: Снижение затрат на лечение поздних стадий диабета, повышение уровня здоровья пациентов.\n",
    "#  \n",
    "#      Оптимизация медицинских услуг\n",
    "#          Предсказание риска диабета для отдельных групп населения.\n",
    "#          Эффект: Перераспределение ресурсов на профилактические меры и профилактические программы.\n",
    "#  \n",
    "#      Поддержка медицинских решений\n",
    "#          Автоматизированная рекомендация дополнительных обследований или консультаций для пациентов с высоким риском.\n",
    "#          Эффект: Ускорение процесса диагностики, уменьшение нагрузки на врачей.\n",
    "#  \n",
    "#  4. Примеры целей технического проекта\n",
    "#      Цель 1: Улучшение диагностики диабета\n",
    "#          Вход: Все признаки, кроме Outcome.\n",
    "#          Целевой признак: Outcome (наличие диабета).\n",
    "#          Результат: Модель классификации, которая определяет, есть ли у пациента диабет.\n",
    "#      Цель 2: Оптимизация медицинских услуг\n",
    "#          Вход: Социально-демографические данные (возраст, количество беременностей) и факторы здоровья (ИМТ, глюкоза).\n",
    "#          Целевой признак: Вероятность (риск) наличия диабета.\n",
    "#          Результат: Отчет о вероятности диабета для различных групп пациентов.\n",
    "#      Цель 3: Поддержка медицинских решений\n",
    "#          Вход: Все признаки набора данных.\n",
    "#          Целевой признак: Рекомендации для дальнейших действий (например, \"провести анализ инсулина\", \"назначить консультацию эндокринолога\").\n",
    "#          Результат: Система поддержки принятия решений для врачей.\n",
    "#  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "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>Pregnancies</th>\n",
       "      <th>Glucose</th>\n",
       "      <th>BloodPressure</th>\n",
       "      <th>SkinThickness</th>\n",
       "      <th>Insulin</th>\n",
       "      <th>BMI</th>\n",
       "      <th>DiabetesPedigreeFunction</th>\n",
       "      <th>Age</th>\n",
       "      <th>Outcome</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>6</td>\n",
       "      <td>148</td>\n",
       "      <td>72</td>\n",
       "      <td>35</td>\n",
       "      <td>0</td>\n",
       "      <td>33.6</td>\n",
       "      <td>0.627</td>\n",
       "      <td>50</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>85</td>\n",
       "      <td>66</td>\n",
       "      <td>29</td>\n",
       "      <td>0</td>\n",
       "      <td>26.6</td>\n",
       "      <td>0.351</td>\n",
       "      <td>31</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>8</td>\n",
       "      <td>183</td>\n",
       "      <td>64</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>23.3</td>\n",
       "      <td>0.672</td>\n",
       "      <td>32</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>89</td>\n",
       "      <td>66</td>\n",
       "      <td>23</td>\n",
       "      <td>94</td>\n",
       "      <td>28.1</td>\n",
       "      <td>0.167</td>\n",
       "      <td>21</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>137</td>\n",
       "      <td>40</td>\n",
       "      <td>35</td>\n",
       "      <td>168</td>\n",
       "      <td>43.1</td>\n",
       "      <td>2.288</td>\n",
       "      <td>33</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Pregnancies  Glucose  BloodPressure  SkinThickness  Insulin   BMI  \\\n",
       "0            6      148             72             35        0  33.6   \n",
       "1            1       85             66             29        0  26.6   \n",
       "2            8      183             64              0        0  23.3   \n",
       "3            1       89             66             23       94  28.1   \n",
       "4            0      137             40             35      168  43.1   \n",
       "\n",
       "   DiabetesPedigreeFunction  Age  Outcome  \n",
       "0                     0.627   50        1  \n",
       "1                     0.351   31        0  \n",
       "2                     0.672   32        1  \n",
       "3                     0.167   21        0  \n",
       "4                     2.288   33        1  "
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv('../../datasets/diabetes.csv')\n",
    "df.head()\n",
    "#df.select_dtypes(include=np.number).columns.tolist()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Количество пропущенных значений в каждом столбце:\n",
      "Pregnancies                 0\n",
      "Glucose                     0\n",
      "BloodPressure               0\n",
      "SkinThickness               0\n",
      "Insulin                     0\n",
      "BMI                         0\n",
      "DiabetesPedigreeFunction    0\n",
      "Age                         0\n",
      "Outcome                     0\n",
      "dtype: int64\n",
      "Количество выбросов в столбце 'Pregnancies': 4\n",
      "Количество выбросов в столбце 'Glucose': 5\n",
      "Количество выбросов в столбце 'BloodPressure': 45\n",
      "Количество выбросов в столбце 'SkinThickness': 1\n",
      "Количество выбросов в столбце 'Insulin': 34\n",
      "Количество выбросов в столбце 'BMI': 19\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 153628 characters]",
      "text/plain": [
       "<Figure size 1500x1000 with 6 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "date             0\n",
      "price            0\n",
      "bedrooms         0\n",
      "bathrooms        0\n",
      "sqft_living      0\n",
      "sqft_lot         0\n",
      "floors           0\n",
      "waterfront       0\n",
      "view             0\n",
      "condition        0\n",
      "grade            0\n",
      "sqft_above       0\n",
      "sqft_basement    0\n",
      "yr_built         0\n",
      "yr_renovated     0\n",
      "zipcode          0\n",
      "lat              0\n",
      "long             0\n",
      "sqft_living15    0\n",
      "sqft_lot15       0\n",
      "dtype: int64\n",
      "Обучающая выборка:  (537, 9)\n",
      "Outcome\n",
      "0    349\n",
      "1    188\n",
      "Name: count, dtype: int64\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 19180 characters]",
      "text/plain": [
       "<Figure size 200x200 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Контрольная выборка:  (115, 9)\n",
      "Outcome\n",
      "0    78\n",
      "1    37\n",
      "Name: count, dtype: int64\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 19472 characters]",
      "text/plain": [
       "<Figure size 200x200 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Тестовая выборка:  (116, 9)\n",
      "Outcome\n",
      "0    73\n",
      "1    43\n",
      "Name: count, dtype: int64\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 18284 characters]",
      "text/plain": [
       "<Figure size 200x200 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Обучающая выборка после оверсемплинга:  (677, 9)\n",
      "Outcome\n",
      "0    349\n",
      "1    328\n",
      "Name: count, dtype: int64\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 21620 characters]",
      "text/plain": [
       "<Figure size 200x200 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Обучающая выборка после андерсемплинга:  (376, 9)\n",
      "Outcome\n",
      "0    188\n",
      "1    188\n",
      "Name: count, dtype: int64\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 21552 characters]",
      "text/plain": [
       "<Figure size 200x200 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "import numpy as np\n",
    "\n",
    "df = pd.read_csv('../../datasets/diabetes.csv')\n",
    "#df = df.drop(columns=['name', 'orbiting_body', 'sentry_object'])\n",
    "\n",
    "\n",
    "#5. Устранение пропущенных данных\n",
    "    \n",
    "#Сведения о пропущенных данных\n",
    "print(\"Количество пропущенных значений в каждом столбце:\")\n",
    "print(df.isnull().sum())\n",
    "\n",
    "# Процент пропущенных значений признаков\n",
    "for i in df.columns:\n",
    "    null_rate = df[i].isnull().sum() / len(df) * 100\n",
    "    if null_rate > 0:\n",
    "        print(f'{i} Процент пустых значений: %{null_rate:.2f}')\n",
    "\n",
    "#Пропущенных данных в датасете нет\n",
    "\n",
    "\n",
    "\n",
    "#6. Проблемы набора данных\n",
    "    #5.1Выбросы: Возможны аномалии в значениях скорости или расстояния.\n",
    "    #Смещение: Данные могут быть смещены в сторону объектов, которые легче обнаружить (крупные, близкие).\n",
    "\n",
    "#7. Решения для обнаруженных проблем\n",
    "    #Выбросы: Идентификация и обработка выбросов через методы (например, IQR или Z-оценка).\n",
    "    #Смещение: Использование методов балансировки данных, таких как oversampling.\n",
    "\n",
    "#7.1 Проверка набора данных на выбросы\n",
    "# Выбираем столбцы для анализа\n",
    "columns_to_check = ['Pregnancies','Glucose','BloodPressure','SkinThickness','Insulin','BMI']\n",
    "def Emissions(columns_to_check):\n",
    "\n",
    "    # Функция для подсчета выбросов\n",
    "    def count_outliers(df, columns):\n",
    "        outliers_count = {}\n",
    "        for col in columns:\n",
    "            Q1 = df[col].quantile(0.25)\n",
    "            Q3 = df[col].quantile(0.75)\n",
    "            IQR = Q3 - Q1\n",
    "            lower_bound = Q1 - 1.5 * IQR\n",
    "            upper_bound = Q3 + 1.5 * IQR\n",
    "            \n",
    "            # Считаем количество выбросов\n",
    "            outliers = df[(df[col] < lower_bound) | (df[col] > upper_bound)]\n",
    "            outliers_count[col] = len(outliers)\n",
    "        \n",
    "        return outliers_count\n",
    "\n",
    "    # Подсчитываем выбросы\n",
    "    outliers_count = count_outliers(df, columns_to_check)\n",
    "\n",
    "    # Выводим количество выбросов для каждого столбца\n",
    "    for col, count in outliers_count.items():\n",
    "        print(f\"Количество выбросов в столбце '{col}': {count}\")\n",
    "        \n",
    "    # Создаем гистограммы\n",
    "    plt.figure(figsize=(15, 10))\n",
    "    for i, col in enumerate(columns_to_check, 1):\n",
    "        plt.subplot(2, 3, i)\n",
    "        sns.histplot(df[col], kde=True)\n",
    "        plt.title(f'Histogram of {col}')\n",
    "    plt.tight_layout()\n",
    "    plt.show()\n",
    "Emissions(columns_to_check)\n",
    "\n",
    "#Признакb 'Pregnancies','Glucose','BloodPressure','SkinThickness','Insulin','BMI' имеют количество выбросов в приемлемом диапазоне\n",
    "#Не нужно проводить устранять проблему  пропущенных  данных.\n",
    "\n",
    "#Подстановка константного значения для пропущенных данных. (пример так как кол-во выбросов в пределах нормы)\n",
    "constant_value = 0  # Например, подставим 0\n",
    "df.fillna(constant_value, inplace=True)\n",
    "print(df_cleaned.isna().sum())\n",
    "\n",
    "\n",
    "#8. Разбиение данных на выборки\n",
    "\n",
    "train_data, temp_data = train_test_split(df, test_size=0.3, random_state=42)\n",
    "val_data, test_data = train_test_split(temp_data, test_size=0.5, random_state=42)\n",
    "\n",
    "print(\"Обучающая выборка: \", train_data.shape)\n",
    "print(train_data.Outcome.value_counts())\n",
    "Outcome_counts = train_data['Outcome'].value_counts()\n",
    "plt.figure(figsize=(2, 2))\n",
    "plt.pie(Outcome_counts, labels=Outcome_counts.index, autopct='%1.1f%%', startangle=90)\n",
    "plt.title('Распределение классов Outcome в обучающей выборке')\n",
    "plt.show()\n",
    "\n",
    "print(\"Контрольная выборка: \", val_data.shape)\n",
    "print(val_data.Outcome.value_counts())\n",
    "Outcome_counts = val_data['Outcome'].value_counts()\n",
    "plt.figure(figsize=(2, 2))\n",
    "plt.pie(Outcome_counts, labels=Outcome_counts.index, autopct='%1.1f%%', startangle=90)\n",
    "plt.title('Распределение классов Outcome в контрольной выборке')\n",
    "plt.show()\n",
    "\n",
    "print(\"Тестовая выборка: \", test_data.shape)\n",
    "print(test_data.Outcome.value_counts())\n",
    "Outcome_counts = test_data['Outcome'].value_counts()\n",
    "plt.figure(figsize=(2, 2))\n",
    "plt.pie(Outcome_counts, labels=Outcome_counts.index, autopct='%1.1f%%', startangle=90)\n",
    "plt.title('Распределение классов Outcome в тестовой выборке')\n",
    "plt.show()\n",
    "\n",
    "\n",
    "#9. Оценить  сбалансированность  выборок  для  каждого  набора  данных.  Оценить необходимость использования методов приращения (аугментации) данных. \n",
    "#Выводы по сбалансированности\n",
    "#Если распределение классов примерно равно (например, 50%/50%), выборка считается сбалансированной, и аугментация данных не требуется.\n",
    "#Если один из классов сильно доминирует (например, 90%/10%), выборка несбалансированная, и может потребоваться аугментация данных.\n",
    "\n",
    "#Данная сборка несбалансированная, и требуется аугментация данных.\n",
    "\n",
    "\n",
    "#10. Выполнить приращение данных методами выборки с избытком (oversampling) и выборки  с  недостатком  (undersampling).  Должны  быть  представлены  примеры реализации обоих методов для выборок набора данных. \n",
    "\n",
    "#10.1\n",
    "#Аугментация данных методом оверсемплинга¶\n",
    "#Этот метод увеличивает количество примеров меньшинства.\n",
    "\n",
    "from imblearn.over_sampling import ADASYN\n",
    "\n",
    "# Создание экземпляра ADASYN\n",
    "ada = ADASYN()\n",
    "\n",
    "# Применение ADASYN\n",
    "X_resampled, y_resampled = ada.fit_resample(train_data.drop(columns=['Outcome']), train_data['Outcome'])\n",
    "\n",
    "# Создание нового DataFrame\n",
    "df_train_adasyn = pd.DataFrame(X_resampled)\n",
    "df_train_adasyn['Outcome'] = y_resampled  # Добавление целевой переменной\n",
    "\n",
    "# Вывод информации о новой выборке\n",
    "print(\"Обучающая выборка после оверсемплинга: \", df_train_adasyn.shape)\n",
    "print(df_train_adasyn['Outcome'].value_counts())\n",
    "Outcome_counts = df_train_adasyn['Outcome'].value_counts()\n",
    "plt.figure(figsize=(2, 2))\n",
    "plt.pie(Outcome_counts, labels=Outcome_counts.index, autopct='%1.1f%%', startangle=90)\n",
    "plt.title('Распределение классов Outcome в обучающей выборке после оверсемплинга')\n",
    "plt.show()\n",
    "\n",
    "\n",
    "#10.2\n",
    "#Аугментация данных методом андерсемплинга\n",
    "#Этот метод помогает сбалансировать выборку, уменьшая количество экземпляров класса большинства, чтобы привести его в соответствие с классом меньшинства\n",
    "\n",
    "from imblearn.under_sampling import RandomUnderSampler\n",
    "\n",
    "rus = RandomUnderSampler()\n",
    "\n",
    "# Применение RandomUnderSampler\n",
    "X_resampled, y_resampled = rus.fit_resample(train_data.drop(columns=['Outcome']), train_data['Outcome'])\n",
    "\n",
    "# Создание нового DataFrame\n",
    "df_train_undersampled = pd.DataFrame(X_resampled)\n",
    "df_train_undersampled['Outcome'] = y_resampled  # Добавление целевой переменной\n",
    "\n",
    "# Вывод информации о новой выборке\n",
    "print(\"Обучающая выборка после андерсемплинга: \", df_train_undersampled.shape)\n",
    "print(df_train_undersampled['Outcome'].value_counts())\n",
    "\n",
    "# Визуализация распределения классов\n",
    "Outcome_counts = df_train_undersampled['Outcome'].value_counts()\n",
    "plt.figure(figsize=(2, 2))\n",
    "plt.pie(Outcome_counts, labels=Outcome_counts.index, autopct='%1.1f%%', startangle=90)\n",
    "plt.title('Распределение классов Outcome в обучающей выборке после андерсемплинга')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
