1452 lines
420 KiB
Plaintext
Raw Normal View History

2024-11-02 02:07:49 +04:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Датасет №1 (Использование мобильных устройств и поведение пользователей)\n",
"Ссылка: https://www.kaggle.com/datasets/valakhorasani/mobile-device-usage-and-user-behavior-dataset\n",
"\n",
"Проблемная область: прогнозирование пользовательского поведения и сегментация пользователей для улучшения работы приложений, оптимизации потребления энергии, анализа пользовательского опыта или рекламы.\n",
"\n",
"Объекты наблюдения: пользователи мобильных устройств, чьи данные об использовании собираются и анализируются."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Index(['User ID', 'Device Model', 'Operating System',\n",
" 'App Usage Time (min/day)', 'Screen On Time (hours/day)',\n",
" 'Battery Drain (mAh/day)', 'Number of Apps Installed',\n",
" 'Data Usage (MB/day)', 'Age', 'Gender', 'User Behavior Class'],\n",
" dtype='object')\n"
]
}
],
"source": [
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"import seaborn as sns\n",
"from sklearn.model_selection import train_test_split\n",
"from imblearn.over_sampling import SMOTE\n",
"\n",
"df_mobiles = pd.read_csv(\"..//..//static//csv//user_behavior_data.csv\")\n",
"print(df_mobiles.columns)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Атрибуты объектов:\n",
"* User ID — уникальный идентификатор пользователя.\n",
"* Device Model — модель устройства.\n",
"* Operating System — операционная система устройства.\n",
"* App Usage Time (min/day) — время использования приложений в минутах в день.\n",
"* Screen On Time (hours/day) — время включенного экрана в часах в день.\n",
"* Battery Drain (mAh/day) — потребление батареи в мАч в день.\n",
"* Number of Apps Installed — количество установленных приложений.\n",
"* Data Usage (MB/day) — объем данных в мегабайтах в день.\n",
"* Age — возраст пользователя.\n",
"* Gender — пол пользователя.\n",
"* User Behavior Class — класс поведения пользователя (категория для классификации).\n",
"\n",
"Связи между объектами:\n",
"Атрибуты, такие как модель устройства, ОС и время использования приложений, могут быть связаны с классом поведения, представляя зависимости между действиями пользователя и его характеристиками.\n",
"\n",
"Примеры бизнес-целей и целей технического проекта:\n",
"1. Оптимизация энергопотребления устройств:\n",
" - Бизнес-цель: Оптимизировать работу приложений для снижения расхода батареи, что увеличит время работы устройства и улучшит пользовательский опыт.\n",
" - Эффект: Повышение удовлетворенности клиентов и снижение вероятности перехода на конкурентные приложения.\n",
"\n",
"2. Сегментация пользователей для рекламы:\n",
" - Бизнес-цель: Создание таргетированной рекламы на основе поведения пользователей (классы поведения).\n",
" - Эффект: Увеличение конверсий и доходов от рекламных кампаний за счет более точной сегментации.\n",
"\n",
"3. Цель: Построение модели для прогнозирования расхода батареи.\n",
" - Вход: Модель устройства, ОС, время использования приложений, количество приложений, возраст.\n",
" - Целевой признак: Battery Drain (mAh/day)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Проверка на пустые значения и дубликаты"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Пустые значения по столбцам:\n",
"User ID 0\n",
"Device Model 0\n",
"Operating System 0\n",
"App Usage Time (min/day) 0\n",
"Screen On Time (hours/day) 0\n",
"Battery Drain (mAh/day) 0\n",
"Number of Apps Installed 0\n",
"Data Usage (MB/day) 0\n",
"Age 0\n",
"Gender 0\n",
"User Behavior Class 0\n",
"dtype: int64\n",
"\n",
"Количество дубликатов: 0\n"
]
}
],
"source": [
"null_values = df_mobiles.isnull().sum()\n",
"print(\"Пустые значения по столбцам:\")\n",
"print(null_values)\n",
"\n",
"duplicates = df_mobiles.duplicated().sum()\n",
"print(f\"\\nКоличество дубликатов: {duplicates}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Пустых значений и дубликатов нет, проверим на выбросы:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Количество выбросов в столбце 'App Usage Time (min/day)': 0\n",
"Количество выбросов в столбце 'Screen On Time (hours/day)': 0\n",
"Количество выбросов в столбце 'Battery Drain (mAh/day)': 0\n",
"Количество выбросов в столбце 'Number of Apps Installed': 0\n",
"Количество выбросов в столбце 'Data Usage (MB/day)': 0\n",
"Количество выбросов в столбце 'User Behavior Class': 0\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABc8AAAPeCAYAAADatOK+AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAADskUlEQVR4nOzdd3QU5dvG8SuFdBJCAqEndKQJ0lF6FxFUpIgQsDewU2yAiIAo2FERQTGKIl2KFEEUUYrSfiA1ICpF6b0k9/sHZ/dlZ5OQhIRQvp9zOLozszPPPLuZe+baKT5mZgIAAAAAAAAAAG6+Od0AAAAAAAAAAAAuN4TnAAAAAAAAAAA4EJ4DAAAAAAAAAOBAeA4AAAAAAAAAgAPhOQAAAAAAAAAADoTnAAAAAAAAAAA4EJ4DAAAAAAAAAOBAeA4AAAAAAAAAgAPhOQAAAAAAAAAADoTnyLDt27fLx8dH48aNy+mmeJgzZ46qVKmioKAg+fj46ODBgzndJGRSXFycunfvntPN8PLII4+oWbNmWTrPS7WuixYtko+PjxYtWpRty+jUqZM6dOiQbfMHcGHUaGS1AQMGyMfHJ6eb4WXZsmUKCAjQjh073MPi4uJ0yy235GCrLo3s/kzOnDmjokWL6v3338+2ZQC4eNR8XKyGDRuqYcOGWT7f1157TeXKlVNycnKWzzs9XHXyv//+y9L5jhs3Tj4+Ptq+fXuWzvd8tWvXVu/evbNt/sgcwvMc5PrDO/9f/vz51ahRI82ePfuSt8cVrrn+5cqVSyVKlFC3bt20bdu2LFnGzz//rAEDBmR5Ad23b586dOig4OBgvffeexo/frxCQ0Mv+L73339fPj4+qlWrVpa2JzPSOuBbsWLFZbljlF7O71Za/y5XiYmJ+vjjj/Xcc8/ldFO8zJgxQ76+vtq9e3eOtqNPnz6aNGmSVq9enaPtALICNTrrZLRGr127Vu3bt1dsbKyCgoJUuHBhNWvWTO+8806WtutydOzYMQ0aNEiVK1dWSEiIIiIiVK9ePX322WcysyxbTlxcXLpq8uW83/H888+rc+fOio2NzemmZKmnn35a5cuXz9E25MqVS0899ZQGDx6skydP5mhbgEuBmp91MlLzs6vfX331VU2dOtVreHatc1bo3r27Rz+EhYWpRIkSat++vSZNmpRjIXRmHD58WMOGDVOfPn3k65s9kWPNmjXl4+OjUaNGZdk833nnHUVEROjMmTNZNs/M6NOnj957770cP7aHJ/+cbgCkl19+WcWLF5eZac+ePRo3bpxuvvlmzZgxI0fOnunVq5dq1KihM2fO6LffftNHH32kmTNnau3atSpUqNBFzfvnn3/WwIED1b17d+XJkydrGixp+fLlOnLkiAYNGqSmTZum+30JCQmKi4vTsmXLtGXLFpUqVSrL2oT/d91112n8+PEew/r166ewsDA9//zzXtNv3Lgx2wptZr311lsqXry4GjVqlKXzzYp1nTlzpqpVq6YCBQpkUasyp2rVqqpevbreeOMNffbZZznaFiCrUKMvXkZq9M8//6xGjRqpWLFiuv/++1WgQAHt3LlTv/zyi9566y317Nkzy9p1udmzZ4+aNGmiDRs2qFOnTnrsscd08uRJTZo0SfHx8Zo1a5YSEhLk5+d30ct68803dfToUffrWbNm6csvv9TIkSMVHR3tHl63bl3dfffd6tu370UvMyutWrVK8+fP188//5zTTclyM2fOVJs2bXK6GerRo4f69u2rL774Qvfcc09ONwe4JKj5Fy8zx+VZ3e+vvvqq2rdvr3bt2nkMz651ziqBgYH6+OOPJUknTpzQjh07NGPGDLVv314NGzbUtGnTFB4enqXLnDt3bpbOT5I++eQTnT17Vp07d87yeUvS5s2btXz5csXFxSkhIUEPP/xwlsx35syZat68uXLlypUl88ustm3bKjw8XO+//75efvnlHG0L/h/h+WWgVatWql69uvv1vffeq5iYGH355Zc5UqTr1aun9u3bSzq341ymTBn16tVLn376qfr163fJ25Mee/fulaQMFcHExET9/PPPmjx5sh588EElJCSof//+2dTCa1tMTIzuvvtuj2FDhw5VdHS013Dp3I7D5eTMmTNKSEjQQw89lOXzzop1nTVr1mVzYNuhQwf1799f77//vsLCwnK6OcBFo0ZfvIzU6MGDBysiIkLLly/3mt41n4thZjp58qSCg4Mvel5ZLT4+Xhs2bNCUKVN06623uof36tVLzz77rF5//XVVrVpVffr0uehlOQOF3bt368svv1S7du0UFxfnNb2//+V1yDB27FgVK1ZMtWvXzummpOn48eMKCQlJ9/Tbtm3Txo0b9cEHH2Rjq9InT548at68ucaNG3fZ7GMA2Y2af/Eyc1x+ufV7RmV0W58af39/r2PjV155RUOHDlW/fv10//3366uvvkr1/ZnZxwkICMh0e1MzduxY3XrrrQoKCsryeUvS559/rvz58+uNN95Q+/bttX379hT3XTLi+PHj+uGHH7L0TPbM8vX1Vfv27fXZZ59p4MCBl/XV+deSy+vUTkg6V2iCg4O9DlSOHTump59+WkWLFlVgYKDKli2r119/3X0Z74kTJ1SuXDmVK1dOJ06ccL9v//79KliwoOrWraukpKQMt6dx48aSzoXNafn+++9Vr149hYaGKk+ePGrbtq02bNjgHj9gwAA9++yzkqTixYu7L0m60P2iJk6cqGrVqik4ONgdtv7999/u8Q0bNlR8fLwkqUaNGvLx8UnXPaQTEhIUGRmp1q1bq3379kpISPCaxnUfuddff10jR45UbGysgoOD1aBBA61bt85j2u7duyssLEzbtm1TixYtFBoaqkKFCunll1/O0kutXXbv3q0ePXqoSJEiCgwMVMGCBdW2bVuP/pw2bZpat26tQoUKKTAwUCVLltSgQYNS/B689957KlGihIKDg1WzZk39+OOPKd4D7dSpU+rfv79KlSqlwMBAFS1aVL1799apU6eybN2c9wF3XdL3008/qVevXsqXL5/y5MmjBx98UKdPn9bBgwfVrVs3RUZGKjIyUr179/bq8+TkZL355puqUKGCgoKCFBMTowcffFAHDhy4YHt++ukn/ffff15nT7guqfz66681cOBAFS5cWLlz51b79u116NAhnTp1Sk888YTy58+vsLAw9ejRw6ufUlvXJUuW6KmnnlK+fPkUGhqq2267Tf/++69X29auXaudO3eqdevW7mF//fWX2rVrp9DQUOXPn19PPvlkip/Pjz/+qDvvvFPFihVzf5ZPPvmkx/Zj7Nix8vHx0e+//+71/ldffVV+fn4ef4/NmjXTsWPHNG/evAv2K3AlokZ7yuoavXXrVlWoUCHFg+78+fN7Dfv8889Vs2ZNhYSEKDIyUvXr1/c4i8p1S7TvvvtO1atXV3BwsD788ENJ0sGDB/XEE0+4P7NSpUpp2LBhXpdGp7d+uJb1008/qWbNmgoKClKJEiXSdSXOL7/8ou+++07du3f3CM5dhgwZotKlS2vYsGHu78/5+ygfffSRSpYsqcDAQNWoUUPLly+/4DLTK6X7a/v4+Oixxx7TxIkTVb58eQUHB6tOnTpau3atJOnDDz9UqVKlFBQUpIYNG6b4Pfr111/VsmVLRUREKCQkRA0aNNCSJUvS1aapU6eqcePGqR5Qpucz2LZtm+68807lzZtXISEhql27tmbOnOkxTWr3Nk3pOSINGzZUxYoVtXLlStWvX18hISHuW72tWLFCLVq0UHR0tIKDg1W8ePEUA+mZM2cqIiJCN910k8e61KhRQ0FBQSpZsqT7++s0duxYNW7cWPnz51dgYKDKly/vFQLEx8crOjo6xUvSmzdvrrJly3oMa9asmX766Sft378/xWUCVztqvqfsOi53Sq3fX3/9ddWtW1dRUVEKDg5WtWrV9M0333hM4+Pjo2PHjunTTz91r1f37t3Ttc6ff/65e/3y5s2rTp06aefOnR7zT21bn9Hta0b07dtXzZs318SJE7Vp0yb38LT2cdJTE1zrc/7x/vnHt4MHD1aRIkUUFBSkJk2aaMu
"text/plain": [
"<Figure size 1500x1000 with 6 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"columns_to_check = ['App Usage Time (min/day)', 'Screen On Time (hours/day)', 'Battery Drain (mAh/day)', 'Number of Apps Installed', 'Data Usage (MB/day)', 'User Behavior Class']\n",
"\n",
"def count_outliers(data, columns):\n",
" outliers_count = {}\n",
" for col in columns:\n",
" Q1 = data[col].quantile(0.25)\n",
" Q3 = data[col].quantile(0.75)\n",
" IQR = Q3 - Q1\n",
" lower_bound = Q1 - 1.5 * IQR\n",
" upper_bound = Q3 + 1.5 * IQR\n",
" \n",
" outliers = data[(data[col] < lower_bound) | (data[col] > upper_bound)]\n",
" outliers_count[col] = len(outliers)\n",
" \n",
" return outliers_count\n",
"\n",
"outliers_count = count_outliers(df_mobiles, columns_to_check)\n",
"\n",
"for col, count in outliers_count.items():\n",
" print(f\"Количество выбросов в столбце '{col}': {count}\")\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.boxplot(x=df_mobiles[col])\n",
" plt.title(f'Box Plot of {col}')\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Выбросов нет"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Разбиение набора данных на обучающую, контрольную и тестовую выборки"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Размер обучающей выборки: 420\n",
"Размер контрольной выборки: 140\n",
"Размер тестовой выборки: 140\n"
]
}
],
"source": [
"train_df, test_df = train_test_split(df_mobiles, test_size=0.2, random_state=42)\n",
"\n",
"train_df, val_df = train_test_split(train_df, test_size=0.25, random_state=42)\n",
"\n",
"print(\"Размер обучающей выборки:\", len(train_df))\n",
"print(\"Размер контрольной выборки:\", len(val_df))\n",
"print(\"Размер тестовой выборки:\", len(test_df))"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Распределение \"Класс поведения пользователя\" в обучающей выборке:\n",
"User Behavior Class\n",
"2 88\n",
"5 88\n",
"4 86\n",
"3 84\n",
"1 74\n",
"Name: count, dtype: int64\n",
"\n",
"Распределение \"Класс поведения пользователя\" в контрольной выборке:\n",
"User Behavior Class\n",
"1 35\n",
"2 29\n",
"4 26\n",
"5 25\n",
"3 25\n",
"Name: count, dtype: int64\n",
"\n",
"Распределение \"Класс поведения пользователя\" в тестовой выборке:\n",
"User Behavior Class\n",
"3 34\n",
"2 29\n",
"4 27\n",
"1 27\n",
"5 23\n",
"Name: count, dtype: int64\n",
"\n"
]
}
],
"source": [
"def check_balance(df, name):\n",
" counts = df['User Behavior Class'].value_counts()\n",
" print(f\"Распределение \\\"Класс поведения пользователя\\\" в {name}:\")\n",
" print(counts)\n",
" print()\n",
"\n",
"check_balance(train_df, \"обучающей выборке\")\n",
"check_balance(val_df, \"контрольной выборке\")\n",
"check_balance(test_df, \"тестовой выборке\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Оверсемплинг и андерсемплинг"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Оверсэмплинг:\n",
"Распределение \"Класс поведения пользователя\" в обучающей выборке:\n",
"User Behavior Class\n",
"1 88\n",
"2 88\n",
"5 88\n",
"4 88\n",
"3 88\n",
"Name: count, dtype: int64\n",
"\n",
"Распределение \"Класс поведения пользователя\" в контрольной выборке:\n",
"User Behavior Class\n",
"5 35\n",
"3 35\n",
"1 35\n",
"2 35\n",
"4 35\n",
"Name: count, dtype: int64\n",
"\n",
"Распределение \"Класс поведения пользователя\" в тестовой выборке:\n",
"User Behavior Class\n",
"4 34\n",
"1 34\n",
"2 34\n",
"3 34\n",
"5 34\n",
"Name: count, dtype: int64\n",
"\n",
"Андерсэмплинг:\n",
"Распределение \"Класс поведения пользователя\" в обучающей выборке:\n",
"User Behavior Class\n",
"1 74\n",
"2 74\n",
"3 74\n",
"4 74\n",
"5 74\n",
"Name: count, dtype: int64\n",
"\n",
"Распределение \"Класс поведения пользователя\" в контрольной выборке:\n",
"User Behavior Class\n",
"1 25\n",
"2 25\n",
"3 25\n",
"4 25\n",
"5 25\n",
"Name: count, dtype: int64\n",
"\n",
"Распределение \"Класс поведения пользователя\" в тестовой выборке:\n",
"User Behavior Class\n",
"1 23\n",
"2 23\n",
"3 23\n",
"4 23\n",
"5 23\n",
"Name: count, dtype: int64\n",
"\n"
]
}
],
"source": [
"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) # type: ignore\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) # type: ignore\n",
" \n",
" resampled_df = pd.concat([x_resampled, y_resampled], axis=1)\n",
" return resampled_df\n",
"\n",
"train_df_oversampled = oversample(train_df, 'User Behavior Class')\n",
"val_df_oversampled = oversample(val_df, 'User Behavior Class')\n",
"test_df_oversampled = oversample(test_df, 'User Behavior Class')\n",
"\n",
"train_df_undersampled = undersample(train_df, 'User Behavior Class')\n",
"val_df_undersampled = undersample(val_df, 'User Behavior Class')\n",
"test_df_undersampled = undersample(test_df, 'User Behavior Class')\n",
"\n",
"print(\"Оверсэмплинг:\")\n",
"check_balance(train_df_oversampled, \"обучающей выборке\")\n",
"check_balance(val_df_oversampled, \"контрольной выборке\")\n",
"check_balance(test_df_oversampled, \"тестовой выборке\")\n",
"\n",
"print(\"Андерсэмплинг:\")\n",
"check_balance(train_df_undersampled, \"обучающей выборке\")\n",
"check_balance(val_df_undersampled, \"контрольной выборке\")\n",
"check_balance(test_df_undersampled, \"тестовой выборке\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Датасет №2 (качество воды) \n",
"\n",
"Ссылка: https://www.kaggle.com/datasets/adityakadiwal/water-potability\n",
"\n",
"Проблемная область: качество питьевой воды и факторы, влияющие на ее безопасность для здоровья.\n",
"\n",
"Объекты наблюдения: водоемы, содержащие воду разного качества."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Index(['ph', 'Hardness', 'Solids', 'Chloramines', 'Sulfate', 'Conductivity',\n",
" 'Organic_carbon', 'Trihalomethanes', 'Turbidity', 'Potability'],\n",
" dtype='object')\n"
]
}
],
"source": [
"# вывод всех столбцов\n",
"df = pd.read_csv(\"..//..//static//csv//water_potability.csv\")\n",
"print(df.columns)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Атрибуты: \n",
"* ph параметр для оценки кислотно-щелочного баланса воды;\n",
"* Hardness жесткость воды, определяемая содержанием кальция и магния;\n",
"* Solids общее количество растворенных веществ, указывающее на минерализацию воды;\n",
"* Chloramines концентрация хлора и хлораминов, использующихся для дезинфекции воды;\n",
"* Sulfate содержание сульфатов, присутствующих в воде;\n",
"* Conductivity электропроводность воды, измеряющая уровень ионов в растворе;\n",
"* Organic_carbon уровень органического углерода, происходящего из разлагающихся органических веществ;\n",
"* Trihalomethanes концентрация трихалометанов, образующихся при обработке хлором;\n",
"* Turbidity мутность воды, указывающая на количество взвешенных твердых частиц;\n",
"* Potability показатель пригодности воды для питья (1 пригодна, 0 непригодна).\n",
"\n",
"Примеры бизнес целей и целей технического проекта:\n",
"1. Совершенствование систем очистки воды.\n",
" * Бизнес-цель: разработка и внедрение инновационных технологий очистки воды, чтобы уменьшить расходы на водоочистные сооружения и повысить их эффективность.\n",
" * Цель технического проекта: проектирование и тестирование новых фильтров и процессов очистки на основе данных о загрязнении воды.\n",
"2. Интеграция данных для управления водными ресурсами.\n",
" * Бизнес-цель: объединение данных о водных ресурсах для комплексного анализа и управления, что позволит более эффективно распределять ресурсы.\n",
" * Цель технического проекта: разработка платформы для интеграции данных с различных датчиков и источников информации, использующей машинное обучение для прогнозирования изменений качества воды.\n",
"3. Повышение осведомленности о качестве воды.\n",
" * Бизнес-цель: информирование населения о состоянии водоемов и возможных рисках для здоровья.\n",
" * Цель технического проекта: разработка платформы для публичного доступа к данным о качестве воды.\n",
"\n",
"Входные данные и целевой признак могут быть следующими:\n",
"1. Входные данные:\n",
" * pH значение;\n",
" * Жесткость воды;\n",
" * Общее количество растворенных веществ;\n",
" * Концентрация хлора и хлораминов;\n",
" * Содержание сульфатов;\n",
" * Электропроводность;\n",
" * Уровень органического углерода;\n",
" * Концентрация трихалометанов;\n",
" * Мутность воды.\n",
"2. Целевой признак:\n",
" * Пригодность воды для питья.\n",
"\n",
"Актуальность: анализ качества питьевой воды и факторов, влияющих на ее безопасность, играет очень важную роль в охране здоровья населения. Так мониторинг факторов, влияющих на качество воды, позволит предотвращать вспышки заболеваний и способствовать повышению уровня жизни.\n",
"\n",
"### Проверяем на выбросы"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Количество выбросов в столбце 'Hardness': 83\n",
"Количество выбросов в столбце 'Solids': 47\n",
"Количество выбросов в столбце 'Organic_carbon': 25\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABdIAAAPdCAYAAACOcJpIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAACO4UlEQVR4nOzdd5gV5d0//s8usIW69CJIU2mCWNCvsSARBWyYxBJbwJ5gjcYntgD2FjXGx54I2HuNFXtUwIIIKKIgqFGBAC697/z+8Lfn4bAwLAgsi6/XdXGxZ+aemXvm3nPms+8zZ05OkiRJAAAAAAAAq5Vb0R0AAAAAAIDNmSAdAAAAAABSCNIBAAAAACCFIB0AAAAAAFII0gEAAAAAIIUgHQAAAAAAUgjSAQAAAAAghSAdAAAAAABSCNIBAAAAACCFIB3gJ5g6dWrk5OTE0KFDK7orWV588cXo2rVrFBQURE5OThQXF1d0l9bqjTfeiJycnHjjjTcquisAAPyMqOnL2meffWKfffbJPF6XY9S/f/9o1arVRusbQEURpAObhaFDh0ZOTk7Wv0aNGkWPHj3ihRde2OT9KQ11S/9Vq1Yt2rRpE7/73e/iyy+/3CDbePfdd2Pw4MEbvCCeNWtWHHHEEVFYWBi33HJL3HvvvVGjRo3Vti097h988MFq5++zzz6x/fbbb9D+AQCwZVLTbzjrUtNHRIwbNy4OO+ywaNmyZRQUFMRWW20V++23X9x8880btF8AP2dVK7oDACu79NJLo3Xr1pEkSUyfPj2GDh0aBxxwQDz77LNx0EEHbfL+nHnmmdGtW7dYtmxZjB49Ou6888547rnnYty4cdGsWbOftO533303Lrnkkujfv38UFRVtmA5HxPvvvx/z5s2Lyy67LHr27LnB1gsAAOWhpv/p1qWmf/fdd6NHjx6x9dZbx8knnxxNmjSJb775JkaOHBk33XRTnHHGGT+5Py1btoxFixZFtWrVfvK6ACorQTqwWenTp0/ssssumccnnnhiNG7cOB588MEKKbr32muvOOywwyIi4vjjj4/tttsuzjzzzBg2bFhccMEFm7w/5TFjxoyIiA1ayG8ISZLE4sWLo7CwsKK7AgDARqSm/+nWpaa/4oorok6dOvH++++XaV+6np8qJycnCgoKNsi6ACort3YBNmtFRUVRWFgYVatmv++3YMGCOPfcc6NFixaRn58f7dq1i7/+9a+RJElERCxatCjat28f7du3j0WLFmWWmz17djRt2jR+8YtfxIoVK9a5P7/85S8jImLKlCmp7V577bXYa6+9okaNGlFUVBR9+/aNCRMmZOYPHjw4zjvvvIiIaN26debjplOnTk1d76OPPho777xzFBYWRoMGDeLYY4+Nb7/9NjN/n332iX79+kVERLdu3SInJyf69++/zvuZZsiQIfHLX/4yGjVqFPn5+dGxY8e47bbbyrRr1apVHHTQQfHSSy/FLrvsEoWFhXHHHXdERMR//vOfOPTQQ6NGjRrRqFGj+OMf/xhLliwps47SW8t8+umn0aNHj6hevXpstdVWce2115Zpu2TJkhg0aFBss802kZ+fHy1atIj/+Z//KbPe4cOHx5577hlFRUVRs2bNaNeuXVx44YVZbW6++ebo1KlTVK9ePerWrRu77LJLPPDAAz/lsAEA/Gyp6bNt6Jp+8uTJ0alTp9WG7o0aNcp6vHz58rjsssuibdu2kZ+fH61atYoLL7xwtbX4ytZ0j/Snnnoqtt9++ygoKIjtt98+nnzyydUu/9BDD8XOO+8ctWrVitq1a0fnzp3jpptuSt0mwObGFenAZmXOnDkxc+bMSJIkZsyYETfffHPMnz8/jj322EybJEnikEMOiddffz1OPPHE6Nq1a7z00ktx3nnnxbfffhs33nhjFBYWxrBhw2KPPfaIiy66KG644YaIiDjttNNizpw5MXTo0KhSpco692/y5MkREVG/fv01tnnllVeiT58+0aZNmxg8eHAsWrQobr755thjjz1i9OjR0apVq/j1r38dn3/+eTz44INx4403RoMGDSIiomHDhmtc79ChQ+P444+Pbt26xVVXXRXTp0+Pm266Kd5555346KOPoqioKC666KJo165d3HnnnZmP1LZt23at+1V63Fe1bNmyMtNuu+226NSpUxxyyCFRtWrVePbZZ2PAgAFRUlISp512WlbbiRMnxlFHHRWnnnpqnHzyydGuXbtYtGhR7LvvvvH111/HmWeeGc2aNYt77703XnvttdX27YcffojevXvHr3/96zjiiCPiscceiz//+c/RuXPn6NOnT0RElJSUxCGHHBJvv/12nHLKKdGhQ4cYN25c3HjjjfH555/HU089FRERn3zySRx00EHRpUuXuPTSSyM/Pz8mTZoU77zzTmZ7d911V5x55plx2GGHxVlnnRWLFy+OsWPHxqhRo+Loo49e67EEAPi5U9Nv2pq+ZcuWMWLEiBg/fvxav9/opJNOimHDhsVhhx0W5557bowaNSquuuqqmDBhwhpD8DV5+eWX4ze/+U107Ngxrrrqqpg1a1Ycf/zx0bx586x2w4cPj6OOOir23XffuOaaayIiYsKECfHOO+/EWWedtU7bBKhQCcBmYMiQIUlElPmXn5+fDB06NKvtU089lUREcvnll2dNP+yww5KcnJxk0qRJmWkXXHBBkpubm7z11lvJo48+mkRE8re//W2t/Xn99deTiEjuvvvu5L///W/y3XffJc8991zSqlWrJCcnJ3n//feTJEmSKVOmJBGRDBkyJLNs165dk0aNGiWzZs3KTPv444+T3Nzc5He/+11m2nXXXZdERDJlypS19mfp0qVJo0aNku233z5ZtGhRZvq//vWvJCKSgQMHZqaVHsvSPqZZ03Ff+V+nTp2yllm4cGGZ9fTq1Stp06ZN1rSWLVsmEZG8+OKLWdP/9re/JRGRPPLII5lpCxYsSLbZZpskIpLXX389M7179+5JRCT33HNPZtqSJUuSJk2aJL/5zW8y0+69994kNzc3+fe//521rdtvvz2JiOSdd95JkiRJbrzxxiQikv/+979rPCZ9+/Yts88AAKydmj7dxqrpX3755aRKlSpJlSpVkt133z35n//5n+Sll15Kli5dmtVuzJgxSUQkJ510Utb0P/3pT0lEJK+99lpmWvfu3ZPu3btnHq/pGDVt2jQpLi7O6ktEJC1btsxMO+uss5LatWsny5cvX+u+AGzO3NoF2KzccsstMXz48Bg+fHjcd9990aNHjzjppJPiiSeeyLR5/vnno0qVKnHmmWdmLXvuuedGkiTxwgsvZKYNHjw4OnXqFP369YsBAwZE9+7dyyyX5oQTToiGDRtGs2bN4sADD4wFCxbEsGHDsu75uLLvv/8+xowZE/3794969eplpnfp0iX222+/eP7558u97ZV98MEHMWPGjBgwYEDWvQkPPPDAaN++fTz33HPrtd5SKx/3lf916dKlTNuV73FeerVR9+7d48svv4w5c+ZktW3dunX06tUra9rzzz8fTZs2zdynMiKievXqccopp6y2bzVr1sy6eikvLy923XXX+PLLLzPTHn300ejQoUO0b98+Zs6cmflX+rHd119/PSL+7x6TTz/9dJSUlKx2e0VFRfGf//wn3n///dXOBwAgnZp+9TZWTb/ffvvFiBEj4pBDDomPP/44rr322ujVq1dstdVW8cwzz2Talfb7nHPOyVr+3HPPjYhYp+2XHqN+/fpFnTp1svrSsWPHrLZFRUWxYMGCGD58+DrvG8DmxK1dgM3KrrvumlXQHnXUUbHjjjvG6aefHgcddFDk5eXFV199Fc2aNYtatWplLduhQ4eIiPjqq68y0/Ly8uLuu++Obt26RUFBQQwZMiRycnLK3Z+BAwfGXnvtFVWqVIkGDRpEhw4dytzbcWWl227Xrl2ZeR06dIiXXnopFixYEDVq1Ch3H9a23vbt28fbb7+9Tutb1arHvVTdunXL3PLlnXfeiUGDBsWIESNi4cKFWfPmzJmTVUi3bt26zDq/+uqr2GabbcqMw+r2LSKiefPmZdrWrVs3xo4dm3n
"text/plain": [
"<Figure size 1500x1000 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"columns_to_check = ['Hardness', 'Solids', 'Organic_carbon']\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",
" outliers = df[(df[col] < lower_bound) | (df[col] > upper_bound)]\n",
" outliers_count[col] = len(outliers)\n",
" \n",
" return outliers_count\n",
"\n",
"outliers_count = count_outliers(df, columns_to_check)\n",
"\n",
"for col, count in outliers_count.items():\n",
" print(f\"Количество выбросов в столбце '{col}': {count}\")\n",
"\n",
"plt.figure(figsize=(15, 10))\n",
"for i, col in enumerate(columns_to_check, 1):\n",
" plt.subplot(2, 2, i)\n",
" sns.boxplot(x=df[col])\n",
" plt.title(f'Box Plot of {col}')\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"В каждом из выбранных столбцов присутствуют выбросы. Очистим их."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Количество удаленных строк: 145\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABdIAAAJOCAYAAACz9fURAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABtf0lEQVR4nO3dd5gV5fk/4GcpS69Kl67SBAuWIAoqKqAitmCIUewarIkaNUSxG7sGazQCMcbeYy8oithFUREREY0FDAg2EGTf3x/+9nw97DIsCOwu3vd1cemZec+c953ZOc/M58yZU5BSSgEAAAAAAJSqSnl3AAAAAAAAKjJBOgAAAAAAZBCkAwAAAABABkE6AAAAAABkEKQDAAAAAEAGQToAAAAAAGQQpAMAAAAAQAZBOgAAAAAAZBCkAwAAAABABkE6lcKHH34YBQUFMWbMmPLuSp5HHnkkNtlkk6hZs2YUFBTEvHnzyrtLy/X0009HQUFBPP300+XdlZ/lpZdeisLCwpg5c+ZKPX9tWQ/FDjzwwGjXrl3u8Zw5c6JOnTrx0EMPlV+nAFaSul/SdtttF9ttt13u8Yqso6VrxM/18ccfR82aNWPChAkr9fyKun1X1hlnnBEFBQW5x4sXL47WrVvH1VdfXY69AtYmFfV9szKeD/9cq7qmrmnFNet///tfeXclj2OLfI4tKi5B+i/MmDFjoqCgIO9f06ZNY/vtt4+HH354jfenOMws/le9evXo0KFDHHDAAfHBBx+sktd4/vnn44wzzljlRX3OnDkxZMiQqFWrVlx11VVx0003RZ06dUptW7zeX3nllVLnb7fddrHRRhut0v6t7UaMGBFDhw6Ntm3blph3zz33xMCBA2PdddeNwsLCaNmyZQwZMiSeeuqpcuhp+VhnnXXi0EMPjdNOO628uwKUI3V/1VmRuh8RMXny5Nhnn32ibdu2UbNmzWjVqlXstNNOMWrUqFXar/Jw1llnxVZbbRW9e/cuMe/pp5+OvfbaK5o3bx6FhYXRtGnTGDRoUNx9993l0NPyUb169fjjH/8Y5557bixcuLC8uwP8hLq46qxoXYyIePvtt+N3v/tdtGrVKmrUqBEtW7aM/fbbL95+++1V2jcqH8cW2RxbVBzVyrsDlI+zzjor2rdvHymlmDVrVowZMyZ22WWXeOCBB2K33XZb4/059thjY4sttojFixfHa6+9Fn//+9/jwQcfjMmTJ0fLli1/1rKff/75OPPMM+PAAw+Mhg0brpoOR8TLL78cX3/9dZx99tmx4447rrLlsnyTJk2KJ554Ip5//vm86SmlOPjgg2PMmDGx6aabxh//+Mdo3rx5fPbZZ3HPPfdEv379YsKECbH11luXU8/XrCOPPDL+9re/xVNPPRU77LBDeXcHKEfq/s+3InX/+eefj+233z7atGkThx12WDRv3jw+/vjjeOGFF+KKK66IY4455mf3p23btrFgwYKoXr36z17Wivjiiy9i7NixMXbs2BLzRo4cGWeddVZssMEGccQRR0Tbtm1jzpw58dBDD8Xee+8dN998c/z2t79do/0tLwcddFCccsop8e9//zsOPvjg8u4OsBR18edb0fPhu+++O4YOHRqNGzeOQw45JNq3bx8ffvhh/OMf/4g777wzbr311thzzz1XWf9Wl+uvvz6KiorKuxtrFccWZePYomIQpP9CDRw4MDbffPPc40MOOSSaNWsWt9xyS7kcOGy77baxzz77RMSPbw4bbrhhHHvssTF27Ng49dRT13h/ymL27NkREav0YGRVSCnFwoULo1atWuXdldVm9OjR0aZNm/jVr36VN/2SSy6JMWPGxPHHHx+XXnpp3lehRowYETfddFNUq/bLedvr0qVLbLTRRjFmzBhBOvzCqfs/34rU/XPPPTcaNGgQL7/8con2xcv5uQoKCqJmzZqrZFkr4l//+ldUq1YtBg0alDf9zjvvjLPOOiv22Wef+Pe//50X8J900knx6KOPxuLFi9d0d8tNw4YNY+edd44xY8Y42YUKSF38+VakLk6fPj3233//6NChQ4wfPz6aNGmSm3fcccfFtttuG/vvv3+8+eab0aFDh2Uu59tvv13uVe+r25r+AHtVqQjrblkcW5SNY4uKwa1diIgfd8hatWqVCBm//fbbOOGEE6J169ZRo0aN6NSpU1x88cWRUoqIiAULFkTnzp2jc+fOsWDBgtzz5s6dGy1atIitt946lixZssL9KQ79ZsyYkdnuqaeeim233Tbq1KkTDRs2jMGDB8eUKVNy888444w46aSTIiKiffv2ua/Mffjhh5nLveOOO6Jnz55Rq1atWHfddeN3v/tdfPLJJ7n52223XQwbNiwiIrbYYosoKCiIAw88cIXHmWX06NGxww47RNOmTaNGjRrRtWvXuOaaa0q0a9euXey2227x6KOPxuabbx61atWK6667LiIi/vvf/8Yee+wRderUiaZNm8Yf/vCH+P7770sso/jWMu+8805sv/32Ubt27WjVqlVceOGFJdp+//33MXLkyFh//fWjRo0a0bp16/jTn/5UYrmPP/54bLPNNtGwYcOoW7dudOrUKf785z/ntRk1alR069YtateuHY0aNYrNN988/v3vfy933dx7772xww475AXlCxYsiPPPPz86d+4cF198cd68Yvvvv39sueWWmct+8cUXY8CAAdGgQYOoXbt29O3bt8R92mbOnBnDhw+PTp06Ra1atWKdddaJX//61yX+roq/OjphwoT44x//GE2aNIk6derEnnvuGV988UWJ13744Ydzf8/16tWLXXfdtdSvOd57772x0UYbRc2aNWOjjTaKe+65Z5nj2WmnneKBBx7I7bMAEer+0lZ13Z8+fXp069at1HChadOmeY9/+OGHOPvss6Njx45Ro0aNaNeuXfz5z38utV7/1LLuBVrWGnHrrbdGz549o169elG/fv3o3r17XHHFFZmvWbz8rbbaKurWrZs3/bTTTovGjRvHjTfeWGrI0L9//+WGU++++27ss88+0bhx46hZs2Zsvvnmcf/99+e1mTt3bpx44onRvXv3qFu3btSvXz8GDhwYb7zxRl674tsl3H777XHuuefGeuutFzVr1ox+/frF+++/X+K1y1L/IyKee+652GKLLaJmzZrRsWPH3DFXaXbaaad47rnnYu7cuZnjBsqfuphvVdfFiy66KL777rv4+9//nheiR0Ssu+66cd1118W3336bd/5ZfI/od955J377299Go0aNYptttomIiKKiojjjjDOiZcuWUbt27dh+++3jnXfeiXbt2uX1Y3XUjNLukV5UVBRXXHFFdO/ePWrWrBlNmjSJAQMGLPPWrsvy7rvvxpAhQ6JJkyZRq1at6NSpU4wYMSI3f0XPQ5955pkYPnx4NG3aNNZbb728Nv/73/9iyJAhUb9+/VhnnXXiuOOOK3HLkLIeoxRnEs8991xsueWWUbNmzejQoUP885//LNO4HVs4tqhMfjmXZpJn/vz58b///S9SSjF79uwYNWpUfPPNN/G73/0u1yalFLvvvnuMGzcuDjnkkNhkk03i0UcfjZNOOik++eSTuOyyy6JWrVoxduzY6N27d4wYMSIuvfTSiIg46qijYv78+TFmzJioWrXqCvdv+vTpEfHjfZ6X5YknnoiBAwdGhw4d4owzzogFCxbEqFGjonfv3vHaa69Fu3btYq+99or33nsvbrnllrjsssti3XXXjYgoUbx/asyYMXHQQQfFFltsEeeff37MmjUrrrjiipgwYUK8/vrr0bBhwxgxYkR06tQp/v73v+e+FtixY8fljqt4vS+ttE9Rr7nmmujWrVvsvvvuUa1atXjggQdi+PDhUVRUFEcddVRe26lTp8bQoUPjiCOOiMMOOyw6deoUCxYsiH79+sVHH30Uxx57bLRs2TJuuummZd4n/Msvv4wBAwbEXnvtFUOGDIk777wzTj755OjevXsMHDgwIn48QNh9993jueeei8MPPzy6dOkSkydPjssuuyzee++9uPfeeyPix3vf7bbbbtGjR48466yzokaNGvH+++/nFY3rr78+jj3
"text/plain": [
"<Figure size 1500x600 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Выбираем столбцы для очистки\n",
"columns_to_clean = ['Hardness', 'Solids', 'Organic_carbon']\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_clean)\n",
"\n",
"# Выводим количество удаленных строк\n",
"print(f\"Количество удаленных строк: {len(df) - len(df_cleaned)}\")\n",
"\n",
"# Создаем диаграммы размаха для очищенных данных\n",
"plt.figure(figsize=(15, 6))\n",
"\n",
"# Диаграмма размаха для Hardness\n",
"plt.subplot(1, 3, 1)\n",
"sns.boxplot(x=df_cleaned['Hardness'])\n",
"plt.title('Box Plot of Hardness (Cleaned)')\n",
"plt.xlabel('Hardness')\n",
"\n",
"# Диаграмма размаха для Solids\n",
"plt.subplot(1, 3, 2)\n",
"sns.boxplot(x=df_cleaned['Solids'])\n",
"plt.title('Box Plot of Solids (Cleaned)')\n",
"plt.xlabel('Solids')\n",
"\n",
"# Диаграмма размаха для Organic_carbon\n",
"plt.subplot(1, 3, 3)\n",
"sns.boxplot(x=df_cleaned['Organic_carbon'])\n",
"plt.title('Box Plot of Organic_carbon (Cleaned)')\n",
"plt.xlabel('Organic_carbon')\n",
"\n",
"plt.tight_layout()\n",
"plt.show()\n",
"\n",
"# Сохраняем очищенный датасет\n",
"df_cleaned.to_csv(\"..//..//static//csv//water_potability_cleaned.csv\", index=False)\n",
"df = df_cleaned"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Теперь проверим на пустые значения"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"ph 466\n",
"Hardness 0\n",
"Solids 0\n",
"Chloramines 0\n",
"Sulfate 746\n",
"Conductivity 0\n",
"Organic_carbon 0\n",
"Trihalomethanes 154\n",
"Turbidity 0\n",
"Potability 0\n",
"dtype: int64\n",
"\n",
"ph True\n",
"Hardness False\n",
"Solids False\n",
"Chloramines False\n",
"Sulfate True\n",
"Conductivity False\n",
"Organic_carbon False\n",
"Trihalomethanes True\n",
"Turbidity False\n",
"Potability False\n",
"dtype: bool\n",
"\n",
"ph процент пустых значений: %14.88\n",
"Sulfate процент пустых значений: %23.83\n",
"Trihalomethanes процент пустых значений: %4.92\n"
]
}
],
"source": [
"# Количество пустых значений признаков\n",
"print(df.isnull().sum())\n",
"\n",
"print()\n",
"\n",
"# Есть ли пустые значения признаков\n",
"print(df.isnull().any())\n",
"\n",
"print()\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}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"В трех столбцах встречается большое число пустых значений. Поэтому вместо удаления заменим их значения на медиану."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Количество пустых значений в каждом столбце после замены:\n",
"ph 0\n",
"Hardness 0\n",
"Solids 0\n",
"Chloramines 0\n",
"Sulfate 0\n",
"Conductivity 0\n",
"Organic_carbon 0\n",
"Trihalomethanes 0\n",
"Turbidity 0\n",
"Potability 0\n",
"dtype: int64\n"
]
}
],
"source": [
"# Замена значений\n",
"df[\"ph\"] = df[\"ph\"].fillna(df[\"ph\"].median())\n",
"df[\"Sulfate\"] = df[\"Sulfate\"].fillna(df[\"Sulfate\"].median())\n",
"df[\"Trihalomethanes\"] = df[\"Trihalomethanes\"].fillna(df[\"Trihalomethanes\"].median())\n",
"\n",
"# Проверка на пропущенные значения после замены\n",
"missing_values_after_drop = df.isnull().sum()\n",
"\n",
"# Вывод результатов после замены\n",
"print(\"\\nКоличество пустых значений в каждом столбце после замены:\")\n",
"print(missing_values_after_drop)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Выборки"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Размер обучающей выборки: (1878, 9)\n",
"Размер контрольной выборки: (626, 9)\n",
"Размер тестовой выборки: (627, 9)\n"
]
}
],
"source": [
"X = df.drop('Potability', axis=1)\n",
"y = df['Potability']\n",
"\n",
"X_train, X_rem, y_train, y_rem = train_test_split(X, y, train_size=0.6, random_state=42)\n",
"\n",
"X_val, X_test, y_val, y_test = train_test_split(X_rem, y_rem, test_size=0.5, random_state=42)\n",
"\n",
"print(\"Размер обучающей выборки:\", X_train.shape)\n",
"print(\"Размер контрольной выборки:\", X_val.shape)\n",
"print(\"Размер тестовой выборки:\", X_test.shape)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Распределение классов в обучающей выборке:\n",
"Potability\n",
"0 0.613951\n",
"1 0.386049\n",
"Name: proportion, dtype: float64\n",
"\n",
"Распределение классов в контрольной выборке:\n",
"Potability\n",
"0 0.616613\n",
"1 0.383387\n",
"Name: proportion, dtype: float64\n",
"\n",
"Распределение классов в тестовой выборке:\n",
"Potability\n",
"0 0.614035\n",
"1 0.385965\n",
"Name: proportion, dtype: float64\n"
]
}
],
"source": [
"def analyze_balance(y_train, y_val, y_test):\n",
" print(\"Распределение классов в обучающей выборке:\")\n",
" print(y_train.value_counts(normalize=True))\n",
" \n",
" print(\"\\nРаспределение классов в контрольной выборке:\")\n",
" print(y_val.value_counts(normalize=True))\n",
" \n",
" print(\"\\nРаспределение классов в тестовой выборке:\")\n",
" print(y_test.value_counts(normalize=True))\n",
"\n",
"analyze_balance(y_train, y_val, y_test)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Используем метод оверсемплинг"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Оверсэмплинг:\n",
"Распределение \"Комбинированный расход топлива\" в обучающей выборке:\n",
"combination_mpg\n",
"21 32\n",
"22 32\n",
"25 32\n",
"19 32\n",
"29 32\n",
"23 32\n",
"28 32\n",
"18 32\n",
"27 32\n",
"20 32\n",
"16 32\n",
"30 32\n",
"32 32\n",
"31 32\n",
"24 32\n",
"26 32\n",
"17 32\n",
"36 32\n",
"34 32\n",
"33 32\n",
"14 32\n",
"Name: count, dtype: int64\n",
"\n",
"Распределение \"Комбинированный расход топлива\" в контрольной выборке:\n",
"combination_mpg\n",
"20 17\n",
"19 17\n",
"17 17\n",
"27 17\n",
"22 17\n",
"26 17\n",
"24 17\n",
"32 17\n",
"21 17\n",
"18 17\n",
"30 17\n",
"23 17\n",
"29 17\n",
"28 17\n",
"34 17\n",
"25 17\n",
"14 17\n",
"33 17\n",
"31 17\n",
"Name: count, dtype: int64\n",
"\n",
"Распределение \"Комбинированный расход топлива\" в тестовой выборке:\n",
"combination_mpg\n",
"28 14\n",
"32 14\n",
"30 14\n",
"23 14\n",
"20 14\n",
"26 14\n",
"21 14\n",
"18 14\n",
"27 14\n",
"25 14\n",
"22 14\n",
"19 14\n",
"29 14\n",
"24 14\n",
"31 14\n",
"17 14\n",
"Name: count, dtype: int64\n",
"\n",
"Андерсэмплинг:\n",
"Распределение \"Комбинированный расход топлива\" в обучающей выборке:\n",
"combination_mpg\n",
"14 1\n",
"16 1\n",
"17 1\n",
"18 1\n",
"19 1\n",
"20 1\n",
"21 1\n",
"22 1\n",
"23 1\n",
"24 1\n",
"25 1\n",
"26 1\n",
"27 1\n",
"28 1\n",
"29 1\n",
"30 1\n",
"31 1\n",
"32 1\n",
"33 1\n",
"34 1\n",
"36 1\n",
"Name: count, dtype: int64\n",
"\n",
"Распределение \"Комбинированный расход топлива\" в контрольной выборке:\n",
"combination_mpg\n",
"14 1\n",
"17 1\n",
"18 1\n",
"19 1\n",
"20 1\n",
"21 1\n",
"22 1\n",
"23 1\n",
"24 1\n",
"25 1\n",
"26 1\n",
"27 1\n",
"28 1\n",
"29 1\n",
"30 1\n",
"31 1\n",
"32 1\n",
"33 1\n",
"34 1\n",
"Name: count, dtype: int64\n",
"\n",
"Распределение \"Комбинированный расход топлива\" в тестовой выборке:\n",
"combination_mpg\n",
"17 1\n",
"18 1\n",
"19 1\n",
"20 1\n",
"21 1\n",
"22 1\n",
"23 1\n",
"24 1\n",
"25 1\n",
"26 1\n",
"27 1\n",
"28 1\n",
"29 1\n",
"30 1\n",
"31 1\n",
"32 1\n",
"Name: count, dtype: int64\n",
"\n"
]
}
],
"source": [
"smote = SMOTE(random_state=42)\n",
"\n",
"# Применение SMOTE для балансировки обучающей выборки\n",
"X_train_resampled, y_train_resampled = smote.fit_resample(X_train, y_train)\n",
"\n",
"# Проверка сбалансированности после SMOTE\n",
"print(\"Сбалансированность обучающей выборки после SMOTE:\")\n",
"print(y_train_resampled.value_counts(normalize=True))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Датасет №3 (Экономика стран)\n",
"Ссылка: https://www.kaggle.com/datasets/pratik453609/economic-data-9-countries-19802020\n",
"\n",
"Проблемная область: экономический анализ и прогнозирование макроэкономических показателей.\n",
"\n",
"Объекты наблюдения: экономические индексы по странам за определённые годы."
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Index(['stock index', 'country', 'year', 'index price', 'log_indexprice',\n",
" 'inflationrate', 'oil prices', 'exchange_rate', 'gdppercent',\n",
" 'percapitaincome', 'unemploymentrate', 'manufacturingoutput',\n",
" 'tradebalance', 'USTreasury'],\n",
" dtype='object')\n"
]
}
],
"source": [
"df_countries = pd.read_csv(\"..//..//static//csv//economic_data.csv\")\n",
"print(df_countries.columns)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Атрибуты объектов:\n",
"1. stock index — индекс акций.\n",
"2. country — страна.\n",
"3. year — год.\n",
"4. index price — цена индекса.\n",
"5. log_indexprice — логарифм цены индекса.\n",
"6. inflationrate — уровень инфляции.\n",
"7. oil prices — цены на нефть.\n",
"8. exchange_rate — валютный курс.\n",
"9. gdppercent — процент роста ВВП.\n",
"10. percapitaincome — доход на душу населения.\n",
"11. unemploymentrate — уровень безработицы.\n",
"12. manufacturingoutput — объём производства.\n",
"13. tradebalance — торговый баланс.\n",
"14. USTreasury — доходность казначейских облигаций США.\n",
"\n",
"Связи между объектами:\n",
"Некоторые атрибуты могут быть связаны друг с другом, например, уровень инфляции и процент роста ВВП могут коррелировать с ценами на нефть, уровнем безработицы и торговым балансом.\n",
"\n",
"Примеры бизнес-целей и эффект:\n",
"1. Прогнозирование экономического роста и планирование инвестиций:\n",
" - Бизнес-цель: Создать модель прогнозирования роста экономики для стран, чтобы принять стратегические инвестиционные решения.\n",
" - Эффект: Повышение точности экономических прогнозов и улучшение прибыльности инвестиционных стратегий.\n",
"\n",
"2. Анализ и оптимизация торговой политики:\n",
" - Бизнес-цель: Изучение влияния изменений торгового баланса и валютных курсов на экономику стран.\n",
" - Эффект: Улучшение торговых соглашений и политики, что приведёт к более устойчивому экономическому росту.\n",
"\n",
"Примеры целей технического проекта:\n",
"1. Цель: Построение модели для прогнозирования уровня инфляции.\n",
" - Вход: Уровень безработицы, ВВП, доход на душу населения, валютный курс, цены на нефть.\n",
" - Целевой признак: inflationrate.\n",
"\n",
"2. Цель: Построение модели для оценки экономического роста.\n",
" - Вход: Торговый баланс, доход на душу населения, валютный курс, инфляция.\n",
" - Целевой признак: gdppercent."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Проверка на пустые значения и дубликаты"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Пустые значения по столбцам:\n",
"stock index 0\n",
"country 0\n",
"year 0\n",
"index price 52\n",
"log_indexprice 0\n",
"inflationrate 43\n",
"oil prices 0\n",
"exchange_rate 2\n",
"gdppercent 19\n",
"percapitaincome 1\n",
"unemploymentrate 21\n",
"manufacturingoutput 91\n",
"tradebalance 4\n",
"USTreasury 0\n",
"dtype: int64\n",
"\n",
"Количество дубликатов: 0\n"
]
}
],
"source": [
"null_values = df_countries.isnull().sum()\n",
"print(\"Пустые значения по столбцам:\")\n",
"print(null_values)\n",
"\n",
"duplicates = df_countries.duplicated().sum()\n",
"print(f\"\\nКоличество дубликатов: {duplicates}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Видим, что есть пустые данные, но нет дубликатов. Удаляем их"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"В наборе данных 'Countries' было удалено 150 строк с пустыми значениями.\n"
]
}
],
"source": [
"def drop_missing_values(dataframe, name):\n",
" before_shape = dataframe.shape \n",
" cleaned_dataframe = dataframe.dropna() \n",
" after_shape = cleaned_dataframe.shape \n",
" print(f\"В наборе данных '{name}' было удалено {before_shape[0] - after_shape[0]} строк с пустыми значениями.\")\n",
" return cleaned_dataframe\n",
"\n",
"df_countries = drop_missing_values(df_countries, \"Countries\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Проверка на выбросы:"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Количество выбросов в столбце 'year': 0\n",
"Количество выбросов в столбце 'index price': 17\n",
"Количество выбросов в столбце 'log_indexprice': 1\n",
"Количество выбросов в столбце 'inflationrate': 35\n",
"Количество выбросов в столбце 'oil prices': 0\n",
"Количество выбросов в столбце 'exchange_rate': 53\n",
"Количество выбросов в столбце 'gdppercent': 13\n",
"Количество выбросов в столбце 'percapitaincome': 0\n",
"Количество выбросов в столбце 'unemploymentrate': 9\n",
"Количество выбросов в столбце 'manufacturingoutput': 29\n",
"Количество выбросов в столбце 'tradebalance': 47\n",
"Количество выбросов в столбце 'USTreasury': 9\n"
]
},
{
"data": {
"image/png": "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h0NPP/205s6da50Dv//+e0nSuHHj1KBBAxUsWFB+fn6KiIjQV199leTx//77r2bPnm3tQ+LxP3LkiHr16qUiRYrIx8dHlStX1syZM5MdN6QNV6DncnFxcTp16pSMMTpx4oQ+/PBDnT9/Xl27drXaGGPUvn17rVy5Ur1791aNGjW0dOlSvfDCCzpy5IgmTJggPz8/zZ49W3fffbeGDh2q8ePHS5KeeuopxcXFKSoqKl2fLB48eFCSVLBgwWTbLF++XK1atVLp0qU1YsQIXbx4UR9++KHuvvtu/fbbbypZsqQ6duyo33//XZ999pkmTJigQoUKSZJCQkKS7TcqKko9e/ZUnTp1NGbMGB0/flwTJ07UmjVrtGXLFgUFBWno0KEqX768pk+fbn3dq0yZMrb9NW7cWCVKlNDcuXP1wAMPuKybO3euypQpo/r160u6XrS5++67VaxYMb388svKly+fvvzyS91///36+uuvrcf/8ccfWrBggR5++GGVKlVKx48f17Rp0xQZGandu3cn+VrXG2+8IW9vbw0ZMkSXL1++7a62AbIaOTfzcu7NHDhwQA899JB69+6t7t27a+bMmerRo4ciIiJUuXJlSdI///yjJk2a6Nq1a1Yenj59uvz8/JL0N2fOHHXv3l0tWrTQO++8owsXLmjKlCm65557tGXLFpUsWVL33nuvBgwYoDFjxuj+++9XrVq1dOzYMT3zzDNq1qyZnnzyyRTjPnPmjFq3bq1OnTqpc+fO+vLLL9W/f395e3urV69eLm1Tm++XLVumtm3bKjQ0VM8++6yKFi2qPXv26LvvvtOzzz4rKfXnJCA3IE9nfZ4eMWKERo4cqWbNmql///7at2+fpkyZoo0bN2rNmjXWV+inTJmip59+Wg0bNtRzzz2nQ4cO6f7771eBAgVUvHjxNG0zOW+//bY8PDw0ZMgQxcXFaezYserSpYvWr19vtZkxY4b69eunBg0aaNCgQfrjjz/Uvn17BQcHq0SJEla7hIQEtW/fXr/88oueeOIJVaxYUTt27NCECRP0+++/W/esnThxolasWKHu3btr3bp18vT01LRp0/TDDz9ozpw5Seb3Tz/9tIKCgjRixAhrrA4fPmx9COC0b98+de7cWf369VPfvn1Vvnx5230+f/68GjZsqD179qhXr16qVauWTp06pf/973/6+++/VahQoVTvC5DTcA7I+nOAlPJcvWPHjgoKCtJzzz2nzp07q3Xr1vL3979p7P7+/ho8eLD8/f21YsUKDRs2TGfPntW7774rSRo6dKji4uL0999/a8KECZJ00z5TM86JderUSaVKldKYMWP022+/6b///a8KFy6sd955x6XdihUr9OWXX+rpp59WoUKFrH4mTpyo9u3bq0uXLrpy5Yo+//xzPfzww/ruu+/Upk0bSdffk/Tp00d169bVE088IUnW+B8/flz16tWzivQhISFasmSJevfurbNnzya5bQ3SwSBXmjVrlpGU5J+Pj4+JiopyabtgwQIjybz55psuyx966CHjcDjMgQMHrGWvvPKK8fDwMD///LOZN2+ekWTef//9FONZuXKlkWRmzpxpTp48aY4ePWoWLVpkSpYsaRwOh9m4caMxxpjo6GgjycyaNct6bI0aNUzhwoXN6dOnrWXbtm0zHh4eplu3btayd99
"text/plain": [
"<Figure size 1500x1000 with 12 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"columns_to_check = ['year', 'index price', 'log_indexprice',\n",
" 'inflationrate', 'oil prices', 'exchange_rate', 'gdppercent',\n",
" 'percapitaincome', 'unemploymentrate', 'manufacturingoutput',\n",
" 'tradebalance', 'USTreasury']\n",
"\n",
"outliers_count = count_outliers(df_countries, columns_to_check)\n",
"\n",
"for col, count in outliers_count.items():\n",
" print(f\"Количество выбросов в столбце '{col}': {count}\")\n",
"\n",
"plt.figure(figsize=(15, 10))\n",
"for i, col in enumerate(columns_to_check, 1):\n",
" plt.subplot(3, 4, i)\n",
" sns.boxplot(x=df_countries[col])\n",
" plt.title(f'Box Plot of {col}')\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"В большинстве из выбранных столбцов присутствуют выбросы. Очистим их."
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Количество удаленных строк: 136\n"
]
},
{
"data": {
"text/plain": [
"<Figure size 1500x600 with 0 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1500x1000 with 9 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<Figure size 640x480 with 0 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"columns_to_clean = ['index price', 'log_indexprice',\n",
" 'inflationrate', 'exchange_rate', 'gdppercent', 'unemploymentrate', 'manufacturingoutput',\n",
" 'tradebalance', 'USTreasury']\n",
"\n",
"df_countries_clean = remove_outliers(df_countries, columns_to_clean)\n",
"\n",
"print(f\"Количество удаленных строк: {len(df_countries) - len(df_countries_clean)}\")\n",
"\n",
"plt.figure(figsize=(15, 6))\n",
"\n",
"plt.figure(figsize=(15, 10))\n",
"for i, col in enumerate(columns_to_clean, 1):\n",
" plt.subplot(3, 3, i)\n",
" sns.boxplot(x=df_countries_clean[col])\n",
" plt.title(f'Box Plot of {col}')\n",
"plt.tight_layout()\n",
"plt.show()\n",
"\n",
"plt.tight_layout()\n",
"plt.show()\n",
"\n",
"df_countries = df_countries_clean"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Разбиение набора данных на обучающую, контрольную и тестовую выборки"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Размер обучающей выборки: 49\n",
"Размер контрольной выборки: 17\n",
"Размер тестовой выборки: 17\n"
]
}
],
"source": [
"train_df, test_df = train_test_split(df_countries, test_size=0.2, random_state=42)\n",
"\n",
"train_df, val_df = train_test_split(train_df, test_size=0.25, random_state=42)\n",
"\n",
"print(\"Размер обучающей выборки:\", len(train_df))\n",
"print(\"Размер контрольной выборки:\", len(val_df))\n",
"print(\"Размер тестовой выборки:\", len(test_df))"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Распределение \"Уровень инфляции\" в обучающей выборке:\n",
"inflationrate\n",
"0.02 25\n",
"0.03 11\n",
"0.01 9\n",
"0.04 4\n",
"Name: count, dtype: int64\n",
"\n",
"Распределение \"Уровень инфляции\" в контрольной выборке:\n",
"inflationrate\n",
"0.03 6\n",
"0.01 6\n",
"0.02 5\n",
"Name: count, dtype: int64\n",
"\n",
"Распределение \"Уровень инфляции\" в тестовой выборке:\n",
"inflationrate\n",
"0.02 6\n",
"0.03 6\n",
"0.01 4\n",
"0.04 1\n",
"Name: count, dtype: int64\n",
"\n"
]
}
],
"source": [
"def check_balance(df, name):\n",
" counts = df['inflationrate'].value_counts()\n",
" print(f\"Распределение \\\"Уровень инфляции\\\" в {name}:\")\n",
" print(counts)\n",
" print()\n",
"\n",
"check_balance(train_df, \"обучающей выборке\")\n",
"check_balance(val_df, \"контрольной выборке\")\n",
"check_balance(test_df, \"тестовой выборке\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Оверсемплинг и андерсемплинг"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Оверсэмплинг:\n",
"Распределение \"Уровень инфляции\" в обучающей выборке:\n",
"inflationrate\n",
"0.03 26\n",
"0.02 25\n",
"0.01 9\n",
"0.04 8\n",
"Name: count, dtype: int64\n",
"\n",
"Распределение \"Уровень инфляции\" в контрольной выборке:\n",
"inflationrate\n",
"0.03 11\n",
"0.01 6\n",
"0.02 5\n",
"Name: count, dtype: int64\n",
"\n",
"Распределение \"Уровень инфляции\" в тестовой выборке:\n",
"inflationrate\n",
"0.03 8\n",
"0.02 6\n",
"0.01 4\n",
"0.04 2\n",
"Name: count, dtype: int64\n",
"\n",
"Андерсэмплинг:\n",
"Распределение \"Уровень инфляции\" в обучающей выборке:\n",
"inflationrate\n",
"0.03 11\n",
"0.02 10\n",
"0.01 5\n",
"0.04 4\n",
"Name: count, dtype: int64\n",
"\n",
"Распределение \"Уровень инфляции\" в контрольной выборке:\n",
"inflationrate\n",
"0.03 6\n",
"0.01 4\n",
"0.02 2\n",
"Name: count, dtype: int64\n",
"\n",
"Распределение \"Уровень инфляции\" в тестовой выборке:\n",
"inflationrate\n",
"0.03 6\n",
"0.02 5\n",
"0.01 2\n",
"0.04 1\n",
"Name: count, dtype: int64\n",
"\n"
]
}
],
"source": [
"def binning(target, bins):\n",
" return pd.qcut(target, q=bins, labels=False)\n",
"\n",
"train_df['inflationrate_binned'] = binning(train_df['inflationrate'], bins=2)\n",
"val_df['inflationrate_binned'] = binning(val_df['inflationrate'], bins=2)\n",
"test_df['inflationrate_binned'] = binning(test_df['inflationrate'], bins=2)\n",
"\n",
"train_df_oversampled = oversample(train_df, 'inflationrate_binned')\n",
"val_df_oversampled = oversample(val_df, 'inflationrate_binned')\n",
"test_df_oversampled = oversample(test_df, 'inflationrate_binned')\n",
"\n",
"train_df_undersampled = undersample(train_df, 'inflationrate_binned')\n",
"val_df_undersampled = undersample(val_df, 'inflationrate_binned')\n",
"test_df_undersampled = undersample(test_df, 'inflationrate_binned')\n",
"\n",
"print(\"Оверсэмплинг:\")\n",
"check_balance(train_df_oversampled, \"обучающей выборке\")\n",
"check_balance(val_df_oversampled, \"контрольной выборке\")\n",
"check_balance(test_df_oversampled, \"тестовой выборке\")\n",
"\n",
"print(\"Андерсэмплинг:\")\n",
"check_balance(train_df_undersampled, \"обучающей выборке\")\n",
"check_balance(val_df_undersampled, \"контрольной выборке\")\n",
"check_balance(test_df_undersampled, \"тестовой выборке\")"
]
}
],
"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
}