AIM-PIbd-31-Masenkin-M-S/lab_2/lab2.ipynb

1031 lines
378 KiB
Plaintext
Raw Normal View History

2024-10-17 00:52:35 +04:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Датасет №1: [Объекты вокруг Земли](https://www.kaggle.com/datasets/sameepvani/nasa-nearest-earth-objects).\n",
"\n",
"### Описание датасета:\n",
"Данный набор данных представляет собой коллекцию сведений о ближайших к Земле объектах (астероидах), сертифицированных NASA. Он содержит данные, которые могут помочь идентифицировать потенциально опасные астероиды, которые могут оказать влияние на Землю или на космические миссии. Набор данных включает в себя такие ключевые характеристики астероидов, как их размер, скорость, расстояние до Земли и информация о возможной опасности столкновения.\n",
"\n",
"---\n",
"\n",
"### Анализ сведений:\n",
"**Проблемная область:**\n",
"Основной проблемной областью является отслеживание и оценка рисков, связанных с приближением астероидов к Земле. С помощью данных о движении и характеристиках астероидов можно предсказать возможные столкновения и минимизировать угрозу для Земли, планируя превентивные действия.\n",
"\n",
"**Актуальность:**\n",
"Набор данных высокоактуален для задач оценки рисков от космических объектов, мониторинга космического пространства и разработки превентивных мер по защите Земли. Также он важен для научных исследований в области астрономии и планетарной безопасности.\n",
"\n",
"**Объекты наблюдения:**\n",
"Объектами наблюдения в данном наборе данных являются астероиды, классифицированные NASA как \"ближайшие к Земле объекты\" (Near-Earth Objects, NEO). Эти объекты могут проходить в непосредственной близости от Земли, что потенциально представляет опасность.\n",
"\n",
"**Атрибуты объектов:**\n",
"- id: Уникальный идентификатор астероида.\n",
"- name: Название, присвоенное астероиду NASA.\n",
"- est_diameter_min: Минимальный оценочные диаметры астероида в километрах.\n",
"- 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",
"\n",
"---\n",
"\n",
"### Качество набора данных:\n",
"**Информативность:**\n",
"Датасет предоставляет важные сведения о ключевых характеристиках астероидов, такие как размер, скорость и расстояние от Земли, что позволяет проводить качественный анализ их потенциальной опасности.\n",
"\n",
"**Степень покрытия:**\n",
"Набор данных включает данные о большом количестве астероидов (>90000 записей), что позволяет охватить значительную часть ближайших к Земле объектов. Однако не все астероиды могут быть обнаружены, так как данные зависят от возможности их наблюдения.\n",
"\n",
"**Соответствие реальным данным:**\n",
"Данные в наборе предоставлены NASA, что указывает на высокую достоверность и актуальность информации. Тем не менее, параметры, такие как диаметр и расстояние, могут быть оценочными и подвергаться уточнению с новыми наблюдениями.\n",
"\n",
"**Согласованность меток:**\n",
"Метрики в датасете четко обозначены, а булевы признаки, такие как \"hazardous\" (опасен или нет), соответствуют конкретным параметрам астероидов и легко интерпретируются.\n",
"\n",
"---\n",
"\n",
"### Бизес-цели:\n",
"1. **Мониторинг космических угроз:**\n",
"Создание системы, которая анализирует астероиды и предсказывает риски столкновения с Землей, помогая государственным агентствам и частным компаниям разрабатывать превентивные меры.\n",
"2. **Поддержка космических миссий:**\n",
"Предоставление точных данных для планирования и безопасного проведения космических миссий, минимизация рисков столкновения с космическими объектами.\n",
"3. **Образовательные и научные исследования:**\n",
"Использование данных для поддержки образовательных программ и научных исследований в области астрономии и космической безопасности.\n",
"\n",
"**Эффект для бизнеса:**\n",
"Набор данных способствует развитию технологий космической безопасности, минимизирует финансовые риски от потенциальных катастроф и поддерживает стратегическое планирование космических миссий.\n",
"\n",
"---\n",
"\n",
"### Технические цели:\n",
"1. **Моделирование риска столкновения:**\n",
"Построение алгоритмов машинного обучения для прогнозирования вероятности столкновения астероидов с Землей.\n",
"2. **Анализ и кластеризация астероидов:**\n",
"Исследование взаимосвязей между астероидами, анализ орбитальных данных и выделение групп астероидов, имеющих схожие характеристики.\n",
"3. **Оптимизация системы предупреждения угроз:**\n",
"Создание системы раннего оповещения, которая будет автоматически анализировать данные и предупреждать о потенциальных угрозах в реальном времени.\n",
"\n",
"**Входные данные:**\n",
"Диаметр, скорость, расстояние, орбитальные параметры астероидов.\n",
"\n",
"**Целевой признак:**\n",
2024-10-17 12:31:09 +04:00
"Признак \"hazardous\" бинарная метка, указывающая на потенциальную опасность астероида.\n",
"\n",
"---"
2024-10-17 00:52:35 +04:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Выгрузка данных из файла в DataFrame:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from typing import Any\n",
2024-10-17 12:31:09 +04:00
"from math import ceil\n",
2024-10-17 00:52:35 +04:00
"\n",
"import pandas as pd\n",
"from pandas import DataFrame, Series\n",
"from sklearn.model_selection import train_test_split\n",
"from imblearn.over_sampling import ADASYN\n",
"from imblearn.under_sampling import RandomUnderSampler\n",
"import matplotlib.pyplot as plt\n",
"\n",
"\n",
"df: DataFrame = pd.read_csv('..//static//csv//neo.csv')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Краткая информация о DataFrame:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"RangeIndex: 90836 entries, 0 to 90835\n",
"Data columns (total 10 columns):\n",
" # Column Non-Null Count Dtype \n",
"--- ------ -------------- ----- \n",
" 0 id 90836 non-null int64 \n",
" 1 name 90836 non-null object \n",
" 2 est_diameter_min 90836 non-null float64\n",
" 3 est_diameter_max 90836 non-null float64\n",
" 4 relative_velocity 90836 non-null float64\n",
" 5 miss_distance 90836 non-null float64\n",
" 6 orbiting_body 90836 non-null object \n",
" 7 sentry_object 90836 non-null bool \n",
" 8 absolute_magnitude 90836 non-null float64\n",
" 9 hazardous 90836 non-null bool \n",
"dtypes: bool(2), float64(5), int64(1), object(2)\n",
2024-10-17 12:31:09 +04:00
"memory usage: 5.7+ MB\n"
2024-10-17 00:52:35 +04:00
]
2024-10-17 12:31:09 +04:00
},
{
"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>est_diameter_min</th>\n",
" <th>est_diameter_max</th>\n",
" <th>relative_velocity</th>\n",
" <th>miss_distance</th>\n",
" <th>absolute_magnitude</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>count</th>\n",
" <td>9.083600e+04</td>\n",
" <td>90836.000000</td>\n",
" <td>90836.000000</td>\n",
" <td>90836.000000</td>\n",
" <td>9.083600e+04</td>\n",
" <td>90836.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>mean</th>\n",
" <td>1.438288e+07</td>\n",
" <td>0.127432</td>\n",
" <td>0.284947</td>\n",
" <td>48066.918918</td>\n",
" <td>3.706655e+07</td>\n",
" <td>23.527103</td>\n",
" </tr>\n",
" <tr>\n",
" <th>std</th>\n",
" <td>2.087202e+07</td>\n",
" <td>0.298511</td>\n",
" <td>0.667491</td>\n",
" <td>25293.296961</td>\n",
" <td>2.235204e+07</td>\n",
" <td>2.894086</td>\n",
" </tr>\n",
" <tr>\n",
" <th>min</th>\n",
" <td>2.000433e+06</td>\n",
" <td>0.000609</td>\n",
" <td>0.001362</td>\n",
" <td>203.346433</td>\n",
" <td>6.745533e+03</td>\n",
" <td>9.230000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>25%</th>\n",
" <td>3.448110e+06</td>\n",
" <td>0.019256</td>\n",
" <td>0.043057</td>\n",
" <td>28619.020645</td>\n",
" <td>1.721082e+07</td>\n",
" <td>21.340000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>50%</th>\n",
" <td>3.748362e+06</td>\n",
" <td>0.048368</td>\n",
" <td>0.108153</td>\n",
" <td>44190.117890</td>\n",
" <td>3.784658e+07</td>\n",
" <td>23.700000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>75%</th>\n",
" <td>3.884023e+06</td>\n",
" <td>0.143402</td>\n",
" <td>0.320656</td>\n",
" <td>62923.604633</td>\n",
" <td>5.654900e+07</td>\n",
" <td>25.700000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>max</th>\n",
" <td>5.427591e+07</td>\n",
" <td>37.892650</td>\n",
" <td>84.730541</td>\n",
" <td>236990.128088</td>\n",
" <td>7.479865e+07</td>\n",
" <td>33.200000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" id est_diameter_min est_diameter_max relative_velocity \\\n",
"count 9.083600e+04 90836.000000 90836.000000 90836.000000 \n",
"mean 1.438288e+07 0.127432 0.284947 48066.918918 \n",
"std 2.087202e+07 0.298511 0.667491 25293.296961 \n",
"min 2.000433e+06 0.000609 0.001362 203.346433 \n",
"25% 3.448110e+06 0.019256 0.043057 28619.020645 \n",
"50% 3.748362e+06 0.048368 0.108153 44190.117890 \n",
"75% 3.884023e+06 0.143402 0.320656 62923.604633 \n",
"max 5.427591e+07 37.892650 84.730541 236990.128088 \n",
"\n",
" miss_distance absolute_magnitude \n",
"count 9.083600e+04 90836.000000 \n",
"mean 3.706655e+07 23.527103 \n",
"std 2.235204e+07 2.894086 \n",
"min 6.745533e+03 9.230000 \n",
"25% 1.721082e+07 21.340000 \n",
"50% 3.784658e+07 23.700000 \n",
"75% 5.654900e+07 25.700000 \n",
"max 7.479865e+07 33.200000 "
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
2024-10-17 00:52:35 +04:00
}
],
"source": [
"# Краткая информация о DataFrame\n",
"df.info()\n",
"\n",
"# Статистическое описание числовых столбцов\n",
2024-10-17 12:31:09 +04:00
"df.describe()"
2024-10-17 00:52:35 +04:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Проблема пропущенных данных:\n",
"\n",
"**Проблема пропущенных данных** — это отсутствие значений в наборе данных, что может искажать результаты анализа и статистические выводы.\n",
"\n",
"Проверка на отсутствие значений, представленная ниже, показала, что DataFrame не имеет пустых значений признаков. Нет необходимости использовать методы заполнения пропущенных данных."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"id False\n",
"name False\n",
"est_diameter_min False\n",
"est_diameter_max False\n",
"relative_velocity False\n",
"miss_distance False\n",
"orbiting_body False\n",
"sentry_object False\n",
"absolute_magnitude False\n",
"hazardous False\n",
"dtype: bool \n",
"\n",
"id 0\n",
"name 0\n",
"est_diameter_min 0\n",
"est_diameter_max 0\n",
"relative_velocity 0\n",
"miss_distance 0\n",
"orbiting_body 0\n",
"sentry_object 0\n",
"absolute_magnitude 0\n",
"hazardous 0\n",
"dtype: int64\n"
]
}
],
"source": [
"# Проверка пропущенных данных\n",
"def check_null_columns(dataframe: DataFrame) -> None:\n",
" # Присутствуют ли пустые значения признаков\n",
" print(dataframe.isnull().any(), '\\n')\n",
"\n",
" # Количество пустых значений признаков\n",
" print(dataframe.isnull().sum())\n",
"\n",
" # Процент пустых значений признаков\n",
" for i in dataframe.columns:\n",
" null_rate: float = dataframe[i].isnull().sum() / len(dataframe) * 100\n",
" if null_rate > 0:\n",
" print(f\"{i} процент пустых значений: %{null_rate:.2f}\")\n",
" \n",
"\n",
"# Проверка пропущенных данных\n",
"check_null_columns(df)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Проблема зашумленности данных:\n",
"\n",
"**Зашумленность** это наличие случайных ошибок или вариаций в данных, которые могут затруднить выявление истинных закономерностей. Шум может возникать из-за ошибок измерений, неправильных записей или других факторов.\n",
"\n",
"**Выбросы** это значения, которые значительно отличаются от остальных наблюдений в наборе данных. Выбросы могут указывать на ошибки в данных или на редкие, но важные события. Их наличие может повлиять на статистические методы анализа.\n",
"\n",
"Представленный ниже код помогает определить наличие выбросов в наборе данных и устранить их (при наличии), заменив значения ниже нижней границы (рассматриваемого минимума) на значения нижней границы, а значения выше верхней границы (рассматриваемого максимума) на значения верхней границы."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Колонка est_diameter_min:\n",
"\tЕсть выбросы: Да\n",
"\tКоличество выбросов: 8306\n",
"\tМинимальное значение: 0.0006089126\n",
2024-10-17 12:31:09 +04:00
"\tМаксимальное значение: 37.8926498379\n",
2024-10-17 00:52:35 +04:00
"\t1-й квартиль (Q1): 0.0192555078\n",
"\t3-й квартиль (Q3): 0.1434019235\n",
"\n",
"Колонка est_diameter_max:\n",
"\tЕсть выбросы: Да\n",
"\tКоличество выбросов: 8306\n",
"\tМинимальное значение: 0.00136157\n",
2024-10-17 12:31:09 +04:00
"\tМаксимальное значение: 84.7305408852\n",
2024-10-17 00:52:35 +04:00
"\t1-й квартиль (Q1): 0.0430566244\n",
"\t3-й квартиль (Q3): 0.320656449\n",
"\n",
"Колонка relative_velocity:\n",
"\tЕсть выбросы: Да\n",
"\tКоличество выбросов: 1574\n",
"\tМинимальное значение: 203.34643253\n",
2024-10-17 12:31:09 +04:00
"\tМаксимальное значение: 236990.1280878666\n",
2024-10-17 00:52:35 +04:00
"\t1-й квартиль (Q1): 28619.02064490995\n",
"\t3-й квартиль (Q3): 62923.60463276395\n",
"\n",
"Колонка miss_distance:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 6745.532515957\n",
"\tМаксимальное значение: 74798651.4521972\n",
"\t1-й квартиль (Q1): 17210820.23576468\n",
"\t3-й квартиль (Q3): 56548996.45139917\n",
"\n",
"Колонка absolute_magnitude:\n",
"\tЕсть выбросы: Да\n",
"\tКоличество выбросов: 101\n",
2024-10-17 12:31:09 +04:00
"\tМинимальное значение: 9.23\n",
"\tМаксимальное значение: 33.2\n",
2024-10-17 00:52:35 +04:00
"\t1-й квартиль (Q1): 21.34\n",
"\t3-й квартиль (Q3): 25.7\n",
"\n"
]
2024-10-17 12:31:09 +04:00
},
{
"data": {
"image/png": "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+br//vslSW3btjX374YNG9SnTx9Vr149z3uOJHXo0EE33HDDZfMuLSrMmeg5RfVKPyn58MMP87wxS9KaNWt04MAB9evXT0FBQdq9e7dmz56t3bt3a8uWLXnejGbOnGn3xvPvIn/69GndfffdeuCBB9S7d28tWbJETz31lNzd3c0/Hmw2m+bOnavevXvr8ccf19mzZ/X+++8rKipKP/zwg5o1a2a3Tk9PT82bN0/R0dHm2PLly/MUrdzOnj2ruLg43XfffebYvHnz5Onpmedx8+fPl7e3t4YPHy5vb2+tW7dOY8aMkc1m06RJkxxuI7cHHnhAtWvXVmxsrLZs2aK3335bp0+f1gcffGC37xo1aqR7771Xbm5u+uKLL/T0008rOztbgwYNslvfwIEDFRQUpKNHj+rdd99V+/btlZiYaHdGTc5+GTp0qDm2efNm/fnnn3nyO3DggFauXKn7779fYWFhSk5O1nvvvac77rhDv/76q0JCQiRJ06ZN07p169SnTx/Fx8fL1dVV7733nr755ht9+OGHZlxycrJatWql8+fP65lnnpGfn58WLFige++9V8uWLbPb79L/fS0xLS1Nixcv1osvvqiAgAD179+/QPs3Z//lvPZiYmIuGTtw4EBFRkZK+ue1smLFCrvlffr00bfffqshQ4boxhtvlKurq2bPnq2ffvqpwPk48sQTT2j+/Pnq16+fnnnmGSUmJurdd9/Vzz//rO+//16VKlXS8ePH1aFDB/n7++uFF15QtWrVdPDgQS1fvlyS5O/vr5kzZ+qpp57Sfffdp27dukmSmjZtWqAc0tLS1K5dOx06dEjPPPOMQkJC9OGHH2rdunUFevy0adN077336qGHHlJGRoY++eQT3X///YqLi1Pnzp3tYjdt2qTPP//cfA3HxsaqS5cuGjVqlGbMmKGnn35ap0+f1sSJE/XYY4/Z5bBu3Tp16tRJ4eHh5h+XOQefmzZt0q233qpu3brp999/18cff6wpU6aoevXq5j6S/vmK60svvaQHHnhAAwYM0IkTJ/TOO++odevW+vnnn+2+Gn7q1Cl16tRJvXr10sMPP6zAwMAC7Y8cPXv2VIMGDfT666/ryy+/1IQJE+Tr66v33ntPd955p9544w199NFHGjFihG655Ra1bt36kuvLyspSVFSUWrRooTfffFPffvutJk+erDp16uipp54qVG4o26jx1HhqPDWeGl82a3xB3/NGjx6tL774Qv3799fOnTtVtWpVrV69WnPmzNErr7yiG2+8sVD5ovzhWIBjAY4FysaxgPTPa+3ChQsaOHCgPDw85Ovrq927d+u2227TtddeqxdeeEFVqlTRkiVLFB0drU8//TTPPstt6dKlOn/+vJ566in5+fnphx9+0DvvvKMjR45o6dKlkv45Bjl69KjWrFmjDz/88JL5de7cWd7e3lqyZInuuOMOu2WLFy9Wo0aNzGstXE3eufXs2VNjx45VUlKSgoKCzPH//e9/Onr0qHr16mWOFeR4Kj9paWlq06aN/vjjDw0ePFhhYWFaunSp+vbtqzNnzujZZ581Y/v376/58+erU6dOGjBggDIzM7Vp0yZt2bJFN998c551t27dWs8884zefvttu2m1GjRooEceeUQffPCBVq9erS5dupiPSUpK0rp16/Tyyy8XaB+
"text/plain": [
"<Figure size 1500x1000 with 5 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
2024-10-17 00:52:35 +04:00
}
],
"source": [
"# Числовые столбцы DataFrame\n",
"numeric_columns: list[str] = [\n",
" 'est_diameter_min',\n",
" 'est_diameter_max', \n",
" 'relative_velocity', \n",
" 'miss_distance', \n",
" 'absolute_magnitude'\n",
"]\n",
"\n",
"# Проверка выбросов в DataFrame\n",
2024-10-17 12:31:09 +04:00
"def check_outliers(dataframe: DataFrame, columns: list[str]) -> None:\n",
2024-10-17 00:52:35 +04:00
" for column in columns:\n",
" if not pd.api.types.is_numeric_dtype(dataframe[column]): # Проверяем, является ли колонка числовой\n",
" continue\n",
" \n",
" Q1: float = dataframe[column].quantile(0.25) # 1-й квартиль (25%)\n",
" Q3: float = dataframe[column].quantile(0.75) # 3-й квартиль (75%)\n",
" IQR: float = Q3 - Q1 # Вычисляем межквартильный размах\n",
"\n",
" # Определяем границы для выбросов\n",
" lower_bound: float = Q1 - 1.5 * IQR # Нижняя граница\n",
" upper_bound: float = Q3 + 1.5 * IQR # Верхняя граница\n",
"\n",
" # Подсчитываем количество выбросов\n",
" outliers: DataFrame = dataframe[(dataframe[column] < lower_bound) | (dataframe[column] > upper_bound)]\n",
" outlier_count: int = outliers.shape[0]\n",
"\n",
" print(f\"Колонка {column}:\")\n",
" print(f\"\\tЕсть выбросы: {'Да' if outlier_count > 0 else 'Нет'}\")\n",
" print(f\"\\tКоличество выбросов: {outlier_count}\")\n",
" print(f\"\\tМинимальное значение: {dataframe[column].min()}\")\n",
" print(f\"\\tМаксимальное значение: {dataframe[column].max()}\")\n",
" print(f\"\\t1-й квартиль (Q1): {Q1}\")\n",
" print(f\"\\t3-й квартиль (Q3): {Q3}\\n\")\n",
2024-10-17 12:31:09 +04:00
"\n",
"# Визуализация выбросов\n",
"def visualize_outliers(dataframe: DataFrame, columns: list[str]) -> None:\n",
" # Диаграммы размахов\n",
" plt.figure(figsize=(15, 10))\n",
" rows: int = ceil(len(columns) / 3)\n",
" for index, column in enumerate(columns, 1):\n",
" plt.subplot(rows, 3, index)\n",
" plt.boxplot(dataframe[column], vert=True, patch_artist=True)\n",
" plt.title(f\"Диаграмма размахов для \\\"{column}\\\"\")\n",
" plt.xlabel(column)\n",
" \n",
" # Отображение графиков\n",
" plt.tight_layout()\n",
" plt.show()\n",
"\n",
"\n",
"# Проверка выбросов\n",
"check_outliers(df, numeric_columns)\n",
"visualize_outliers(df, numeric_columns)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Колонка est_diameter_min:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 0.0006089126\n",
"\tМаксимальное значение: 0.32962154705\n",
"\t1-й квартиль (Q1): 0.0192555078\n",
"\t3-й квартиль (Q3): 0.1434019235\n",
"\n",
"Колонка est_diameter_max:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 0.00136157\n",
"\tМаксимальное значение: 0.7370561859\n",
"\t1-й квартиль (Q1): 0.0430566244\n",
"\t3-й квартиль (Q3): 0.320656449\n",
"\n",
"Колонка relative_velocity:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 203.34643253\n",
"\tМаксимальное значение: 114380.48061454494\n",
"\t1-й квартиль (Q1): 28619.02064490995\n",
"\t3-й квартиль (Q3): 62923.60463276395\n",
"\n",
"Колонка miss_distance:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 6745.532515957\n",
"\tМаксимальное значение: 74798651.4521972\n",
"\t1-й квартиль (Q1): 17210820.23576468\n",
"\t3-й квартиль (Q3): 56548996.45139917\n",
"\n",
"Колонка absolute_magnitude:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 14.8\n",
"\tМаксимальное значение: 32.239999999999995\n",
"\t1-й квартиль (Q1): 21.34\n",
"\t3-й квартиль (Q3): 25.7\n",
"\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABdEAAAPdCAYAAABlRyFLAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAADy8ElEQVR4nOzde1wV5dr/8S8HWaAkigiIG4XUUvNAQRKWh5JEswNlhmaJZNpTUhq7E23FY5HHUCMpy0OpRbbLp9QHM4zdQdLE3JqpWWqYtlA8QKKCwvz+6MfkEhYCoqB93q/XvHLdc80990zLdS2vNXOPg2EYhgAAAAAAAAAAQBmOtT0AAAAAAAAAAADqKoroAAAAAAAAAADYQREdAAAAAAAAAAA7KKIDAAAAAAAAAGAHRXQAAAAAAAAAAOygiA4AAAAAAAAAgB0U0QEAAAAAAAAAsIMiOgAAAAAAAAAAdlBEBwAAAAAAAADADoroAHARZGRkyMHBQRkZGWbb0KFDFRAQUGtj+jvYu3evHBwctHDhwtoeCgDgCkA+BwCg7ikvP9cEBwcHjR8/vkb7rG09e/ZUz549L1r/AQEBGjp06EXrvy6hiF6ODz/8UA4ODuUuHTp0qO3hAX8bPXv2ND+Mhw4detE++E+cOKHx48fXeAK+HK1bt07jx4/XsWPHansoteLsAnxAQMAV9wXq74Z8DtQN5PNL7++ez89V+iN76XuDH9yvXOR+oG64VLm/OlatWsW/8y6iH3/8UePHj9fevXur3cfZ/xY/+71U25xrewB12Ysvvqh27dqZr1966aVaHA2Ai+XEiROaMGGCJF3U5D5v3jyVlJRctP5rwrp16zRhwgQNHTpUjRo1qu3hVFnLli118uRJ1atXr7aHgjqEfA78PZDP/3K553PgQpH7AdizatUqJScnl1tIP3nypJydKZVWxc6dO+Xo+Nc12j/++KMmTJignj17XnF37vHOqMDtt99u8wX8rbfeUm5ubu0NCMBl7e9c2D1x4oTq169/0ffj4OAgV1fXi74fXF7I5wBqEvn84udz4EKR+4HLy5kzZ1RSUiIXF5daHQf/lqw6i8VS20O4ZJjOpRxFRUWSZPNLij0LFy6Ug4ODzW0KJSUl6tSpU5nbBLds2aKhQ4fq6quvlqurq3x9ffXII4/o8OHDNn2OHz++3NvPzv41rGfPnurQoYOysrLUtWtXubm5KTAwUCkpKWWOJSEhQcHBwfLw8FCDBg3UrVs3ffHFFzZxpbc4Ojg4aPny5TbrTp06pcaNG8vBwUHTp08vM05vb2+dPn3aZpv33nvP7O/sLyv/+7//q379+snPz08Wi0WtWrXSpEmTVFxcfN5zXbq/HTt26IEHHlDDhg3VpEkTjRo1SqdOnbKJXbBggW677TZ5e3vLYrGoffv2mjt3bpk+77nnHgUEBMjV1VXe3t66++67tXXrVpuY0uNISkoqs33btm3l4OCg2NhYs+3IkSN65pln1LFjR7m7u6thw4bq27ev/vvf/9psGx0dLVdXV23fvt2mPSIiQo0bN9aBAwfMtt27d2vAgAHy9PRU/fr1ddNNN2nlypU225XOCVa6WCwWXXPNNUpMTJRhGBWf3P/P3nuvvKu5zn7PnLuc7eDBgxo2bJhatGghJycnM8bd3b1SY6pISUmJkpKSdN1118nV1VU+Pj567LHHdPToUZu4jRs3KiIiQl5eXubflUceecQ8jqZNm0qSJkyYYI6vKrd3/fbbb4qMjFSDBg3k7e2tp59+WoWFhWXiyptDdfr06eratauaNGkiNzc3BQcH68MPPyyzben7bNmyZWrfvr3c3NwUFhZmvl/feOMNtW7dWq6ururZs2e5t06tX79effr0kYeHh+rXr68ePXrom2++MdePHz9ezz77rCQpMDDQPBdn97V48WIFBwfLzc1Nnp6eGjhwoPbt22ezn7M/n7p376769evrxRdfrNS5LH0P/vTTT3rooYfk4eGhpk2bauzYsTIMQ/v27dM999yjhg0bytfXVzNmzLDZvrw50YcOHSp3d3ft379fkZGRcnd3V9OmTfXMM89U6rMHly/y+XKbdeRz8jn5vGLk87qTzyv7mTdu3Dg5OjoqPT3dpn3EiBFycXEp8/cVVz5y/3KbdeR+cn9dzP2l+58+fbqSkpLUqlUrWSwW/fjjj5KkHTt26P7775enp6dcXV0VEhKiTz755Lz9fvXVVxowYIBatGghi8Uif39/Pf300zp58qQZM3ToUCUnJ0tSucd99neH0umh/vOf/5TZ1xtvvCEHBwf98MMPZlt1x322Dh066NZbby3TXlJSoubNm+v++++3aavM96fylP6/9fHxkaurqzp37qxFixaVu99Zs2apY8eOcnV1VdOmTdWnTx9t3LjRjDl7TvSFCxdqwIABkqRbb73VPL8ZGRmKjo6Wl5dXmc8cSerdu7euvfba8467tnElejlKE291f0159913y3x4S9KaNWu0e/duxcTEyNfXV9u2bdObb76pbdu26dtvvy3zgTV37lybD6dzvwgcPXpUd9xxhx544AENGjRIH3zwgR5//HG5uLiY/6DIz8/XW2+9pUGDBmn48OH6448/9PbbbysiIkIbNmxQUFCQTZ+urq5asGCBIiMjzbaPPvqoTGI72x9//KEVK1bo3nvvNdsWLFggV1fXMtstXLhQ7u7uiouLk7u7u9auXauEhATl5+dr2rRpdvdxtgceeEABAQFKTEzUt99+q9mzZ+vo0aN65513bM7dddddp7vvvlvOzs769NNP9cQTT6ikpEQjR4606W/EiBHy9fXVgQMH9Nprryk8PFx79uyxucqm9LyMHj3abFu3bp1+/fXXMuPbvXu3li9frgEDBigwMFA5OTl644031KNHD/3444/y8/OTJM2aNUtr165VdHS0MjMz5eTkpDfeeEOfffaZ3n33XTMuJydHXbt21YkTJ/TUU0+pSZMmWrRoke6++259+OGHNudd+uvWxZMnTyo1NVUvvviivL29NWzYsEqd39LzV/rei4+PrzB2xIgR6tatm6Q/3ysff/yxzfro6Gh9/vnnevLJJ9W5c2c5OTnpzTff1KZNmyo9Hnsee+wxLVy4UDExMXrqqae0Z88evfbaa/r+++/1zTffqF69ejp48KB69+6tpk2b6oUXXlCjRo20d+9effTRR5Kkpk2bau7cuXr88cd177336r777pMkderUqVJjOHnypHr16qXs7Gw99dRT8vPz07vvvqu1a9dWavtZs2bp7rvv1uDBg1VUVKT3339fAwYM0IoVK9SvXz+b2K+++kqffPKJ+R5OTEzUnXfeqeeee06vv/66nnjiCR09elRTp07VI488YjOGtWvXqm/fvgoODjb/wVn6BfWrr75Sly5ddN999+mnn37Se++9p1dffVVeXl7mOZL+vA127NixeuCBB/Too4/q0KFDmjNnjrp3767vv//e5nbxw4cPq2/fvho4cKAeeugh+fj4VOp8lIqKilK7du30yiuvaOXKlZo8ebI8PT31xhtv6LbbbtOUKVO0ZMkSPfPMM7rxxhvVvXv3CvsrLi5WRESEQkNDNX36dH3++eeaMWOGWrVqpccff7xKY8Plg3xOPiefk8/J55dnPq/sZ96YMWP06aefatiwYdq6dauuuuoqrV69WvPmzdOkSZPUuXPnKo0Xlz9yP7mf3H955H7pz/faqVOnNGLECFksFnl6emrbtm26+eab1bx5c73wwgtq0KCBPvjgA0VGRurf//53mXN2tmXLlunEiRN6/PHH1aRJE23YsEFz5szRb7/9pmXLlkn68zvHgQMHtGbNGr377rsVjq9fv35yd3fXBx98oB49etisS01N1XXXXWc+a+FCxn22qKgojR8/XlarVb6+vmb7119/rQMHDmjgwIFmW2W+P5Xn5MmT6tmzp37++WfFxsYqMDBQy5Yt09ChQ3Xs2DGNGjXKjB02bJgWLlyovn376tFHH9WZM2f01Vdf6dtvv1VISEiZvrt3766nnnpKs2fPtplWq127dnr44Yf1zjvvaPXq1brzzjvNbaxWq9auXat
"text/plain": [
"<Figure size 1500x1000 with 5 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Устранить выборсы в DataFrame\n",
"def remove_outliers(dataframe: DataFrame, columns: list[str]) -> DataFrame:\n",
" for column in columns:\n",
" if not pd.api.types.is_numeric_dtype(dataframe[column]): # Проверяем, является ли колонка числовой\n",
" continue\n",
" \n",
" Q1: float = dataframe[column].quantile(0.25) # 1-й квартиль (25%)\n",
" Q3: float = dataframe[column].quantile(0.75) # 3-й квартиль (75%)\n",
" IQR: float = Q3 - Q1 # Вычисляем межквартильный размах\n",
"\n",
" # Определяем границы для выбросов\n",
" lower_bound: float = Q1 - 1.5 * IQR # Нижняя граница\n",
" upper_bound: float = Q3 + 1.5 * IQR # Верхняя граница\n",
"\n",
" # Устраняем выбросы:\n",
" # Заменяем значения ниже нижней границы на нижнюю границу\n",
" # А значения выше верхней границы на верхнюю\n",
" dataframe[column] = dataframe[column].apply(lambda x: lower_bound if x < lower_bound else upper_bound if x > upper_bound else x)\n",
2024-10-17 00:52:35 +04:00
" \n",
" return dataframe\n",
"\n",
"\n",
2024-10-17 12:31:09 +04:00
"# Устраняем выборсы\n",
"df: DataFrame = remove_outliers(df, numeric_columns)\n",
"\n",
2024-10-17 00:52:35 +04:00
"# Проверка выбросов\n",
2024-10-17 12:31:09 +04:00
"check_outliers(df, numeric_columns)\n",
"visualize_outliers(df, numeric_columns)"
2024-10-17 00:52:35 +04:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Разбиение набора данных на выборки:\n",
"\n",
"**Групповое разбиение данных** это метод разделения данных на несколько групп или подмножеств на основе определенного признака или характеристики. При этом наблюдения для одного объекта должны попасть только в одну выборку.\n",
"\n",
"**Основные виды выборки данных**:\n",
"1. Обучающая выборка (60-80%). Обучение модели (подбор коэффициентов некоторой математической функции для аппроксимации).\n",
"2. Контрольная выборка (10-20%). Выбор метода обучения, настройка гиперпараметров.\n",
"3. Тестовая выборка (10-20% или 20-30%). Оценка качества модели перед передачей заказчику.\n",
"\n",
"Разделим выборку данных на 3 группы и проанализируем качество распределения данных.\n",
"\n",
"Весь набор данных состоит из 90836 объектов, из которых 81996 (около 90.3%) неопасны (False), а 8840 (около 9.7%) опасны (True). Это говорит о том, что класс \"неопасные\" значительно преобладает.\n",
"\n",
"Все выборки показывают одинаковое распределение классов, что свидетельствует о том, что данные были отобраны случайным образом и не содержат явного смещения.\n",
"\n",
"Однако, несмотря на сбалансированность при разбиении данных, в целом данные обладают значительным дисбалансом между классами. Это может быть проблемой при обучении модели, так как она может иметь тенденцию игнорировать опасные объекты (True), что следует учитывать при дальнейшем анализе и выборе методов обработки данных.\n",
"\n",
"Для получения более сбалансированных выборок данных необходимо воспользоваться методами приращения (аугментации) данных, а именно методами oversampling и undersampling."
]
},
{
"cell_type": "code",
2024-10-17 12:31:09 +04:00
"execution_count": 6,
2024-10-17 00:52:35 +04:00
"metadata": {},
"outputs": [],
"source": [
"# Функция для создания выборок\n",
"def split_stratified_into_train_val_test(\n",
" df_input,\n",
" stratify_colname=\"y\",\n",
" frac_train=0.6,\n",
" frac_val=0.15,\n",
" frac_test=0.25,\n",
" random_state=None,\n",
") -> tuple[Any, Any, Any]:\n",
" \"\"\"\n",
" Splits a Pandas dataframe into three subsets (train, val, and test)\n",
" following fractional ratios provided by the user, where each subset is\n",
" stratified by the values in a specific column (that is, each subset has\n",
" the same relative frequency of the values in the column). It performs this\n",
" splitting by running train_test_split() twice.\n",
"\n",
" Parameters\n",
" ----------\n",
" df_input : Pandas dataframe\n",
" Input dataframe to be split.\n",
" stratify_colname : str\n",
" The name of the column that will be used for stratification. Usually\n",
" this column would be for the label.\n",
" frac_train : float\n",
" frac_val : float\n",
" frac_test : float\n",
" The ratios with which the dataframe will be split into train, val, and\n",
" test data. The values should be expressed as float fractions and should\n",
" sum to 1.0.\n",
" random_state : int, None, or RandomStateInstance\n",
" Value to be passed to train_test_split().\n",
"\n",
" Returns\n",
" -------\n",
" df_train, df_val, df_test :\n",
" Dataframes containing the three splits.\n",
" \"\"\"\n",
"\n",
" if frac_train + frac_val + frac_test != 1.0:\n",
" raise ValueError(\n",
" \"fractions %f, %f, %f do not add up to 1.0\"\n",
" % (frac_train, frac_val, frac_test)\n",
" )\n",
"\n",
" if stratify_colname not in df_input.columns:\n",
" raise ValueError(\"%s is not a column in the dataframe\" % (stratify_colname))\n",
"\n",
" X: DataFrame = df_input # Contains all columns.\n",
" y: DataFrame = df_input[\n",
" [stratify_colname]\n",
" ] # Dataframe of just the column on which to stratify.\n",
"\n",
" # Split original dataframe into train and temp dataframes.\n",
" df_train, df_temp, y_train, y_temp = train_test_split(\n",
" X, y, \n",
" stratify=y, \n",
" test_size=(1.0 - frac_train), \n",
" random_state=random_state\n",
" )\n",
"\n",
" # Split the temp dataframe into val and test dataframes.\n",
" relative_frac_test: float = frac_test / (frac_val + frac_test)\n",
" df_val, df_test, y_val, y_test = train_test_split(\n",
" df_temp,\n",
" y_temp,\n",
" stratify=y_temp,\n",
" test_size=relative_frac_test,\n",
" random_state=random_state,\n",
" )\n",
"\n",
" assert len(df_input) == len(df_train) + len(df_val) + len(df_test)\n",
"\n",
" return df_train, df_val, df_test"
]
},
{
"cell_type": "code",
2024-10-17 12:31:09 +04:00
"execution_count": 7,
2024-10-17 00:52:35 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"hazardous\n",
"False 81996\n",
"True 8840\n",
"Name: count, dtype: int64 \n",
"\n",
"Обучающая выборка: (54501, 6)\n",
"Распределение выборки данных по классам \"hazardous\":\n",
" hazardous\n",
"False 49197\n",
"True 5304\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"False\": 90.27%\n",
"Процент объектов класса \"True\": 9.73%\n",
"\n",
"Контрольная выборка: (18167, 6)\n",
"Распределение выборки данных по классам \"hazardous\":\n",
" hazardous\n",
"False 16399\n",
"True 1768\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"False\": 90.27%\n",
"Процент объектов класса \"True\": 9.73%\n",
"\n",
"Тестовая выборка: (18168, 6)\n",
"Распределение выборки данных по классам \"hazardous\":\n",
" hazardous\n",
"False 16400\n",
"True 1768\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"False\": 90.27%\n",
"Процент объектов класса \"True\": 9.73%\n",
"\n",
"Для обучающей выборки аугментация данных требуется\n",
"Для контрольной выборки аугментация данных требуется\n",
"Для тестовой выборки аугментация данных требуется\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABgcAAAH/CAYAAABzUQ1QAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAACenklEQVR4nOzdd3xT9f7H8Xe6S8sqZRZk7yGKgIAIKg7An1vEcRkuFATFdR1XARduRdxeBRSuA72CEwUVAQUBBWTILnu27O425/dHb2NDd5v0e5Lzej4ePJSQJp9mnFfa78mJy7IsSwAAAAAAAAAAwDFCTA8AAAAAAAAAAAAqF4sDAAAAAAAAAAA4DIsDAAAAAAAAAAA4DIsDAAAAAAAAAAA4DIsDAAAAAAAAAAA4DIsDAAAAAAAAAAA4DIsDAAAAAAAAAAA4DIsDAAAAAAAAAAA4DIsDABAAjhw5os2bNys7O9v0KPAhy7J06NAhbdq0yfQoAACggjIzM7Vv3z7t2bPH9CgAAMCHUlJStHPnTh0+fNj0KD7H4gAQAJo0aaKLL77Y9Bg+07dvX/Xt29f0GLaWlZWlZ599VqeeeqoiIyNVs2ZNtWzZUj/88IPp0QLCmjVrNGvWLM/fV65cqa+//trcQPkcP35c//rXv9S6dWtFRESoVq1aatWqlTZs2GB6NADlQKMB/5s+fbq2bdvm+fvUqVO1e/ducwPls3z5cl133XWKj49XZGSk6tevryuvvNL0WIDj0GMgMD311FNyu92SJLfbrYkTJxqe6G8zZ87Ueeedp6pVqyo2NlannHKKnn32WdNj+VyZFgemTp0ql8vl+RMVFaVWrVrpjjvu0P79+/01IxD0xo8fryZNmkj6+3kG/+vbt6+GDRsmSRo2bJhtXnxlZGSoX79+euSRR9S3b1/NnDlTc+fO1Y8//qgePXqYHi8gHD9+XCNGjNCSJUu0adMm3XnnnVq9erXpsZScnKwePXrolVde0VVXXaXZs2dr7ty5mj9/vmcbUF40GvAPGm2GXRsNMxYuXKj7779f27Zt03fffadRo0YpJMT8fm6zZ8/WWWedpXXr1unJJ5/U3Llzde+992rJkiX0GPAxemwGPYa/TZs2Tc8//7x27dqlF154QdOmTTM9kiTpgQce0KBBg1S1alW98847mjt3rubNm6eRI0eaHs3nwsrzRY899piaNm2q9PR0LVq0SG+88Ya++eYbrVmzRlWqVPH1jADgKM8884x+++03fffdd7z4KqcePXp4/khSq1atdMsttxieSrrvvvu0d+9eLV68WO3bt/fLddBoAECwGTt2rPr27aumTZtKku6++27Vr1/f6EyHDh3SzTffrAsvvFAzZ85URESEJGnXrl2S6DEAAKXx2GOPaciQIfrnP/+pyMhITZ8+3fRI+vnnn/XMM89o4sSJeuCBB0yP43flWhzo37+/zjjjDEnSzTffrFq1aunFF1/U7Nmzde211/p0QACBJyUlRTExMabHCEjZ2dl6+eWXdc8997AwUEGzZs3SunXrlJaWpo4dO3p+aDflwIEDmjZtmt58802/LQxINBpA8Wg0AlGbNm20ZcsWrVmzRvHx8WrevLnpkTRlyhSlp6dr6tSphb7GoMcAikOPgVzXXHONzjnnHG3evFktW7ZU7dq1TY+k559/Xj179nTEwoDko88cOPfccyVJiYmJknL3orj33nvVsWNHxcbGqlq1aurfv79WrVpV4GvT09M1fvx4tWrVSlFRUapfv76uuOIKbdmyRZK0bds2r8MknPwn/y/P5s+fL5fLpY8//lgPPfSQ6tWrp5iYGF1yySXauXNngev+7bffdNFFF6l69eqqUqWK+vTpo19++aXQ77Fv376FXv/48eMLnHf69Onq0qWLoqOjFRcXp8GDBxd6/cV9b/m53W69/PLLat++vaKiolS3bl2NGDGiwIdgFHWMvTvuuKPAZRY2+3PPPVfgNpVyD3Eybtw4tWjRQpGRkWrUqJHuv/9+ZWRkFHpb5VfYcfKefPJJhYSE6D//+U+5bo+8J2mtWrUUHR2tLl266NNPPy30+qdPn65u3bqpSpUqqlmzps4++2x9//33Xuf59ttv1adPH1WtWlXVqlVT165dC8w2c+ZMz30aHx+vG264ocBxTocNG+Y1c82aNdW3b18tXLiwxNuptBYtWqRu3bopKipKzZo10/vvv+/176V97jVp0qTI23r+/PmSpO3bt2vkyJFq3bq1oqOjVatWLV199dVex3uV/n5L588//6yRI0eqTp06atiwoeff3377bTVv3lzR0dHq1q1bkbfHgQMHdNNNN6lu3bqKiorSqaeeWuDtZHnP8bwZ8+Q9dqZOneo5bd++fRo+fLgaNmzoOf7rpZdeWmD+ssp/24WEhKhevXq65pprtGPHjlJ9/euvv6727dsrMjJSDRo00KhRo3TkyBHPv2/YsEGHDx9W1apV1adPH1WpUkXVq1fXxRdfrDVr1njO99NPP8nlcunzzz8vcB3/+c9/5HK5tHjxYs/MeW8FzVPYbblw4UJdffXVOuWUUzzP9bFjxyotLc3ra8ePH1/geTljxgx17txZUVFRqlWrlq699toCt8mwYcMUGxvrddqnn35a6H0aGxtbYGapdNvX/Nuddu3aqUuXLlq1alWh25PCnLy9j4+P18CBA71ufyl3O3rHHXcUeTl5z428x9yyZcvkdruVmZmpM844o9jbSpJ+/PFH9e7dWzExMapRo4YuvfRS/fXXX17nybsv1q9fr9dff12SdN555+nOO+9Uenq6pL8bfd1112n8+PGe7USHDh0UFhYml8ul3r17e20n8m7nqKgoRUdHq2rVqjSaRtPoEtDowG50Ya289dZbFRUVVeB7KqnlUu7zq0OHDgWu5/nnn/dqQ3H3t8vl8hxCI+92fP755/XSSy+pcePGio6OVp8+fQr0SSpdQwq73Qp7vOWdp6Rjeeef8WQdOnQosL0pzeMq/+MnJiZG3bt3V/PmzTVq1Ci5XK5CXysU9vV5f8LDw9WkSRPdd999yszM9Jwv77myfPnyIi/r5G3mkiVL1LlzZz311FNq1KiRIiMj1bJly0I/4yg7O9tzSKF//OMfatKkicaOHauxY8d6bROio6M928K811Xt2rXTRx995PUzc40aNTzP7cK+z5P/NGzY0DNjQkKCXC6XPvzwQ3qcDz2mx/TYfI/91cT169frqquuUlxcnKKionTGGWfoiy++8DpPUR1ISkoqsC0o7OfhEydOqF69egVu+7zXA7///rt69uyp6OhoNW3aVG+++WaBOcvSxZK6Jklbt27V1Vdfrbi4OFWpUkVnnnlmgUYV9r1IBV8XleX2kaQVK1aof//+qlatmmJjY3XeeedpyZIlXufJ//NynTp1PNusTp06FXisFubkw+pWqVJFHTt21L///W+v8xX2e4iTnfw9LFmyRB06dNDgwYMVFxen6Ohode3a1etzDfOU5X4rzWN22LBhBQ45PH36dIWEhOjpp5/2Or00j+3SKNc7B06W90uCWrVqScp9AM6aNUtXX321mjZtqv379+utt95Snz59tG7dOjVo0ECSlJOTo4svvlg//PCDBg8erDvvvFPHjx/X3LlztWbNGq89Qq699loNGDDA63offPDBQud58skn5XK59M9//lMHDhzQyy+/rH79+mnlypWKjo6WlPuCuX///urSpYvGjRunkJAQTZkyReeee64WLlyobt26Fbjchg0bej4Y48SJE7r99tsLve5HHnlEgwYN0s0336yDBw9q8uTJOvvss7VixQrVqFGjwNfceuut6t27tyTpv//9b4Ff9o0YMUJTp07V8OHDNWbMGCUmJurVV1/VihUr9Msvvyg8PLzQ26Esjhw5UuiHfrjdbl1yySVatGiRbr31VrVt21arV6/WSy+9pI0bNxb6xCjOlClT9K9//UsvvPCCrrvuukLPU9LtMWnSJF1yySW6/vrrlZmZqY8++khXX321vvrqKw0cONBzvgkTJmj8+PHq2bOnHnvsMUVEROi3337Tjz/+qAsuuEBS7sbkxhtvVPv27fX
"text/plain": [
"<Figure size 1500x500 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Вывод распределения количества наблюдений по меткам (классам)\n",
"print(df.hazardous.value_counts(), '\\n')\n",
"\n",
"data: DataFrame = df[[\n",
" 'est_diameter_min', \n",
" 'est_diameter_max', \n",
" 'relative_velocity', \n",
" 'miss_distance', \n",
" 'absolute_magnitude', \n",
" 'hazardous'\n",
"]].copy()\n",
"\n",
"df_train, df_val, df_test = split_stratified_into_train_val_test(\n",
" data, \n",
" stratify_colname=\"hazardous\", \n",
" frac_train=0.60, \n",
" frac_val=0.20, \n",
" frac_test=0.20\n",
")\n",
"\n",
"# Оценка сбалансированности\n",
"def check_balance(dataframe: DataFrame, dataframe_name: str, column: str) -> None:\n",
" counts: Series[int] = dataframe[column].value_counts()\n",
" print(dataframe_name + \": \", dataframe.shape)\n",
" print(f\"Распределение выборки данных по классам \\\"{column}\\\":\\n\", counts)\n",
" total_count: int = len(dataframe)\n",
" for value in counts.index:\n",
" percentage: float = counts[value] / total_count * 100\n",
" print(f\"Процент объектов класса \\\"{value}\\\": {percentage:.2f}%\")\n",
" print()\n",
" \n",
"# Определение необходимости аугментации данных\n",
"def need_augmentation(dataframe: DataFrame,\n",
" column: str, \n",
" first_value: Any, second_value: Any) -> bool:\n",
" counts: Series[int] = dataframe[column].value_counts()\n",
" ratio: float = counts[first_value] / counts[second_value]\n",
" return ratio > 1.5 or ratio < 0.67\n",
" \n",
" # Визуализация сбалансированности классов\n",
"def visualize_balance(dataframe_train: DataFrame,\n",
" dataframe_val: DataFrame,\n",
" dataframe_test: DataFrame, \n",
" column: str) -> None:\n",
" fig, axes = plt.subplots(1, 3, figsize=(15, 5))\n",
"\n",
" # Обучающая выборка\n",
" counts_train: Series[int] = dataframe_train[column].value_counts()\n",
" axes[0].pie(counts_train, labels=counts_train.index, autopct='%1.1f%%', startangle=90)\n",
" axes[0].set_title(f\"Распределение классов \\\"{column}\\\" в обучающей выборке\")\n",
"\n",
" # Контрольная выборка\n",
" counts_val: Series[int] = dataframe_val[column].value_counts()\n",
" axes[1].pie(counts_val, labels=counts_val.index, autopct='%1.1f%%', startangle=90)\n",
" axes[1].set_title(f\"Распределение классов \\\"{column}\\\" в контрольной выборке\")\n",
"\n",
" # Тестовая выборка\n",
" counts_test: Series[int] = dataframe_test[column].value_counts()\n",
" axes[2].pie(counts_test, labels=counts_test.index, autopct='%1.1f%%', startangle=90)\n",
" axes[2].set_title(f\"Распределение классов \\\"{column}\\\" в тренировочной выборке\")\n",
"\n",
" # Отображение графиков\n",
" plt.tight_layout()\n",
" plt.show()\n",
" \n",
"\n",
"# Проверка сбалансированности\n",
"check_balance(df_train, 'Обучающая выборка', 'hazardous')\n",
"check_balance(df_val, 'Контрольная выборка', 'hazardous')\n",
"check_balance(df_test, 'Тестовая выборка', 'hazardous')\n",
"\n",
"# Проверка необходимости аугментации\n",
"print(f\"Для обучающей выборки аугментация данных {'не ' if not need_augmentation(df_train, 'hazardous', True, False) else ''}требуется\")\n",
"print(f\"Для контрольной выборки аугментация данных {'не ' if not need_augmentation(df_val, 'hazardous', True, False) else ''}требуется\")\n",
"print(f\"Для тестовой выборки аугментация данных {'не ' if not need_augmentation(df_test, 'hazardous', True, False) else ''}требуется\")\n",
" \n",
"# Визуализация сбалансированности классов\n",
"visualize_balance(df_train, df_val, df_test, 'hazardous')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Приращение данных:\n",
"\n",
"**Аугментация данных** может быть полезна в том случае, когда имеется недостаточное количество данных и мы хотим сгенерировать новые данные на основе имеющихся, слегка модифицировав их.\n",
"\n",
"**Методы решения:**\n",
"1. **Выборка с избытком (oversampling).** Копирование наблюдений или генерация новых наблюдений на основе существующих с помощью алгоритмов SMOTE и ADASYN (нахождение k-ближайших соседей).\n",
"2. **Выборка с недостатком (undersampling).** Исключение некоторых наблюдений для меток с большим количеством наблюдений. Наблюдения можно исключать случайным образом или на основе определения связей Томека для наблюдений разных меток."
]
},
{
"cell_type": "code",
2024-10-17 12:31:09 +04:00
"execution_count": 8,
2024-10-17 00:52:35 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"После применения метода oversampling:\n",
2024-10-17 12:31:09 +04:00
"Обучающая выборка: (100699, 6)\n",
2024-10-17 00:52:35 +04:00
"Распределение выборки данных по классам \"hazardous\":\n",
" hazardous\n",
2024-10-17 12:31:09 +04:00
"True 51502\n",
2024-10-17 00:52:35 +04:00
"False 49197\n",
"Name: count, dtype: int64\n",
2024-10-17 12:31:09 +04:00
"Процент объектов класса \"True\": 51.14%\n",
"Процент объектов класса \"False\": 48.86%\n",
2024-10-17 00:52:35 +04:00
"\n",
2024-10-17 12:31:09 +04:00
"Контрольная выборка: (32759, 6)\n",
2024-10-17 00:52:35 +04:00
"Распределение выборки данных по классам \"hazardous\":\n",
" hazardous\n",
"False 16399\n",
2024-10-17 12:31:09 +04:00
"True 16360\n",
2024-10-17 00:52:35 +04:00
"Name: count, dtype: int64\n",
2024-10-17 12:31:09 +04:00
"Процент объектов класса \"False\": 50.06%\n",
"Процент объектов класса \"True\": 49.94%\n",
2024-10-17 00:52:35 +04:00
"\n",
2024-10-17 12:31:09 +04:00
"Тестовая выборка: (33556, 6)\n",
2024-10-17 00:52:35 +04:00
"Распределение выборки данных по классам \"hazardous\":\n",
" hazardous\n",
2024-10-17 12:31:09 +04:00
"True 17156\n",
2024-10-17 00:52:35 +04:00
"False 16400\n",
"Name: count, dtype: int64\n",
2024-10-17 12:31:09 +04:00
"Процент объектов класса \"True\": 51.13%\n",
"Процент объектов класса \"False\": 48.87%\n",
2024-10-17 00:52:35 +04:00
"\n",
"Для обучающей выборки аугментация данных не требуется\n",
"Для контрольной выборки аугментация данных не требуется\n",
"Для тестовой выборки аугментация данных не требуется\n"
]
},
{
"data": {
2024-10-17 12:31:09 +04:00
"image/png": "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
2024-10-17 00:52:35 +04:00
"text/plain": [
"<Figure size 1500x500 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Метод приращения с избытком (oversampling)\n",
"def oversample(df: DataFrame, column: str) -> DataFrame:\n",
" X: DataFrame = df.drop(column, axis=1)\n",
" y: DataFrame = df[column] # type: ignore\n",
" \n",
" adasyn = ADASYN()\n",
" X_resampled, y_resampled = adasyn.fit_resample(X, y) # type: ignore\n",
" \n",
" df_resampled: DataFrame = pd.concat([X_resampled, y_resampled], axis=1)\n",
" return df_resampled\n",
"\n",
"\n",
"# Приращение данных (oversampling)\n",
"df_train_oversampled: DataFrame = oversample(df_train, 'hazardous')\n",
"df_val_oversampled: DataFrame = oversample(df_val, 'hazardous')\n",
"df_test_oversampled: DataFrame = oversample(df_test, 'hazardous')\n",
"\n",
"# Проверка сбалансированности\n",
"print('После применения метода oversampling:')\n",
"check_balance(df_train_oversampled, 'Обучающая выборка', 'hazardous')\n",
"check_balance(df_val_oversampled, 'Контрольная выборка', 'hazardous')\n",
"check_balance(df_test_oversampled, 'Тестовая выборка', 'hazardous')\n",
"\n",
"# Проверка необходимости аугментации\n",
"print(f\"Для обучающей выборки аугментация данных {'не ' if not need_augmentation(df_train_oversampled, 'hazardous', True, False) else ''}требуется\")\n",
"print(f\"Для контрольной выборки аугментация данных {'не ' if not need_augmentation(df_val_oversampled, 'hazardous', True, False) else ''}требуется\")\n",
"print(f\"Для тестовой выборки аугментация данных {'не ' if not need_augmentation(df_test_oversampled, 'hazardous', True, False) else ''}требуется\")\n",
" \n",
"# Визуализация сбалансированности классов\n",
"visualize_balance(df_train_oversampled, df_val_oversampled, df_test_oversampled, 'hazardous')"
]
},
{
"cell_type": "code",
2024-10-17 12:31:09 +04:00
"execution_count": 9,
2024-10-17 00:52:35 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"После применения метода undersampling:\n",
"Обучающая выборка: (10608, 6)\n",
"Распределение выборки данных по классам \"hazardous\":\n",
" hazardous\n",
"False 5304\n",
"True 5304\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"False\": 50.00%\n",
"Процент объектов класса \"True\": 50.00%\n",
"\n",
"Контрольная выборка: (3536, 6)\n",
"Распределение выборки данных по классам \"hazardous\":\n",
" hazardous\n",
"False 1768\n",
"True 1768\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"False\": 50.00%\n",
"Процент объектов класса \"True\": 50.00%\n",
"\n",
"Тестовая выборка: (3536, 6)\n",
"Распределение выборки данных по классам \"hazardous\":\n",
" hazardous\n",
"False 1768\n",
"True 1768\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"False\": 50.00%\n",
"Процент объектов класса \"True\": 50.00%\n",
"\n",
"Для обучающей выборки аугментация данных не требуется\n",
"Для контрольной выборки аугментация данных не требуется\n",
"Для тестовой выборки аугментация данных не требуется\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABgcAAAHzCAYAAAAEk80rAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAACIjUlEQVR4nOzdd3gU9d6G8WfTQxJqIPTepInSpAkqqJRXsYD1UGwoYsHu8ShgQ8QCYkOPIgo25Ah2AQEVREEUpEsJICAldEL6zvtHyJrNbvruzszu/bmuXErYbL7Zdk/4zcw6DMMwBAAAAAAAAAAAQkaY2QMAAAAAAAAAAIDAYnEAAAAAAAAAAIAQw+IAAAAAAAAAAAAhhsUBAAAAAAAAAABCDIsDAAAAAAAAAACEGBYHAAAAAAAAAAAIMSwOAAAAAAAAAAAQYlgcAAAAAAAAAAAgxLA4AAA2cPToUW3dulXZ2dlmjwIfMgxDhw8f1pYtW8weBQAAlFNmZqb27dunvXv3mj0KAADwodTUVP311186cuSI2aP4HIsDgA00bNhQAwcONHsMn+ndu7d69+5t9hiWlpWVpWeffVZnnnmmoqOjVaVKFTVr1kzfffed2aPZwrp16zR37lzXn1evXq0vv/zSvIHyOXHihP7zn/+oRYsWioqKUrVq1dS8eXNt3rzZ7NEAlAGNBvxv5syZ2rFjh+vP77zzjvbs2WPeQPn8+uuvuvbaa5WYmKjo6GjVqlVLV1xxhdljASGHHgP29PTTT8vpdEqSnE6nJkyYYPJE/5g9e7YuuOACJSQkKD4+XvXr19ezzz5r9lg+V6rFgXfeeUcOh8P1ERMTo+bNm2v06NHav3+/v2YEgt64cePUsGFDSf88z+B/vXv31vDhwyVJw4cPt8zGV0ZGhvr06aNHH31UvXv31uzZs7VgwQItWrRIXbt2NXs8Wzhx4oRGjhypn3/+WVu2bNFdd92ltWvXmj2WDh06pK5du+qll17SlVdeqXnz5mnBggVasmSJ6zWgrGg04B802hxWbTTM8eOPP+qBBx7Qjh079O233+r2229XWJj5+7nNmzdPPXr00IYNG/TUU09pwYIFuu+++/Tzzz/TY8DH6LE56DH8bcaMGXruuee0e/duPf/885oxY4bZI0mSHnroIQ0ZMkQJCQl68803tWDBAi1cuFCjRo0yezSfiyjLFz3++ONq1KiR0tPTtXTpUr322mv66quvtG7dOlWoUMHXMwJASJk4caJ++eUXffvtt2x8lVHXrl1dH5LUvHlz3XzzzSZPJd1///36+++/tXz5crVu3dov34NGAwCCzZgxY9S7d281atRIknTPPfeoVq1aps50+PBh3XTTTbrooos0e/ZsRUVFSZJ2794tiR4DAFASjz/+uIYOHaoHH3xQ0dHRmjlzptkj6fvvv9fEiRM1YcIEPfTQQ2aP43dlWhzo16+fOnbsKEm66aabVK1aNb3wwguaN2+errnmGp8OCMB+UlNTFRcXZ/YYtpSdna3Jkyfr3nvvZWGgnObOnasNGzYoLS1Nbdu2df3SbpYDBw5oxowZev311/22MCDRaABFo9Gwo5YtW2rbtm1at26dEhMT1aRJE7NH0vTp05Wenq533nnH6zYGPQZQFHoM5Lrqqqt03nnnaevWrWrWrJmqV69u9kh67rnn1K1bt5BYGJB89J4D559/viQpOTlZUu5eFPfdd5/atm2r+Ph4VaxYUf369dOaNWs8vjY9PV3jxo1T8+bNFRMTo1q1aunyyy/Xtm3bJEk7duxwO01CwY/8/3i2ZMkSORwOffTRR/r3v/+tmjVrKi4uTpdccon++usvj+/9yy+/6OKLL1alSpVUoUIF9erVS8uWLfP6M/bu3dvr9x83bpzHZWfOnKkOHTooNjZWVatW1dVXX+31+xf1s+XndDo1efJktW7dWjExMUpKStLIkSM93gSjsHPsjR492uM6vc0+adIkj9tUyj3FydixY9W0aVNFR0erXr16euCBB5SRkeH1tsrP23nynnrqKYWFhen9998v0+2R9yStVq2aYmNj1aFDB33yySdev//MmTPVuXNnVahQQVWqVNG5556r+fPnu13m66+/Vq9evZSQkKCKFSuqU6dOHrPNnj3bdZ8mJibq+uuv9zjP6fDhw91mrlKlinr37q0ff/yx2NuppJYuXarOnTsrJiZGjRs31rvvvuv29yV97jVs2LDQ23rJkiWSpJ07d2rUqFFq0aKFYmNjVa1aNQ0ePNjtfK/SP4d0fv/99xo1apRq1KihunXruv7+jTfeUJMmTRQbG6vOnTsXenscOHBAN954o5KSkhQTE6MzzzzT43CyvOd43ox58h4777zzjutz+/bt04gRI1S3bl3X+V8vvfRSj/lLK/9tFxYWppo1a+qqq67Srl27SvT1r776qlq3bq3o6GjVrl1bt99+u44ePer6+82bN+vIkSNKSEhQr169VKFCBVWqVEkDBw7UunXrXJdbvHixHA6HPv30U4/v8f7778vhcGj58uWumfMOBc3j7bb88ccfNXjwYNWvX9/1XB8zZozS0tLcvnbcuHEez8tZs2apffv2iomJUbVq1XTNNdd43CbDhw9XfHy82+c++eQTr/dpfHy8x8xSyV5f87/utGrVSh06dNCaNWu8vp54U/D1PjExUQMGDHC7/aXc19HRo0cXej15z428x9zKlSvldDqVmZmpjh07FnlbSdKiRYvUs2dPxcXFqXLlyrr00ku1ceNGt8vk3RebNm3Sq6++Kkm64IILdNdddyk9PV3SP42+9tprNW7cONfrRJs2bRQRESGHw6GePXu6vU7k3c4xMTGKjY1VQkICjabRNLoYNNrejfbWyltuuUUxMTEeP1NxLZdyn19t2rTx+D7PPfecWxuKur8dDofrFBp5t+Nzzz2nF198UQ0aNFBsbKx69erl0SepZA3xdrt5e7zlXaa4c3nnn7GgNm3aeLzelORxlf/xExcXpy5duqhJkya6/fbb5XA4vG4rePv6vI/IyEg1bNhQ999/vzIzM12Xy3uu/Prrr4VeV8HXzJ9//lnt27fX008/rXr16ik6OlrNmjXz+h5H2dnZrlMK/etf/1LDhg01ZswYjRkzxu01ITY21vVamLdd1apVK3344YduvzNXrlzZ9dz29nMW/Khbt65rxjp16sjhcOiDDz6gx/nQY3pMj83vsb+auGnTJl155ZWqWrWqYmJi1LFjR3322WdulymsAykpKR6vBd5+Hz558qRq1qzpcdvnbQ+sWrVK3bp1U2xsrBo1aqTXX3/dY87SdLG4rknS9u3bNXjwYFWtWlUVKlTQOeec49Eobz+L5LldVJrbR5J+//139evXTxUrVlR8fLwuuOAC/fzzz26Xyf/7co0aNVyvWe3atfN4rHpT8LS6FSpUUNu2bfXf//7X7XLe/h2ioII/w88//6w2bdro6quvVtWqVRUbG6tOnTq5va9hntLcbyV5zA4fPtzjlMMzZ85UWFiYnnnmGbfPl+SxXRJlOnKgoLx/JKhWrZqk3Afg3LlzNXjwYDVq1Ej79+/XtGnT1KtXL23YsEG1a9eWJOXk5GjgwIH67rvvdPXVV+uuu+7SiRMntGDBAq1bt85tj5BrrrlG/fv3d/u+Dz/8sNd5nnrqKTkcDj344IM6cOCAJk+erD59+mj16tWKjY2VlLvB3K9fP3Xo0EFjx45VWFiYpk+frvPPP18//vijOnfu7HG9devWdb0xxsmTJ3Xbbbd5/d6PPvqohgwZoptuukkHDx7U1KlTde655+r3339X5cqVPb7mlltuUc+ePSVJ//vf/zz+sW/kyJF65513NGLECN15551KTk7Wyy+/rN9//13Lli1TZGSk19uhNI4ePer1TT+cTqcuueQSLV26VLfccovOOOMMrV27Vi+++KL+/PNPr0+MokyfPl3/+c9/9Pzzz+vaa6/1epnibo8pU6bokksu0XXXXafMzEx9+OGHGjx4sL744gsNGDDAdbnx48dr3Lhx6tatmx5//HFFRUXpl19+0aJFi3ThhRdKyn0xueGGG9S6dWs9/PDDqly
"text/plain": [
"<Figure size 1500x500 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Метод приращения с недостатком (undersampling)\n",
"def undersample(df: DataFrame, column: str) -> DataFrame:\n",
" X: DataFrame = df.drop(column, axis=1)\n",
" y: DataFrame = df[column] # type: ignore\n",
" \n",
" undersampler = RandomUnderSampler()\n",
" X_resampled, y_resampled = undersampler.fit_resample(X, y) # type: ignore\n",
" \n",
" df_resampled: DataFrame = pd.concat([X_resampled, y_resampled], axis=1)\n",
" return df_resampled\n",
"\n",
"\n",
"# Приращение данных (undersampling)\n",
"df_train_undersampled: DataFrame = undersample(df_train, 'hazardous')\n",
"df_val_undersampled: DataFrame = undersample(df_val, 'hazardous')\n",
"df_test_undersampled: DataFrame = undersample(df_test, 'hazardous')\n",
"\n",
"# Проверка сбалансированности\n",
"print('После применения метода undersampling:')\n",
"check_balance(df_train_undersampled, 'Обучающая выборка', 'hazardous')\n",
"check_balance(df_val_undersampled, 'Контрольная выборка', 'hazardous')\n",
"check_balance(df_test_undersampled, 'Тестовая выборка', 'hazardous')\n",
"\n",
"# Проверка необходимости аугментации\n",
"print(f\"Для обучающей выборки аугментация данных {'не ' if not need_augmentation(df_train_undersampled, 'hazardous', True, False) else ''}требуется\")\n",
"print(f\"Для контрольной выборки аугментация данных {'не ' if not need_augmentation(df_val_undersampled, 'hazardous', True, False) else ''}требуется\")\n",
"print(f\"Для тестовой выборки аугментация данных {'не ' if not need_augmentation(df_test_undersampled, 'hazardous', True, False) else ''}требуется\")\n",
" \n",
"# Визуализация сбалансированности классов\n",
"visualize_balance(df_train_undersampled, df_val_undersampled, df_test_undersampled, 'hazardous')"
]
}
],
"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
}