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

2932 lines
1.3 MiB
Plaintext
Raw Permalink 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,
2024-10-17 00:52:35 +04:00
"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,
2024-10-17 00:52:35 +04:00
"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",
2024-10-18 01:38:52 +04:00
" <th>count</th>\n",
" <th>mean</th>\n",
" <th>std</th>\n",
" <th>min</th>\n",
" <th>25%</th>\n",
" <th>50%</th>\n",
" <th>75%</th>\n",
" <th>max</th>\n",
2024-10-17 12:31:09 +04:00
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
2024-10-18 01:38:52 +04:00
" <th>id</th>\n",
" <td>90836.0</td>\n",
2024-10-17 12:31:09 +04:00
" <td>1.438288e+07</td>\n",
" <td>2.087202e+07</td>\n",
2024-10-18 01:38:52 +04:00
" <td>2.000433e+06</td>\n",
" <td>3.448110e+06</td>\n",
" <td>3.748362e+06</td>\n",
" <td>3.884023e+06</td>\n",
" <td>5.427591e+07</td>\n",
2024-10-17 12:31:09 +04:00
" </tr>\n",
" <tr>\n",
2024-10-18 01:38:52 +04:00
" <th>est_diameter_min</th>\n",
" <td>90836.0</td>\n",
" <td>1.274321e-01</td>\n",
" <td>2.985112e-01</td>\n",
" <td>6.089126e-04</td>\n",
" <td>1.925551e-02</td>\n",
" <td>4.836765e-02</td>\n",
" <td>1.434019e-01</td>\n",
" <td>3.789265e+01</td>\n",
2024-10-17 12:31:09 +04:00
" </tr>\n",
" <tr>\n",
2024-10-18 01:38:52 +04:00
" <th>est_diameter_max</th>\n",
" <td>90836.0</td>\n",
" <td>2.849469e-01</td>\n",
" <td>6.674914e-01</td>\n",
" <td>1.361570e-03</td>\n",
" <td>4.305662e-02</td>\n",
" <td>1.081534e-01</td>\n",
" <td>3.206564e-01</td>\n",
" <td>8.473054e+01</td>\n",
2024-10-17 12:31:09 +04:00
" </tr>\n",
" <tr>\n",
2024-10-18 01:38:52 +04:00
" <th>relative_velocity</th>\n",
" <td>90836.0</td>\n",
" <td>4.806692e+04</td>\n",
" <td>2.529330e+04</td>\n",
" <td>2.033464e+02</td>\n",
" <td>2.861902e+04</td>\n",
" <td>4.419012e+04</td>\n",
" <td>6.292360e+04</td>\n",
" <td>2.369901e+05</td>\n",
2024-10-17 12:31:09 +04:00
" </tr>\n",
" <tr>\n",
2024-10-18 01:38:52 +04:00
" <th>miss_distance</th>\n",
" <td>90836.0</td>\n",
" <td>3.706655e+07</td>\n",
" <td>2.235204e+07</td>\n",
" <td>6.745533e+03</td>\n",
" <td>1.721082e+07</td>\n",
" <td>3.784658e+07</td>\n",
2024-10-17 12:31:09 +04:00
" <td>5.654900e+07</td>\n",
2024-10-18 01:38:52 +04:00
" <td>7.479865e+07</td>\n",
2024-10-17 12:31:09 +04:00
" </tr>\n",
" <tr>\n",
2024-10-18 01:38:52 +04:00
" <th>absolute_magnitude</th>\n",
" <td>90836.0</td>\n",
" <td>2.352710e+01</td>\n",
" <td>2.894086e+00</td>\n",
" <td>9.230000e+00</td>\n",
" <td>2.134000e+01</td>\n",
" <td>2.370000e+01</td>\n",
" <td>2.570000e+01</td>\n",
" <td>3.320000e+01</td>\n",
2024-10-17 12:31:09 +04:00
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
2024-10-18 01:38:52 +04:00
" count mean std min \\\n",
"id 90836.0 1.438288e+07 2.087202e+07 2.000433e+06 \n",
"est_diameter_min 90836.0 1.274321e-01 2.985112e-01 6.089126e-04 \n",
"est_diameter_max 90836.0 2.849469e-01 6.674914e-01 1.361570e-03 \n",
"relative_velocity 90836.0 4.806692e+04 2.529330e+04 2.033464e+02 \n",
"miss_distance 90836.0 3.706655e+07 2.235204e+07 6.745533e+03 \n",
"absolute_magnitude 90836.0 2.352710e+01 2.894086e+00 9.230000e+00 \n",
2024-10-17 12:31:09 +04:00
"\n",
2024-10-18 01:38:52 +04:00
" 25% 50% 75% max \n",
"id 3.448110e+06 3.748362e+06 3.884023e+06 5.427591e+07 \n",
"est_diameter_min 1.925551e-02 4.836765e-02 1.434019e-01 3.789265e+01 \n",
"est_diameter_max 4.305662e-02 1.081534e-01 3.206564e-01 8.473054e+01 \n",
"relative_velocity 2.861902e+04 4.419012e+04 6.292360e+04 2.369901e+05 \n",
"miss_distance 1.721082e+07 3.784658e+07 5.654900e+07 7.479865e+07 \n",
"absolute_magnitude 2.134000e+01 2.370000e+01 2.570000e+01 3.320000e+01 "
2024-10-17 12:31:09 +04:00
]
},
"execution_count": 2,
2024-10-17 12:31:09 +04:00
"metadata": {},
"output_type": "execute_result"
2024-10-17 00:52:35 +04:00
}
],
"source": [
"# Краткая информация о DataFrame\n",
"df.info()\n",
"\n",
"# Статистическое описание числовых столбцов\n",
2024-10-18 01:38:52 +04:00
"df.describe().transpose()"
2024-10-17 00:52:35 +04:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Проблема пропущенных данных:\n",
"\n",
"**Проблема пропущенных данных** — это отсутствие значений в наборе данных, что может искажать результаты анализа и статистические выводы.\n",
"\n",
"Проверка на отсутствие значений, представленная ниже, показала, что DataFrame не имеет пустых значений признаков. Нет необходимости использовать методы заполнения пропущенных данных."
]
},
{
"cell_type": "code",
"execution_count": 3,
2024-10-17 00:52:35 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Присутствуют ли пустые значения признаков в колонке:\n",
2024-10-17 00:52:35 +04:00
"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",
"Количество пустых значений признаков в колонке:\n",
2024-10-17 00:52:35 +04:00
"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",
"\n",
"Процент пустых значений признаков в колонке:\n",
"\n"
2024-10-17 00:52:35 +04:00
]
}
],
"source": [
"# Проверка пропущенных данных\n",
"def check_null_columns(dataframe: DataFrame) -> None:\n",
" # Присутствуют ли пустые значения признаков\n",
" print('Присутствуют ли пустые значения признаков в колонке:')\n",
2024-10-17 00:52:35 +04:00
" print(dataframe.isnull().any(), '\\n')\n",
"\n",
" # Количество пустых значений признаков\n",
" print('Количество пустых значений признаков в колонке:')\n",
" print(dataframe.isnull().sum(), '\\n')\n",
2024-10-17 00:52:35 +04:00
"\n",
" # Процент пустых значений признаков\n",
" print('Процент пустых значений признаков в колонке:')\n",
" for column in dataframe.columns:\n",
" null_rate: float = dataframe[column].isnull().sum() / len(dataframe) * 100\n",
2024-10-17 00:52:35 +04:00
" if null_rate > 0:\n",
" print(f\"{column} процент пустых значений: {null_rate:.2f}%\")\n",
" print()\n",
2024-10-17 00:52:35 +04:00
" \n",
"\n",
"# Проверка пропущенных данных\n",
"check_null_columns(df)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Проблема зашумленности данных:\n",
"\n",
"**Зашумленность** это наличие случайных ошибок или вариаций в данных, которые могут затруднить выявление истинных закономерностей. Шум может возникать из-за ошибок измерений, неправильных записей или других факторов.\n",
"\n",
"**Выбросы** это значения, которые значительно отличаются от остальных наблюдений в наборе данных. Выбросы могут указывать на ошибки в данных или на редкие, но важные события. Их наличие может повлиять на статистические методы анализа.\n",
"\n",
"Представленный ниже код помогает определить наличие выбросов в наборе данных и устранить их (при наличии), заменив значения ниже нижней границы (рассматриваемого минимума) на значения нижней границы, а значения выше верхней границы (рассматриваемого максимума) на значения верхней границы."
]
},
{
"cell_type": "code",
"execution_count": 4,
2024-10-17 00:52:35 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Проверка наличия выбросов в колонках:\n",
2024-10-17 00:52:35 +04:00
"Колонка 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",
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",
"# Числовые столбцы 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",
"# Проверка наличия выбросов в колонках\n",
"print('Проверка наличия выбросов в колонках:')\n",
2024-10-17 12:31:09 +04:00
"check_outliers(df, numeric_columns)\n",
"visualize_outliers(df, numeric_columns)"
]
},
{
"cell_type": "code",
"execution_count": 5,
2024-10-17 12:31:09 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Проверка наличия выбросов в колонках после их устранения:\n",
2024-10-17 12:31:09 +04:00
"Колонка 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",
"# Проверка наличия выбросов в колонках\n",
"print('Проверка наличия выбросов в колонках после их устранения:')\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",
"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",
"execution_count": 7,
2024-10-17 00:52:35 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Распределение количества наблюдений по меткам (классам):\n",
2024-10-17 00:52:35 +04:00
"hazardous\n",
"False 81996\n",
"True 8840\n",
"Name: count, dtype: int64 \n",
"\n",
"Проверка сбалансированности выборок:\n",
2024-10-18 01:38:52 +04:00
"Обучающая выборка: (54501, 10)\n",
"Распределение выборки данных по классам в колонке \"hazardous\":\n",
2024-10-17 00:52:35 +04:00
" hazardous\n",
"False 49197\n",
"True 5304\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"False\": 90.27%\n",
"Процент объектов класса \"True\": 9.73%\n",
"\n",
2024-10-18 01:38:52 +04:00
"Контрольная выборка: (18167, 10)\n",
"Распределение выборки данных по классам в колонке \"hazardous\":\n",
2024-10-17 00:52:35 +04:00
" hazardous\n",
"False 16399\n",
"True 1768\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"False\": 90.27%\n",
"Процент объектов класса \"True\": 9.73%\n",
"\n",
2024-10-18 01:38:52 +04:00
"Тестовая выборка: (18168, 10)\n",
"Распределение выборки данных по классам в колонке \"hazardous\":\n",
2024-10-17 00:52:35 +04:00
" hazardous\n",
"False 16400\n",
"True 1768\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"False\": 90.27%\n",
"Процент объектов класса \"True\": 9.73%\n",
"\n",
"Проверка необходимости аугментации выборок:\n",
2024-10-17 00:52:35 +04:00
"Для обучающей выборки аугментация данных требуется\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",
"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",
2024-10-17 00:52:35 +04:00
" 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",
"print('Распределение количества наблюдений по меткам (классам):')\n",
"print(df.hazardous.value_counts(), '\\n')\n",
"\n",
"df_train, df_val, df_test = split_stratified_into_train_val_test(\n",
" df, \n",
" stratify_colname=\"hazardous\", \n",
" frac_train=0.60, \n",
" frac_val=0.20, \n",
" frac_test=0.20\n",
")\n",
"\n",
"# Проверка сбалансированности выборок\n",
"print('Проверка сбалансированности выборок:')\n",
2024-10-17 00:52:35 +04:00
"check_balance(df_train, 'Обучающая выборка', 'hazardous')\n",
"check_balance(df_val, 'Контрольная выборка', 'hazardous')\n",
"check_balance(df_test, 'Тестовая выборка', 'hazardous')\n",
"\n",
"# Проверка необходимости аугментации выборок\n",
"print('Проверка необходимости аугментации выборок:')\n",
2024-10-17 00:52:35 +04:00
"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",
"execution_count": 8,
2024-10-17 00:52:35 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Проверка сбалансированности выборок после применения метода oversampling:\n",
"Обучающая выборка: (99094, 21839)\n",
"Распределение выборки данных по классам в колонке \"hazardous\":\n",
2024-10-17 00:52:35 +04:00
" hazardous\n",
"True 49897\n",
2024-10-17 00:52:35 +04:00
"False 49197\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"True\": 50.35%\n",
"Процент объектов класса \"False\": 49.65%\n",
2024-10-17 00:52:35 +04:00
"\n",
"Контрольная выборка: (33065, 11737)\n",
"Распределение выборки данных по классам в колонке \"hazardous\":\n",
2024-10-17 00:52:35 +04:00
" hazardous\n",
"True 16666\n",
2024-10-17 00:52:35 +04:00
"False 16399\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"True\": 50.40%\n",
"Процент объектов класса \"False\": 49.60%\n",
2024-10-17 00:52:35 +04:00
"\n",
"Тестовая выборка: (33123, 11819)\n",
"Распределение выборки данных по классам в колонке \"hazardous\":\n",
2024-10-17 00:52:35 +04:00
" hazardous\n",
"True 16723\n",
2024-10-17 00:52:35 +04:00
"False 16400\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"True\": 50.49%\n",
"Процент объектов класса \"False\": 49.51%\n",
2024-10-17 00:52:35 +04:00
"\n",
"Проверка необходимости аугментации выборок после применения метода oversampling:\n",
2024-10-17 00:52:35 +04:00
"Для обучающей выборки аугментация данных не требуется\n",
"Для контрольной выборки аугментация данных не требуется\n",
"Для тестовой выборки аугментация данных не требуется\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABgcAAAHzCAYAAAAEk80rAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAC1DklEQVR4nOzdd3RT9f/H8Ve6S1tm2SAbkSWKoIAIKqIMceNmuEUcuP06ABciDoaK4E8BBVFwgJshIHvvvcqeLat75f7+qIlNFy00vTc3z8c5PUqapO/cJPd1733fz+c6DMMwBAAAAAAAAAAA/EaA2QUAAAAAAAAAAICSRXMAAAAAAAAAAAA/Q3MAAAAAAAAAAAA/Q3MAAAAAAAAAAAA/Q3MAAAAAAAAAAAA/Q3MAAAAAAAAAAAA/Q3MAAAAAAAAAAAA/Q3MAAAAAAAAAAAA/Q3MAAHzAqVOntHPnTmVkZJhdCoqRYRg6ceKEduzYYXYpAADgPKWlpenIkSM6dOiQ2aUAAIBilJiYqP379+vkyZNml1LsaA4APqB27drq3r272WUUm44dO6pjx45ml2Fp6enpev/993XxxRcrNDRU5cqVU4MGDfT333+bXZpP2Lhxo6ZNm+b+99q1a/X777+bV1A28fHxeu2113ThhRcqJCREFSpUUMOGDbVt2zazSwNwDshowPsmTpyoPXv2uP89fvx4HTx40LyCslm5cqXuueceRUdHKzQ0VFWrVtVtt91mdlmA3yGPAd/07rvvyul0SpKcTqeGDBlickX/mTp1qq699lpFRUUpMjJSF1xwgd5//32zyyp2RWoOjB8/Xg6Hw/0TFhamhg0bqn///jp69Ki3agRsb9CgQapdu7ak/75n8L6OHTuqT58+kqQ+ffpYZuMrNTVVnTp10uuvv66OHTtq6tSpmjVrlubMmaM2bdqYXZ5PiI+P16OPPqqlS5dqx44devrpp7Vhwwazy1JcXJzatGmjkSNH6vbbb9f06dM1a9YszZs3z70OOFdkNOAdZLQ5rJrRMMeCBQv04osvas+ePZoxY4aeeOIJBQSYf57b9OnTdeWVV2rz5s165513NGvWLD3//PNaunQpeQwUM/LYHOQxvG3ChAn64IMPdODAAX344YeaMGGC2SVJkl5++WX17NlTUVFR+uKLLzRr1izNnj1b/fr1M7u0Yhd0Lg968803VadOHaWkpGjhwoUaPXq0/vjjD23cuFGlSpUq7hoBwK8MHTpUy5Yt04wZM9j4Okdt2rRx/0hSw4YN9fDDD5tclfTCCy/o8OHDWrJkiZo0aeKVv0FGAwDsZsCAAerYsaPq1KkjSXr22WdVtWpVU2s6ceKEHnroIV1//fWaOnWqQkJCJEkHDhyQRB4DAFAYb775pnr16qWXXnpJoaGhmjhxotkl6Z9//tHQoUM1ZMgQvfzyy2aX43Xn1Bzo0qWLLrvsMknSQw89pAoVKuijjz7S9OnTdffddxdrgQB8T2JioiIiIswuwydlZGRo+PDheu6552gMnKdp06Zp8+bNSk5OVrNmzdw77WY5duyYJkyYoM8//9xrjQGJjAZQMDIavqhRo0batWuXNm7cqOjoaNWrV8/skjRu3DilpKRo/PjxeW5jkMcACkIeA1nuvPNOXX311dq5c6caNGigihUrml2SPvjgA7Vt29YvGgNSMV1z4JprrpEkxcTESMo6i+L5559Xs2bNFBkZqdKlS6tLly5at25drsempKRo0KBBatiwocLCwlS1alXdeuut2rVrlyRpz549HtMk5PzJfvBs3rx5cjgc+v777/W///1PVapUUUREhHr06KH9+/fn+tvLli3TDTfcoDJlyqhUqVLq0KGDFi1alOdr7NixY55/f9CgQbnuO3HiRLVs2VLh4eEqX7687rrrrjz/fkGvLTun06nhw4erSZMmCgsLU+XKlfXoo4/mughGfnPs9e/fP9dz5lX7sGHDci1TKWuKk4EDB6p+/foKDQ1VzZo19eKLLyo1NTXPZZVdXvPkvfPOOwoICNC33357TsvD9SWtUKGCwsPD1bJlS/3www95/v2JEyeqdevWKlWqlMqVK6errrpKM2fO9LjPn3/+qQ4dOigqKkqlS5dWq1atctU2depU93saHR2t++67L9c8p3369PGouVy5curYsaMWLFhw1uVUWAsXLlTr1q0VFhamunXr6uuvv/b4fWG/e7Vr1853Wc+bN0+StHfvXvXr108XXnihwsPDVaFCBd1xxx0e871K/w3p/Oeff9SvXz9VqlRJNWrUcP9+7NixqlevnsLDw9W6det8l8exY8f04IMPqnLlygoLC9PFF1+caziZ6zvuqtHF9dkZP368+7YjR46ob9++qlGjhnv+15tuuilX/UWVfdkFBASoSpUquvPOO7Vv375CPf6zzz5TkyZNFBoaqmrVqumJJ57QqVOn3L/ftm2bTp48qaioKHXo0EGlSpVSmTJl1L17d23cuNF9v7lz58rhcOjnn3/O9Te+/fZbORwOLVmyxF2zayioS17LcsGCBbrjjjt0wQUXuL/rAwYMUHJyssdjBw0alOt7OWnSJLVo0UJhYWGqUKGC7r777lzLpE+fPoqMjPS47YcffsjzPY2MjMxVs1S49Wv29U7jxo3VsmVLrVu3Ls/1SV5yru+jo6PVrVs3j+UvZa1H+/fvn+/zuL4brs/cihUr5HQ6lZaWpssuu6zAZSVJc+bMUfv27RUREaGyZcvqpptu0pYtWzzu43ovtm7dqs8++0ySdO211+rpp59WSkqKpP8y+p577tGgQYPc64mmTZsqKChIDodD7du391hPuJZzWFiYwsPDFRUVRUaT0WT0WZDRvp3ReWXlI488orCwsFyv6WxZLmV9v5o2bZrr73zwwQce2VDQ++1wONxTaLiW4wcffKCPP/5YtWrVUnh4uDp06JArn6TCZUheyy2vz5vrPmebyzt7jTk1bdo01/qmMJ+r7J+fiIgIXX755apXr56eeOIJORyOPLcV8nq86yc4OFi1a9fWCy+8oLS0NPf9XN+VlStX5vtcOdeZS5cuVYsWLfTuu++qZs2aCg0NVYMGDfK8xlFGRoZ7SqH7779ftWvX1oABAzRgwACPdUJ4eLh7XejarmrcuLG+++47j33msmXLur/beb3OnD81atRw11i9enU5HA5NnjyZPM6GPCaPyWPz89hbmbh161bdfvvtKl++vMLCwnTZZZfpl19+8bhPfjkQGxuba12Q1/5wQkKCqlSpkmvZu7YHVq1apbZt2yo8PFx16tTR559/nqvOouTi2XJNknbv3q077rhD5cuXV6lSpXTFFVfkyqi8XouUe7uoKMtHktasWaMuXbqodOnSioyM1LXXXqulS5d63Cf7/nKlSpXc66zmzZvn+qzmJee0uqVKlVKzZs30f//3fx73y+s4RE45X8PSpUvVtGlT3XXXXSpfvrzCw8PVqlUrj+sauhTlfSvMZ7ZPnz65phyeOHGiAgIC9N5773ncXpjPdmGc08iBnFwHCSpUqCAp6wM4bdo03XHHHapTp46OHj2qMWPGqEOHDtq8ebOqVasmScrMzFT37t31999/66677tLTTz+t+Ph4zZo1Sxs3bvQ4I+Tuu+9W165dPf7uK6+8kmc977zzjhwOh1566SUdO3ZMw4cPV6dOnbR27VqFh4dLytpg7tKli1q2bKmBAwcqICBA48aN0zXXXKMFCxaodevWuZ63Ro0a7gtjJCQk6PHHH8/zb7/++uvq2bOnHnroIR0/flyjRo3SVVddpTVr1qhs2bK5HvPII4+offv2kqSffvop18G+Rx99VOPHj1ffvn311FNPKSYmRp988onWrFmjRYsWKTg4OM/lUBSnTp3K86IfTqdTPXr00MKFC/XII4/ooosu0oYNG/Txxx9r+/bteX4xCjJu3Di99tpr+vDDD3XPPffkeZ+zLY8RI0aoR48euvfee5WWlqbvvvtOd9xxh3777Td169bNfb/Bgwdr0KBBatu2rd58802FhIRo2bJlmjNnjjp37iwpa2XywAMPqEmTJnrllVdUtmxZrVmzRn/99Ze7Pte
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",
2024-10-18 01:38:52 +04:00
" X: DataFrame = pd.get_dummies(df.drop(column, axis=1))\n",
2024-10-17 00:52:35 +04:00
" 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",
2024-10-17 00:52:35 +04:00
"check_balance(df_train_oversampled, 'Обучающая выборка', 'hazardous')\n",
"check_balance(df_val_oversampled, 'Контрольная выборка', 'hazardous')\n",
"check_balance(df_test_oversampled, 'Тестовая выборка', 'hazardous')\n",
"\n",
"# Проверка необходимости аугментации выборок\n",
"print('Проверка необходимости аугментации выборок после применения метода oversampling:')\n",
2024-10-17 00:52:35 +04:00
"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",
"execution_count": 9,
2024-10-17 00:52:35 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Проверка сбалансированности выборок после применения метода undersampling:\n",
"Обучающая выборка: (10608, 21839)\n",
"Распределение выборки данных по классам в колонке \"hazardous\":\n",
2024-10-17 00:52:35 +04:00
" hazardous\n",
"False 5304\n",
"True 5304\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"False\": 50.00%\n",
"Процент объектов класса \"True\": 50.00%\n",
"\n",
"Контрольная выборка: (3536, 11737)\n",
"Распределение выборки данных по классам в колонке \"hazardous\":\n",
2024-10-17 00:52:35 +04:00
" hazardous\n",
"False 1768\n",
"True 1768\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"False\": 50.00%\n",
"Процент объектов класса \"True\": 50.00%\n",
"\n",
"Тестовая выборка: (3536, 11819)\n",
"Распределение выборки данных по классам в колонке \"hazardous\":\n",
2024-10-17 00:52:35 +04:00
" hazardous\n",
"False 1768\n",
"True 1768\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"False\": 50.00%\n",
"Процент объектов класса \"True\": 50.00%\n",
"\n",
"Проверка необходимости аугментации выборок после применения метода undersampling:\n",
2024-10-17 00:52:35 +04:00
"Для обучающей выборки аугментация данных не требуется\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",
2024-10-18 01:38:52 +04:00
" X: DataFrame = pd.get_dummies(df.drop(column, axis=1))\n",
2024-10-17 00:52:35 +04:00
" 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",
2024-10-17 00:52:35 +04:00
"check_balance(df_train_undersampled, 'Обучающая выборка', 'hazardous')\n",
"check_balance(df_val_undersampled, 'Контрольная выборка', 'hazardous')\n",
"check_balance(df_test_undersampled, 'Тестовая выборка', 'hazardous')\n",
"\n",
"# Проверка необходимости аугментации выборок\n",
"print('Проверка необходимости аугментации выборок после применения метода undersampling:')\n",
2024-10-17 00:52:35 +04:00
"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')"
]
2024-10-18 01:38:52 +04:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Датасет №2: [Зарплаты в области Data Science](https://www.kaggle.com/datasets/henryshan/2023-data-scientists-salary).\n",
"\n",
"### Описание датасета:\n",
"Данный набор данных предназначен для исследования факторов, влияющих на заработную плату специалистов по данным (Data Scientists) в 2023 году. Набор данных содержит информацию о различных характеристиках работников, таких как уровень опыта, тип занятости, местоположение сотрудника и компании, удалённость работы и размер компании. Этот анализ помогает понять, какие факторы наиболее значимо влияют на уровень зарплат в области Data Science, и как изменяются заработные платы в зависимости от этих факторов.\n",
"\n",
"---\n",
"\n",
"### Анализ сведений:\n",
"**Проблемная область:**\n",
"Основная задача изучить, как различные факторы, такие как опыт, тип занятости, местоположение и удалённость работы, влияют на уровень зарплаты специалистов по данным. Это важно для понимания рыночных тенденций и формирования конкурентоспособной системы оплаты труда.\n",
"\n",
"**Актуальность:**\n",
"Данный набор данных актуален для компаний, стремящихся выстроить конкурентоспособные стратегии оплаты труда, а также для специалистов по данным, желающих оценить свои зарплатные ожидания в зависимости от их опыта, географии и типа занятости.\n",
"\n",
"**Объекты наблюдения:**\n",
"Объектами наблюдения являются специалисты по данным, работающие в различных компаниях и странах, с разным уровнем опыта и типом занятости.\n",
"\n",
"**Атрибуты объектов:**\n",
"- work_year: Год, в который была выплачена зарплата.\n",
"- experience_level: Уровень опыта сотрудника.\n",
" - EN: Начальный.\n",
" - MI: Средний.\n",
" - SE: Старший.\n",
" - EX: Исполнительный.\n",
"- employment_type: Тип занятости.\n",
" - PT: Полная.\n",
" - FT: Частичная.\n",
" - CT: Контрактная.\n",
" - FL: Фриланс.\n",
"- job_title: Должность, которую занимал сотрудник.\n",
"- salary: Общая сумма выплаченной заработной платы.\n",
"- salary_currency: Валюта, в которой выплачена зарплата.\n",
"- salary_in_usd: Заработная плата, конвертированная в доллары США (USD).\n",
"- employee_residence: Страна проживания сотрудника в год выплаты зарплаты.\n",
"- remote_ratio: Доля удалённой работы (например, 100% удалённо или частично удалённо).\n",
"- company_location: Страна, в которой расположена основная офисная компания работодателя.\n",
"- company_size: Среднее количество сотрудников, работающих в компании.\n",
"\n",
"**Связь между объектами:**\n",
"Набор данных позволяет исследовать взаимосвязи между факторами, такими как уровень опыта, тип занятости и местоположение сотрудника, с уровнем его заработной платы. Взаимосвязи между этими факторами могут дать полезную информацию о влиянии определённых условий работы на доход.\n",
"\n",
"---\n",
"\n",
"### Качество набора данных:\n",
"**Информативность:**\n",
"Датасет предоставляет важную информацию для анализа различных факторов, влияющих на зарплату специалистов по данным. Он включает множество атрибутов, которые можно использовать для построения моделей и анализа.\n",
"\n",
"**Степень покрытия:**\n",
"Набор данных охватывает специалистов по данным с разным опытом, работающих в различных странах, что позволяет провести сравнительный анализ и выявить региональные и глобальные тренды.\n",
"\n",
"**Соответствие реальным данным:**\n",
"Заработные платы специалистов по данным, приведенные в датасете, отражают реальную ситуацию на рынке труда в 2023 году, предоставляя точные данные для анализа текущих рыночных условий.\n",
2024-10-18 01:38:52 +04:00
"\n",
"**Согласованность меток:**\n",
"Все категории, такие как уровни опыта или типы занятости, имеют четко определённые метки, что упрощает анализ и моделирование.\n",
"\n",
"---\n",
"\n",
"### Бизес-цели:\n",
"1. **Оптимизация структуры оплаты труда:**\n",
"Компании могут использовать данный анализ для создания конкурентных предложений по оплате труда, основываясь на опыте, географии и других значимых факторах.\n",
"2. **Планирование найма и удержание специалистов:**\n",
"Помогает работодателям понять, какие факторы могут привлечь или удержать специалистов по данным, и оптимизировать HR-процессы для сокращения текучести кадров.\n",
2024-10-18 01:38:52 +04:00
"3. **Анализ глобальных и региональных зарплатных трендов:**\n",
"Позволяет компаниям проводить сравнительный анализ зарплат по регионам, уровням опыта и типам занятости, помогая в принятии решений о расширении бизнеса в разные страны.\n",
2024-10-18 01:38:52 +04:00
"\n",
"**Эффект для бизнеса:**\n",
"Компании, использующие данную информацию, могут предлагать конкурентоспособные зарплаты, улучшить процессы найма и удержания специалистов, а также сократить издержки, связанные с высокими зарплатными ожиданиями. Это также помогает улучшить планирование бюджета на персонал.\n",
"\n",
"---\n",
"\n",
"### Технические цели:\n",
"1. **Построение модели прогнозирования зарплат:**\n",
"Создание модели, которая будет предсказывать уровень зарплаты специалиста по данным на основе таких факторов, как опыт, регион и удалённость работы.\n",
"2. **Анализ влияния опыта и удалённости на зарплату:**\n",
"Исследование того, как уровень опыта и удалённость работы влияют на заработную плату, что может помочь компаниям лучше планировать условия найма.\n",
"3. **Оптимизация найма специалистов:**\n",
"С помощью анализа компания может определить наиболее значимые факторы для назначения зарплат, чтобы предлагать более конкурентные условия и привлекать лучших специалистов.\n",
"\n",
"**Входные данные:**\n",
"Год, уровень опыта, тип занятости, должность, зарплата, страна проживания, удалённость работы.\n",
"\n",
"**Целевой признак:**\n",
"Признак \"salary_in_usd\" заработная плата в долларах США.\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Выгрузка данных из файла в DataFrame:"
]
},
{
"cell_type": "code",
"execution_count": 21,
2024-10-18 01:38:52 +04:00
"metadata": {},
"outputs": [],
"source": [
"df: DataFrame = pd.read_csv('..//static//csv//ds_salaries.csv')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Краткая информация о DataFrame:"
]
},
{
"cell_type": "code",
"execution_count": 22,
2024-10-18 01:38:52 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"RangeIndex: 3755 entries, 0 to 3754\n",
"Data columns (total 11 columns):\n",
" # Column Non-Null Count Dtype \n",
"--- ------ -------------- ----- \n",
" 0 work_year 3755 non-null int64 \n",
" 1 experience_level 3755 non-null object\n",
" 2 employment_type 3755 non-null object\n",
" 3 job_title 3755 non-null object\n",
" 4 salary 3755 non-null int64 \n",
" 5 salary_currency 3755 non-null object\n",
" 6 salary_in_usd 3755 non-null int64 \n",
" 7 employee_residence 3755 non-null object\n",
" 8 remote_ratio 3755 non-null int64 \n",
" 9 company_location 3755 non-null object\n",
" 10 company_size 3755 non-null object\n",
"dtypes: int64(4), object(7)\n",
"memory usage: 322.8+ KB\n"
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>count</th>\n",
" <th>mean</th>\n",
" <th>std</th>\n",
" <th>min</th>\n",
" <th>25%</th>\n",
" <th>50%</th>\n",
" <th>75%</th>\n",
" <th>max</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>work_year</th>\n",
" <td>3755.0</td>\n",
" <td>2022.373635</td>\n",
" <td>0.691448</td>\n",
" <td>2020.0</td>\n",
" <td>2022.0</td>\n",
" <td>2022.0</td>\n",
" <td>2023.0</td>\n",
" <td>2023.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>salary</th>\n",
" <td>3755.0</td>\n",
" <td>190695.571771</td>\n",
" <td>671676.500508</td>\n",
" <td>6000.0</td>\n",
" <td>100000.0</td>\n",
" <td>138000.0</td>\n",
" <td>180000.0</td>\n",
" <td>30400000.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>salary_in_usd</th>\n",
" <td>3755.0</td>\n",
" <td>137570.389880</td>\n",
" <td>63055.625278</td>\n",
" <td>5132.0</td>\n",
" <td>95000.0</td>\n",
" <td>135000.0</td>\n",
" <td>175000.0</td>\n",
" <td>450000.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>remote_ratio</th>\n",
" <td>3755.0</td>\n",
" <td>46.271638</td>\n",
" <td>48.589050</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>100.0</td>\n",
" <td>100.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" count mean std min 25% \\\n",
"work_year 3755.0 2022.373635 0.691448 2020.0 2022.0 \n",
"salary 3755.0 190695.571771 671676.500508 6000.0 100000.0 \n",
"salary_in_usd 3755.0 137570.389880 63055.625278 5132.0 95000.0 \n",
"remote_ratio 3755.0 46.271638 48.589050 0.0 0.0 \n",
"\n",
" 50% 75% max \n",
"work_year 2022.0 2023.0 2023.0 \n",
"salary 138000.0 180000.0 30400000.0 \n",
"salary_in_usd 135000.0 175000.0 450000.0 \n",
"remote_ratio 0.0 100.0 100.0 "
]
},
"execution_count": 22,
2024-10-18 01:38:52 +04:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Краткая информация о DataFrame\n",
"df.info()\n",
"\n",
"# Статистическое описание числовых столбцов\n",
"df.describe().transpose()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Проблема пропущенных данных:\n",
"\n",
"Проверка на отсутствие значений, представленная ниже, показала, что DataFrame не имеет пустых значений признаков. Нет необходимости использовать методы заполнения пропущенных данных."
]
},
{
"cell_type": "code",
"execution_count": 23,
2024-10-18 01:38:52 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Присутствуют ли пустые значения признаков в колонке:\n",
2024-10-18 01:38:52 +04:00
"work_year False\n",
"experience_level False\n",
"employment_type False\n",
"job_title False\n",
"salary False\n",
"salary_currency False\n",
"salary_in_usd False\n",
"employee_residence False\n",
"remote_ratio False\n",
"company_location False\n",
"company_size False\n",
"dtype: bool \n",
"\n",
"Количество пустых значений признаков в колонке:\n",
2024-10-18 01:38:52 +04:00
"work_year 0\n",
"experience_level 0\n",
"employment_type 0\n",
"job_title 0\n",
"salary 0\n",
"salary_currency 0\n",
"salary_in_usd 0\n",
"employee_residence 0\n",
"remote_ratio 0\n",
"company_location 0\n",
"company_size 0\n",
"dtype: int64 \n",
"\n",
"Процент пустых значений признаков в колонке:\n",
"\n"
2024-10-18 01:38:52 +04:00
]
}
],
"source": [
"# Проверка пропущенных данных\n",
"check_null_columns(df)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Проблема зашумленности данных:\n",
"\n",
"Представленный ниже код помогает определить наличие выбросов в наборе данных и устранить их (при наличии), заменив значения ниже нижней границы (рассматриваемого минимума) на значения нижней границы, а значения выше верхней границы (рассматриваемого максимума) на значения верхней границы."
]
},
{
"cell_type": "code",
"execution_count": 24,
2024-10-18 01:38:52 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Проверка наличия выбросов в колонках:\n",
2024-10-18 01:38:52 +04:00
"Колонка work_year:\n",
"\tЕсть выбросы: Да\n",
"\tКоличество выбросов: 76\n",
"\tМинимальное значение: 2020\n",
"\tМаксимальное значение: 2023\n",
"\t1-й квартиль (Q1): 2022.0\n",
"\t3-й квартиль (Q3): 2023.0\n",
"\n",
"Колонка salary:\n",
"\tЕсть выбросы: Да\n",
"\tКоличество выбросов: 113\n",
"\tМинимальное значение: 6000\n",
"\tМаксимальное значение: 30400000\n",
"\t1-й квартиль (Q1): 100000.0\n",
"\t3-й квартиль (Q3): 180000.0\n",
"\n",
"Колонка salary_in_usd:\n",
"\tЕсть выбросы: Да\n",
"\tКоличество выбросов: 63\n",
"\tМинимальное значение: 5132\n",
"\tМаксимальное значение: 450000\n",
"\t1-й квартиль (Q1): 95000.0\n",
"\t3-й квартиль (Q3): 175000.0\n",
"\n",
"Колонка remote_ratio:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 0\n",
"\tМаксимальное значение: 100\n",
"\t1-й квартиль (Q1): 0.0\n",
"\t3-й квартиль (Q3): 100.0\n",
"\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1500x1000 with 4 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Числовые столбцы DataFrame\n",
"numeric_columns: list[str] = [\n",
" 'work_year',\n",
" 'salary',\n",
" 'salary_in_usd',\n",
" 'remote_ratio'\n",
"]\n",
"\n",
"# Проверка наличия выбросов в колонках\n",
"print('Проверка наличия выбросов в колонках:')\n",
2024-10-18 01:38:52 +04:00
"check_outliers(df, numeric_columns)\n",
"visualize_outliers(df, numeric_columns)"
]
},
{
"cell_type": "code",
"execution_count": 25,
2024-10-18 01:38:52 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Проверка наличия выбросов в колонках после их устранения:\n",
2024-10-18 01:38:52 +04:00
"Колонка work_year:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 2020.5\n",
"\tМаксимальное значение: 2023.0\n",
"\t1-й квартиль (Q1): 2022.0\n",
"\t3-й квартиль (Q3): 2023.0\n",
"\n",
"Колонка salary:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 6000.0\n",
"\tМаксимальное значение: 300000.0\n",
"\t1-й квартиль (Q1): 100000.0\n",
"\t3-й квартиль (Q3): 180000.0\n",
"\n",
"Колонка salary_in_usd:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 5132.0\n",
"\tМаксимальное значение: 295000.0\n",
"\t1-й квартиль (Q1): 95000.0\n",
"\t3-й квартиль (Q3): 175000.0\n",
"\n",
"Колонка remote_ratio:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 0\n",
"\tМаксимальное значение: 100\n",
"\t1-й квартиль (Q1): 0.0\n",
"\t3-й квартиль (Q3): 100.0\n",
"\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1500x1000 with 4 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Устраняем выборсы\n",
"df: DataFrame = remove_outliers(df, numeric_columns)\n",
"\n",
"# Проверка наличия выбросов в колонках\n",
"print('Проверка наличия выбросов в колонках после их устранения:')\n",
2024-10-18 01:38:52 +04:00
"check_outliers(df, numeric_columns)\n",
"visualize_outliers(df, numeric_columns)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Разбиение набора данных на выборки:\n",
"\n",
"Разделим выборку данных на 3 группы и проанализируем качество распределения данных.\n",
"\n",
"Стратифицированное разбиение требует, чтобы в каждом классе, по которому происходит стратификация, было минимум по два элемента, иначе метод не сможет корректно разделить данные на тренировочные, валидационные и тестовые наборы.\n",
"\n",
"Чтобы решить эту проблему введём категории для значения зарплаты. Вместо того, чтобы использовать точные значения зарплаты для стратификации, мы создадим категории зарплат, основываясь на квартилях (25%, 50%, 75%) и минимальном и максимальном значении зарплаты. Это позволит создать более крупные классы, что устранит проблему с редкими значениями\n",
2024-10-18 01:38:52 +04:00
"\n",
"Категории для разбиения зарплат:\n",
"- Низкая зарплата: зарплаты ниже первого квартиля (25%) — это значения меньше 95000.\n",
"- Средняя зарплата: зарплаты между первым квартилем (25%) и третьим квартилем (75%) — это зарплаты от 95000 до 175000.\n",
"- Высокая зарплата: зарплаты выше третьего квартиля (75%) и до максимального значения — это зарплаты выше 175000.\n",
"\n",
"Весь набор данных состоит из 3755 объектов, из которых 1867 (около 49.7%) имеют средний уровень зарплаты (medium), 956 (около 25.4%) низкий уровень зарплаты (low), и 932 (около 24.8%) высокий уровень зарплаты (high).\n",
"\n",
"Все выборки показывают одинаковое распределение классов, что свидетельствует о том, что данные были отобраны случайным образом и не содержат явного смещения.\n",
"\n",
"Однако, несмотря на сбалансированность при разбиении данных, в целом данные обладают значительным дисбалансом между классами. Это может быть проблемой при обучении модели, так как она может иметь тенденцию игнорировать низкие или высокие зарплаты (low или high), что следует учитывать при дальнейшем анализе и выборе методов обработки данных.\n",
"\n",
"Для получения более сбалансированных выборок данных необходимо воспользоваться методами приращения (аугментации) данных, а именно методами oversampling и undersampling."
]
},
{
"cell_type": "code",
"execution_count": 26,
2024-10-18 01:38:52 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Распределение количества наблюдений по меткам (классам):\n",
2024-10-18 01:38:52 +04:00
"salary_in_usd\n",
"100000.0 99\n",
"150000.0 98\n",
"120000.0 91\n",
"160000.0 84\n",
"130000.0 82\n",
" ..\n",
"39916.0 1\n",
"26005.0 1\n",
"22611.0 1\n",
"5679.0 1\n",
"40038.0 1\n",
"Name: count, Length: 1002, dtype: int64 \n",
"\n",
"Статистическое описание целевого признака:\n",
2024-10-18 01:38:52 +04:00
"count 3755.000000\n",
"mean 136959.779760\n",
"std 61098.121137\n",
"min 5132.000000\n",
"25% 95000.000000\n",
"50% 135000.000000\n",
"75% 175000.000000\n",
"max 295000.000000\n",
"Name: salary_in_usd, dtype: float64 \n",
"\n",
"Распределение количества наблюдений по меткам (классам):\n",
2024-10-18 01:38:52 +04:00
"salary_category\n",
"medium 1867\n",
"low 956\n",
"high 932\n",
"Name: count, dtype: int64 \n",
"\n",
"Проверка сбалансированности выборок:\n",
2024-10-18 01:38:52 +04:00
"Обучающая выборка: (2253, 12)\n",
"Распределение выборки данных по классам в колонке \"salary_category\":\n",
2024-10-18 01:38:52 +04:00
" salary_category\n",
"medium 1120\n",
"low 574\n",
"high 559\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"medium\": 49.71%\n",
"Процент объектов класса \"low\": 25.48%\n",
"Процент объектов класса \"high\": 24.81%\n",
"\n",
"Контрольная выборка: (751, 12)\n",
"Распределение выборки данных по классам в колонке \"salary_category\":\n",
2024-10-18 01:38:52 +04:00
" salary_category\n",
"medium 373\n",
"low 191\n",
"high 187\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"medium\": 49.67%\n",
"Процент объектов класса \"low\": 25.43%\n",
"Процент объектов класса \"high\": 24.90%\n",
"\n",
"Тестовая выборка: (751, 12)\n",
"Распределение выборки данных по классам в колонке \"salary_category\":\n",
2024-10-18 01:38:52 +04:00
" salary_category\n",
"medium 374\n",
"low 191\n",
"high 186\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"medium\": 49.80%\n",
"Процент объектов класса \"low\": 25.43%\n",
"Процент объектов класса \"high\": 24.77%\n",
"\n",
"Проверка необходимости аугментации выборок:\n",
2024-10-18 01:38:52 +04:00
"Для обучающей выборки аугментация данных требуется\n",
"Для контрольной выборки аугментация данных требуется\n",
"Для тестовой выборки аугментация данных требуется\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1500x500 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Вывод распределения количества наблюдений по меткам (классам)\n",
"print('Распределение количества наблюдений по меткам (классам):')\n",
2024-10-18 01:38:52 +04:00
"print(df.salary_in_usd.value_counts(), '\\n')\n",
"\n",
"# Статистическое описание целевого признака\n",
"print('Статистическое описание целевого признака:')\n",
2024-10-18 01:38:52 +04:00
"print(df['salary_in_usd'].describe().transpose(), '\\n')\n",
"\n",
"# Определим границы для каждой категории зарплаты\n",
"bins: list[float] = [df['salary_in_usd'].min() - 1, \n",
" df['salary_in_usd'].quantile(0.25), \n",
" df['salary_in_usd'].quantile(0.75), \n",
" df['salary_in_usd'].max() + 1]\n",
2024-10-18 01:38:52 +04:00
"labels: list[str] = ['low', 'medium', 'high']\n",
"\n",
"# Создаем новую колонку с категориями зарплат#\n",
2024-10-18 01:38:52 +04:00
"df['salary_category'] = pd.cut(df['salary_in_usd'], bins=bins, labels=labels)\n",
"\n",
"# Вывод распределения количества наблюдений по меткам (классам)\n",
"print('Распределение количества наблюдений по меткам (классам):')\n",
2024-10-18 01:38:52 +04:00
"print(df['salary_category'].value_counts(), '\\n')\n",
"\n",
"df_train, df_val, df_test = split_stratified_into_train_val_test(\n",
" df,\n",
" stratify_colname=\"salary_category\", \n",
" frac_train=0.60, \n",
" frac_val=0.20, \n",
" frac_test=0.20\n",
")\n",
"\n",
"# Проверка сбалансированности выборок\n",
"print('Проверка сбалансированности выборок:')\n",
2024-10-18 01:38:52 +04:00
"check_balance(df_train, 'Обучающая выборка', 'salary_category')\n",
"check_balance(df_val, 'Контрольная выборка', 'salary_category')\n",
"check_balance(df_test, 'Тестовая выборка', 'salary_category')\n",
"\n",
"# Проверка необходимости аугментации выборок\n",
"print('Проверка необходимости аугментации выборок:')\n",
2024-10-18 01:38:52 +04:00
"print(f\"Для обучающей выборки аугментация данных {'не ' if not need_augmentation(df_train, 'salary_category', 'low', 'medium') else ''}требуется\")\n",
"print(f\"Для контрольной выборки аугментация данных {'не ' if not need_augmentation(df_val, 'salary_category', 'low', 'medium') else ''}требуется\")\n",
"print(f\"Для тестовой выборки аугментация данных {'не ' if not need_augmentation(df_test, 'salary_category', 'low', 'medium') else ''}требуется\")\n",
" \n",
"# Визуализация сбалансированности классов\n",
"visualize_balance(df_train, df_val, df_test, 'salary_category')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Приращение данных:"
]
},
{
"cell_type": "code",
"execution_count": 27,
2024-10-18 01:38:52 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Проверка сбалансированности выборок после применения метода oversampling:\n",
"Обучающая выборка: (3360, 240)\n",
"Распределение выборки данных по классам в колонке \"salary_category\":\n",
2024-10-18 01:38:52 +04:00
" salary_category\n",
"low 1121\n",
"medium 1120\n",
"high 1119\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"low\": 33.36%\n",
"Процент объектов класса \"medium\": 33.33%\n",
"Процент объектов класса \"high\": 33.30%\n",
"\n",
"Контрольная выборка: (1119, 154)\n",
"Распределение выборки данных по классам в колонке \"salary_category\":\n",
2024-10-18 01:38:52 +04:00
" salary_category\n",
"low 373\n",
"medium 373\n",
"high 373\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"low\": 33.33%\n",
"Процент объектов класса \"medium\": 33.33%\n",
"Процент объектов класса \"high\": 33.33%\n",
"\n",
"Тестовая выборка: (1122, 159)\n",
"Распределение выборки данных по классам в колонке \"salary_category\":\n",
2024-10-18 01:38:52 +04:00
" salary_category\n",
"low 374\n",
2024-10-18 01:38:52 +04:00
"medium 374\n",
"high 374\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"low\": 33.33%\n",
"Процент объектов класса \"medium\": 33.33%\n",
"Процент объектов класса \"high\": 33.33%\n",
2024-10-18 01:38:52 +04:00
"\n",
"Проверка необходимости аугментации выборок после применения метода oversampling:\n",
2024-10-18 01:38:52 +04:00
"Для обучающей выборки аугментация данных не требуется\n",
"Для контрольной выборки аугментация данных не требуется\n",
"Для тестовой выборки аугментация данных не требуется\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABjUAAAH/CAYAAAAfV19VAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAC/CklEQVR4nOzdd3gUZdvG4Ws3vSf0Ir1LEcUGqGClWrB3seH3gq+9N4oVO6CgoCIKCiJKl45IVXrvNQmQCiG97Xx/8O6aTYEkJJktv/M4ODSb3dl7JzN7Pbv3zDMWwzAMAQAAAAAAAAAAuDir2QUAAAAAAAAAAACUBk0NAAAAAAAAAADgFmhqAAAAAAAAAAAAt0BTAwAAAAAAAAAAuAWaGgAAAAAAAAAAwC3Q1AAAAAAAAAAAAG6BpgYAAAAAAAAAAHALNDUAAAAAAAAAAIBboKkBAKg0qampOnTokNLT080uBRXs5MmT2rdvn/Ly8swuBQAAnIO8vDzFx8fryJEjZpcCAAAqUFZWlo4ePar4+HizS6lwNDUAL9O4cWP179/f7DLgoQzD0NixY3X55ZcrODhY4eHhatKkiSZOnGh2aW4hJiZG33//vePnQ4cOadKkSeYVVEBubq4+/PBDXXDBBQoICFBUVJRatGihxYsXm10a4DHIaMCzzJ49W5s2bXL8PH36dG3fvt28ggrYu3evHn/8cdWtW1f+/v6qXbu2OnfuLMMwzC4NMB15DOBsvvjiC508edLx8+eff+4yB3MuWrRIN910kyIjIxUUFKT69evr6aefNrusClempsb3338vi8Xi+BcYGKiWLVvqySefVFxcXGXVCHi8IUOGqHHjxpL+3c9w7kaPHu30BbGn6N+/v7p37y7JedtxBffee6/+7//+T23atNGPP/6ohQsXatGiRbr11lvNLs0tWCwWDRo0SPPnz9ehQ4f00ksvafny5aV6bGVmdHZ2tq677jq9+eab6t69u6ZOnaqFCxdqyZIl6ty58zktG3B1ZHTlIKPhqQrm8Y033qiLLrpITZo00e23367HH39cqampZpeoNWvW6NJLL9WSJUv0yiuvaP78+Vq4cKGmT5/OexxcFnlcOchjoHxmzZqlIUOGKDo6WpMmTdKbb76poKAgs8vS6NGj1aNHD6WkpGjEiBFauHChFi5cqGHDhpldWoXzLc+Dhg0bpiZNmigrK0srVqzQmDFjNHfuXG3btk3BwcEVXSMAlMvo0aNVo0YNjrKpIj/88IOmTJmiiRMn6t577zW7HLdUv359Pf744+rZs6ckqW7duvrzzz/LtIzKyOjhw4fr77//1vz58x0fDgDgXJDR8HTDhg1T9erVNWTIEB06dEiHDh1ScHCwOnToYGpdOTk5evjhh9WyZUstWLBAERERptYDwFzkMVA+r732mm666SaNGDFCVqtVn3zyiaxWcydE2rt3r5577jkNGDBAo0eP9vjmb7maGr169dLFF18sSXrsscdUvXp1ffrpp5oxY4buueeeCi0QgOvKysqSv7+/6W/c7i49PV0hISFml3HOPvroI91zzz00NM7R559/rv/+979KTExUu3btyrxtVHRG5+Xl6fPPP9fzzz9PQwNwI2R0xfCUjEbVs+fxo48+qm3btmnUqFGaMGGC6Z+ZZ82apd27d2vXrl00NIAqQB5XDPIYrqZbt246fPiwdu7cqQYNGui8884zuySNHDlSderU0ciRIz2+oSFV0DU1rrnmGknSwYMHJUnJycl64YUX1L59e4WGhio8PFy9evXS5s2bizw2KytLQ4YMUcuWLRUYGKi6devq1ltv1f79+yWdnk+84HQahf8V/ILlzz//lMVi0ZQpU/Taa6+pTp06CgkJ0U033aTo6Ogiz/3333+rZ8+eioiIUHBwsLp166aVK1cW+xq7d+9e7PMPGTKkyH0nTpyoTp06KSgoSNWqVdPdd99d7POf6bUVZLPZ9Pnnn6tt27YKDAxU7dq19cQTT+jEiRNO92vcuLH69u1b5HmefPLJIsssrvaPPvqoyDqVTk87MnjwYDVv3lwBAQFq0KCBXnrpJWVnZxe7rgrq3r17keW9++67slqt+umnn8q1Pj7++GN16dJF1atXV1BQkDp16qRff/212OefOHGiLr30UgUHBysqKkpXXXWVFixY4HSfP/74Q926dVNYWJjCw8N1ySWXFKlt6tSpjr9pjRo1dP/99ys2NtbpPv3793eqOSoqSt27dy/11DFnsm7dOvXo0UM1atRQUFCQmjRpokceeaTc66Wg0u6v9v1r8uTJeuONN1S/fn0FBwdr06ZNslgs+uyzz4ose9WqVbJYLPr5559L/VptNptGjBih9u3bKzAwUDVr1lTPnj21bt06x33Gjx+va665RrVq1VJAQIDOP/98jRkzxmk5jRs31vbt27Vs2bJi3y9OnjypZ555Rg0aNFBAQICaN2+u4cOHy2azOS0nKSlJDzzwgMLDwxUZGamHHnpImzdvlsViKXKa7pIlS3TllVcqJCREkZGRuvnmm7Vz506n+wwZMkQWi0U7duzQvffeq6ioKF1xxRUaP368LBaLNm7cWGSdvPfee/Lx8SmyzZVF4fewGjVqqE+fPtq2bVupHn+2fSA9PV3btm1TgwYN1KdPH4WHhyskJKTIPnDgwIFSby/FvX/Y3ycKrvstW7aof//+atq0qQIDA1WnTh098sgjSkpKcnqs/TT1Q4cOOW6bP3++unTpouDgYEVERKhv375F1on9b5aYmOi4bd26dcVuA+3atSv2i/8//vjDsW2EhYWpT58+RebU7t+/v+O06GbNmumyyy5TcnKygoKCitRdnG+++UaSdMkllzi9B9WuXVvSvxndoEEDNW3atMR93r6v//nnn8rKytJTTz2lEydO6MMPP1RAQIB8fHwUFhamvn37av78+WfMaB8fH1177bVas2aNU0b37dtXFotFQUFBatSokSIjIxUeHq4HH3zQkW32jLZarfL19XXK6AEDBigwMNBxFktJGd2iRYsi65mM/hcZTUaT0e6f0WXZj0u7r4SGhhZ5nl9//dWRDcXVfKb3BovFoieffFKTJk1Sq1atFBgYqE6dOumvv/4q8jwbN25Ur169FB4ertDQUEeGlGa92f8V/Nt3795d7dq1O9MqdKqxsL59+xaZsiQ9PV3PP/+8Y/ts1aqVPv744yLXorjkkks0ZMgQBQQEqFOnTrrjjjsknZ6qs3v37mfdvwu+JqvVqrCwMEVERDh9Zp40aZIsFovjaMyS/gUGBjrq+uWXX2QYhgYPHqyoqCjH8ps3b669e/cWWQcvvviiQkNDHcuqX7++5s2bV+Rv0a5dO3Xq1OmMn5kLjjEK5rGPj4+qVaumXbt2OZZpz7dGjRqRxwWQxyUjj8ljs/K4sjIxNjZWjzzyiGrXrq2AgAC1bdtW3333ndN97NtccdtxaGio0xk4xX0ettls6tChQ5G/lX08cODAAfXo0UMhISGqV6+ehg0bViTvSpuLhT8n1q9fXwMGDHC6LoUkxcfH69FHH1Xt2rUVGBioCy64QBMmTHC6T3GvRSr6flqW9SOd/r7ijjvuULVq1RQcHKzLL79cc+bMcbpPwSyLjIxU586ddd5556lPnz7F5kZh9sfb/wUEBKhly5Z6//33ndZZcd9DFFb4+j9r1qxRp06dNHDgQMd2065dO40bN67IY8vydyvNNmuvt6ClS5cqICBA//d//+d0e2m27dIo15kahdkbENWrV5d0eiOYPn267rjjDjVp0kRxcXH6+uuv1a1bN+3YsUP16tWTJOXn56tv375avHix7r77bj399NNKTU3VwoULtW3bNjVr1szxHPfcc4969+7t9LyvvvpqsfW8++67slgsevnllxUfH6/PP/9c1113nTZt2uSY32zJkiXq1auXOnXqpMGDB8tqtTre9JcvX65LL720yHLPO+88vf/++5KktLQ0/ec//yn2ud98803deeedeuyxx5SQkKBRo0bpqquu0saNGxUZGVnkMQMGDNCVV14pSfrtt9/0+++/O/3+iSee0Pfff6+HH35YTz31lA4ePKg
2024-10-18 01:38:52 +04:00
"text/plain": [
"<Figure size 1500x500 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Приращение данных (oversampling)\n",
"df_train_oversampled: DataFrame = oversample(df_train, 'salary_category')\n",
"df_val_oversampled: DataFrame = oversample(df_val, 'salary_category')\n",
"df_test_oversampled: DataFrame = oversample(df_test, 'salary_category')\n",
"\n",
"# Проверка сбалансированности выборок\n",
"print('Проверка сбалансированности выборок после применения метода oversampling:')\n",
2024-10-18 01:38:52 +04:00
"check_balance(df_train_oversampled, 'Обучающая выборка', 'salary_category')\n",
"check_balance(df_val_oversampled, 'Контрольная выборка', 'salary_category')\n",
"check_balance(df_test_oversampled, 'Тестовая выборка', 'salary_category')\n",
"\n",
"# Проверка необходимости аугментации выборок\n",
"print('Проверка необходимости аугментации выборок после применения метода oversampling:')\n",
2024-10-18 01:38:52 +04:00
"print(f\"Для обучающей выборки аугментация данных {'не ' if not need_augmentation(df_train_oversampled, 'salary_category', 'low', 'medium') else ''}требуется\")\n",
"print(f\"Для контрольной выборки аугментация данных {'не ' if not need_augmentation(df_val_oversampled, 'salary_category', 'low', 'medium') else ''}требуется\")\n",
"print(f\"Для тестовой выборки аугментация данных {'не ' if not need_augmentation(df_test_oversampled, 'salary_category', 'low', 'medium') else ''}требуется\")\n",
" \n",
"# Визуализация сбалансированности классов\n",
"visualize_balance(df_train_oversampled, df_val_oversampled, df_test_oversampled, 'salary_category')"
]
},
{
"cell_type": "code",
"execution_count": 28,
2024-10-18 01:38:52 +04:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Проверка сбалансированности выборок после применения метода undersampling:\n",
"Обучающая выборка: (1677, 240)\n",
"Распределение выборки данных по классам в колонке \"salary_category\":\n",
2024-10-18 01:38:52 +04:00
" salary_category\n",
"low 559\n",
"medium 559\n",
"high 559\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"low\": 33.33%\n",
"Процент объектов класса \"medium\": 33.33%\n",
"Процент объектов класса \"high\": 33.33%\n",
"\n",
"Контрольная выборка: (561, 154)\n",
"Распределение выборки данных по классам в колонке \"salary_category\":\n",
2024-10-18 01:38:52 +04:00
" salary_category\n",
2024-10-18 01:43:18 +04:00
"low 187\n",
"medium 187\n",
"high 187\n",
2024-10-18 01:38:52 +04:00
"Name: count, dtype: int64\n",
"Процент объектов класса \"low\": 33.33%\n",
"Процент объектов класса \"medium\": 33.33%\n",
"Процент объектов класса \"high\": 33.33%\n",
"\n",
"Тестовая выборка: (558, 159)\n",
"Распределение выборки данных по классам в колонке \"salary_category\":\n",
2024-10-18 01:38:52 +04:00
" salary_category\n",
"low 186\n",
"medium 186\n",
"high 186\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"low\": 33.33%\n",
"Процент объектов класса \"medium\": 33.33%\n",
"Процент объектов класса \"high\": 33.33%\n",
"\n",
"Проверка необходимости аугментации выборок после применения метода undersampling:\n",
2024-10-18 01:38:52 +04:00
"Для обучающей выборки аугментация данных не требуется\n",
"Для контрольной выборки аугментация данных не требуется\n",
"Для тестовой выборки аугментация данных не требуется\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABjUAAAH/CAYAAAAfV19VAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAACma0lEQVR4nOzdd3xT9f7H8XfSvQsUKCB7T1FcgAhOpgO3uHDhveBVr3szXNctoLhFFFyIsgUBUZkKsvfeqwNK6W5zfn/wS2w6oPvknLyej8d9/H6GNPk0TfI67fecE4dhGIYAAAAAAAAAAAB8nNPsAQAAAAAAAAAAAEqCRQ0AAAAAAAAAAGAJLGoAAAAAAAAAAABLYFEDAAAAAAAAAABYAosaAAAAAAAAAADAEljUAAAAAAAAAAAAlsCiBgAAAAAAAAAAsAQWNQAAAAAAAAAAgCWwqAEAqDSpqanatWuX0tLSzB4FFezYsWPatm2bcnNzzR4FAACUQ25uro4cOaI9e/aYPQoAAKhAmZmZOnDggI4cOWL2KBWORQ3AzzRq1EgDBw40ewzYlGEY+vjjj3XBBRcoPDxc0dHRaty4scaPH2/2aJawb98+ffHFF57/3rVrlyZMmGDeQPnk5OTo9ddf15lnnqmQkBBVq1ZNzZs317x588weDbANGg3Yy/Tp07Vq1SrPf0+ePFnr1683b6B8tm7dqvvuu0916tRRcHCwateurc6dO8swDLNHA0xHjwGcznvvvadjx455/vvdd9/1mZ05586dq6uuukqxsbEKCwtTvXr19NBDD5k9VoUr1aLGF198IYfD4flfaGioWrRooQceeECHDx+urBkB2xs2bJgaNWok6Z/XGcpvzJgxXn8gtouBAweqR48ekryfO75gwIAB+te//qXWrVvrq6++0pw5czR37lxde+21Zo9mCQ6HQ0OGDNHs2bO1a9cuPfHEE1qwYEGJvrYyG52VlaXLLrtMzz//vHr06KGJEydqzpw5+vXXX9W5c+dy3Tbg62h05aDRsKv8Pb7yyit19tlnq3Hjxrr++ut13333KTU11ewRtXTpUp133nn69ddf9dRTT2n27NmaM2eOJk+ezHscfBY9rhz0GCibadOmadiwYdq7d68mTJig559/XmFhYWaPpTFjxqhnz55KSUnRyJEjNWfOHM2ZM0cjRowwe7QKF1iWLxoxYoQaN26szMxMLVy4UB988IFmzpypdevWKTw8vKJnBIAyGTNmjOLi4tjLpop8+eWX+u677zR+/HgNGDDA7HEsqV69errvvvvUq1cvSVKdOnX022+/leo2KqPRr732mv7880/Nnj3b88sBAJQHjYbdjRgxQjVq1NCwYcO0a9cu7dq1S+Hh4erQoYOpc2VnZ+uuu+5SixYt9MsvvygmJsbUeQCYix4DZfPMM8/oqquu0siRI+V0OvXWW2/J6TT3hEhbt27VI488okGDBmnMmDG2X/wt06JG7969dc4550iS7r33XtWoUUNvv/22pkyZoltuuaVCBwTguzIzMxUcHGz6G7fVpaWlKSIiwuwxyu2NN97QLbfcwoJGOb377rv6z3/+o8TERLVr167Uz42KbnRubq7effddPfrooyxoABZCoyuGXRqNqufu8T333KN169Zp9OjRGjdunOm/M0+bNk2bN2/Wpk2bWNAAqgA9rhj0GL6me/fu2r17tzZu3Kj69evrjDPOMHskjRo1SvHx8Ro1apTtFzSkCvpMjUsuuUSStHPnTklScnKyHnvsMbVv316RkZGKjo5W7969tXr16kJfm5mZqWHDhqlFixYKDQ1VnTp1dO2112r79u2STp5PPP/pNAr+L/8fWH777Tc5HA599913euaZZxQfH6+IiAhdddVV2rt3b6H7/vPPP9WrVy/FxMQoPDxc3bt316JFi4r8Hnv06FHk/Q8bNqzQdcePH69OnTopLCxM1atX180331zk/Z/qe8vP5XLp3XffVdu2bRUaGqratWvr/vvv19GjR72u16hRI/Xr16/Q/TzwwAOFbrOo2d94441Cj6l08rQjQ4cOVbNmzRQSEqL69evriSeeUFZWVpGPVX49evQodHsvv/yynE6nvv766zI9Hm+++aa6dOmiGjVqKCwsTJ06ddIPP/xQ5P2PHz9e5513nsLDw1WtWjVddNFF+uWXX7yu8/PPP6t79+6KiopSdHS0zj333EKzTZw40fMzjYuL02233ab9+/d7XWfgwIFeM1erVk09evQo8aljTmX58uXq2bOn4uLiFBYWpsaNG+vuu+8u8+OSX0lfr+7X17fffqvnnntO9erVU3h4uFatWiWHw6F33nmn0G0vXrxYDodD33zzTYm/V5fLpZEjR6p9+/YKDQ1VzZo11atXLy1fvtxznbFjx+qSSy5RrVq1FBISojZt2uiDDz7wup1GjRpp/fr1+v3334t8vzh27Jgefvhh1a9fXyEhIWrWrJlee+01uVwur9tJSkrS7bffrujoaMXGxurOO+/U6tWr5XA4Ch2m++uvv6pbt26KiIhQbGysrr76am3cuNHrOsOGDZPD4dCGDRs0YMAAVatWTRdeeKHGjh0rh8OhlStXFnpMXnnlFQUEBBR6zpVGwfewuLg49e3bV+vWrSvR15/uNZCWlqZ169apfv366tu3r6KjoxUREVHoNbBjx44SP1+Kev9wv0/kf+zXrFmjgQMHqkmTJgoNDVV8fLzuvvtuJSUleX2t+zD1Xbt2eS6bPXu2unTpovDwcMXExKhfv36FHhP3zywxMdFz2fLly4t8DrRr167IP/z//PPPnudGVFSU+vbtW+ic2gMHDvQcFt20aVOdf/75Sk5OVlhYWKG5i/Lpp59Kks4991yv96DatWtL+qfR9evXV5MmTYp9zbtf67/99psyMzP14IMP6ujRo3r99dcVEhKigIAARUVFqV+/fpo9e/YpGx0QEKBLL71US5cu9Wp0v3795HA4FBYWpoYNGyo2NlbR0dG64447PG1zN9rpdCowMNCr0YMGDVJoaKjnKJbiGt28efNCjzON/geNptE02vqNLs3ruKSvlcjIyEL388MPP3jaUNTMp3pvcDgceuCBBzRhwgS1bNlSoaGh6tSpk/74449C97Ny5Ur17t1b0dHRioyM9DSkJI+b+3/5f/Y9evRQu3btTvUQes1YUL9+/QqdsiQtLU2PPvqo5/nZsmVLvfnmm4U+i+Lcc8/VsGHDFBISok6dOumGG26QdPJUnT169Djt6zv/9+R0OhUVFaWYmBiv35knTJggh8Ph2RuzuP+FhoZ65vr+++9lGIaGDh2qatWqeW6/WbNm2rp1a6HH4PHHH1dkZKTnturVq6dZs2YV+lm0a9dOnTp1OuXvzPm3MfL3OCAgQNWrV9emTZs8t+nuW8OGDelxPvS4ePSYHpvV48pq4v79+3X33Xerdu3aCgkJUdu2bfX55597Xcf9nCvqeRwZGel1BE5Rvw+7XC516NCh0M/KvT2wY8cO9ezZUxEREapbt65GjBhRqHcl7WLB3xPr1aunQYMGeX0uhSQdOXJE99xzj2rXrq3Q0FCdeeaZGjdunNd1ivpepMLvp6V5fKSTf6+44YYbVL16dYWHh+uCCy7QjBkzvK6Tv2WxsbHq3LmzzjjjDPXt27fIbhTk/nr3/0JCQtSiRQu9+uqrXo9ZUX+HKKjg5/8sXbpUnTp10uDBgz3Pm3bt2umTTz4p9LWl+bmV5Dnrnje/+fPnKyQkRP/617+8Li/Jc7skynSkRkHuBYgaNWpIOvkkmDx5sm644QY1btxYhw8f1kcffaTu3btrw4YNqlu3riQpLy9P/fr107x583TzzTfroYceUmpqqubMmaN169apadOmnvu45ZZb1KdPH6/7ffrpp4uc5+WXX5bD4dCTTz6pI0eO6N1339Vll12mVatWec5v9uuvv6p3797q1KmThg4dKqfT6XnTX7Bggc4777xCt3vGGWfo1VdflSSdOHFC//73v4u87+eff1433nij7r33XiUkJGj06NG66KKLtHLlSsXGxhb6mkGDBqlbt26SpB9//FE//fST17/ff//9+uK
"text/plain": [
"<Figure size 1500x500 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Приращение данных (undersampling)\n",
"df_train_undersampled: DataFrame = undersample(df_train, 'salary_category')\n",
2024-10-18 01:43:18 +04:00
"df_val_undersampled: DataFrame = undersample(df_val, 'salary_category')\n",
2024-10-18 01:38:52 +04:00
"df_test_undersampled: DataFrame = undersample(df_test, 'salary_category')\n",
"\n",
"# Проверка сбалансированности выборок\n",
"print('Проверка сбалансированности выборок после применения метода undersampling:')\n",
2024-10-18 01:38:52 +04:00
"check_balance(df_train_undersampled, 'Обучающая выборка', 'salary_category')\n",
"check_balance(df_val_undersampled, 'Контрольная выборка', 'salary_category')\n",
"check_balance(df_test_undersampled, 'Тестовая выборка', 'salary_category')\n",
"\n",
"# Проверка необходимости аугментации выборок\n",
"print('Проверка необходимости аугментации выборок после применения метода undersampling:')\n",
2024-10-18 01:38:52 +04:00
"print(f\"Для обучающей выборки аугментация данных {'не ' if not need_augmentation(df_train_undersampled, 'salary_category', 'low', 'medium') else ''}требуется\")\n",
"print(f\"Для контрольной выборки аугментация данных {'не ' if not need_augmentation(df_val_undersampled, 'salary_category', 'low', 'medium') else ''}требуется\")\n",
"print(f\"Для тестовой выборки аугментация данных {'не ' if not need_augmentation(df_test_undersampled, 'salary_category', 'low', 'medium') else ''}требуется\")\n",
" \n",
"# Визуализация сбалансированности классов\n",
"visualize_balance(df_train_undersampled, df_val_undersampled, df_test_undersampled, 'salary_category')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Датасет №3: [Экономика стран](https://www.kaggle.com/datasets/pratik453609/economic-data-9-countries-19802020).\n",
"\n",
"### Описание датасета:\n",
"Данный набор данных содержит информацию о ключевых макроэкономических показателях для восьми стран (Китай, Франция, Германия, Индия, Япония, Испания, Великобритания, США) и одного специального административного района (Гонконг) за период с 1980 по 2020 год. В наборе представлены данные о таких макроэкономических переменных, как инфляция, уровень безработицы, ВВП, обменные курсы (по отношению к доллару США), доход на душу населения и цены на основные фондовые индексы каждой страны. Этот датасет полезен для анализа взаимосвязей между экономическими показателями и динамикой фондовых индексов стран, что может быть использовано для экономического моделирования и прогноза.\n",
"\n",
"---\n",
"\n",
"### Анализ сведений:\n",
"**Проблемная область:**\n",
"Основная задача исследование взаимосвязей между макроэкономическими переменными и ценами на фондовые индексы, а также анализ влияния таких факторов, как инфляция, ВВП и обменные курсы на фондовые рынки и экономическую стабильность стран.\n",
"\n",
"**Актуальность:**\n",
"Этот датасет актуален для исследователей, аналитиков и экономистов, занимающихся изучением макроэкономических трендов, финансовых рынков и их взаимосвязей. Он предоставляет данные, необходимые для анализа экономических кризисов, изменений на фондовых рынках и долгосрочных макроэкономических прогнозов.\n",
"\n",
"**Объекты наблюдения:**\n",
"Страны (или регионы), данные по которым включены в датасет: Китай, Франция, Германия, Гонконг, Индия, Япония, Испания, Великобритания и США. Для каждого из них собирались данные за период с 1980 по 2020 год.\n",
"\n",
"**Атрибуты объектов:**\n",
"- stock index: Название основного фондового индекса страны.\n",
"- country: Название страны.\n",
"- year: Год, к которому относятся данные.\n",
"- index price: Средняя цена фондового индекса за год.\n",
"- log_indexprice: Логарифмическое значение цены индекса для учета валютных различий.\n",
"- inflationrate: Уровень инфляции в стране.\n",
"- oil prices: Цены на нефть в долларах США.\n",
"- exchange_rate: Обменный курс валюты страны по отношению к доллару США.\n",
"- gdppercent: Рост ВВП (в процентах).\n",
"- percapitaincome: Доход на душу населения.\n",
"- unemploymentrate: Уровень безработицы (в процентах).\n",
"- manufacturingoutput: Объем производства в промышленном секторе страны.\n",
"- tradebalance: Торговый баланс.\n",
"- USTreasury: Облигации.\n",
"\n",
"**Связь между объектами:**\n",
"Данные позволяют исследовать взаимосвязи между макроэкономическими факторами и ценами на фондовые индексы, а также между другими экономическими показателями. Например, можно анализировать, как инфляция и обменный курс влияют на фондовый рынок каждой страны или как колебания цен на нефть отражаются на экономике разных стран.\n",
"\n",
"---\n",
"\n",
"### Качество набора данных:\n",
"**Информативность:**\n",
"Датасет включает широкий спектр макроэкономических показателей и цены фондовых индексов за 40-летний период, что делает его очень полезным для анализа долгосрочных экономических трендов и финансовых рынков.\n",
"\n",
"**Степень покрытия:**\n",
"Набор данных охватывает данные по ведущим экономикам мира, представляя достаточно полную картину макроэкономической динамики в разных странах и регионах за большой временной период (19802020 гг.).\n",
"\n",
"**Соответствие реальным данным:**\n",
"Все представленные макроэкономические показатели и цены фондовых индексов являются официальными экономическими данными, которые используются для анализа и прогнозирования в реальных условиях.\n",
"\n",
"**Согласованность меток:**\n",
"Названия признаков определены недостаточно чётко. Обычно названия признаков записываются в стиле \"snake_case\" слова пишутся строчными буквами и разделяются знаком нижнего подчеркивания. В данном же случае некоторые названия переменных записаны в стиле \"snake_case\", у некоторых слова разделяются пробелом, у некоторых вовсе не разделяются и пишутся слитно. Также в описании датасета отсутствовала расшифровка нескольких столбцов датасета их предназначение пришлось домысливать самому, основываясь лишь на собственной логике. Сами данные представляют собой легко интерпретируемые экономические показатели, что упрощает их анализ и использование в эконометрических моделях.\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",
"Признак \"index_price\" средняя цена фондового индекса страны.\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Выгрузка данных из файла в DataFrame:"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"df: DataFrame = pd.read_csv('..//static//csv//economic_data.csv')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Краткая информация о DataFrame:"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"RangeIndex: 369 entries, 0 to 368\n",
"Data columns (total 14 columns):\n",
" # Column Non-Null Count Dtype \n",
"--- ------ -------------- ----- \n",
" 0 stock index 369 non-null object \n",
" 1 country 369 non-null object \n",
" 2 year 369 non-null float64\n",
" 3 index price 317 non-null float64\n",
" 4 log_indexprice 369 non-null float64\n",
" 5 inflationrate 326 non-null float64\n",
" 6 oil prices 369 non-null float64\n",
" 7 exchange_rate 367 non-null float64\n",
" 8 gdppercent 350 non-null float64\n",
" 9 percapitaincome 368 non-null float64\n",
" 10 unemploymentrate 348 non-null float64\n",
" 11 manufacturingoutput 278 non-null float64\n",
" 12 tradebalance 365 non-null float64\n",
" 13 USTreasury 369 non-null float64\n",
"dtypes: float64(12), object(2)\n",
"memory usage: 40.5+ KB\n"
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>count</th>\n",
" <th>mean</th>\n",
" <th>std</th>\n",
" <th>min</th>\n",
" <th>25%</th>\n",
" <th>50%</th>\n",
" <th>75%</th>\n",
" <th>max</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>year</th>\n",
" <td>369.0</td>\n",
" <td>2000.000000</td>\n",
" <td>11.848225</td>\n",
" <td>1980.00</td>\n",
" <td>1990.00</td>\n",
" <td>2000.00</td>\n",
" <td>2010.0000</td>\n",
" <td>2020.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>index price</th>\n",
" <td>317.0</td>\n",
" <td>7898.648297</td>\n",
" <td>7811.336862</td>\n",
" <td>168.61</td>\n",
" <td>2407.10</td>\n",
" <td>5160.10</td>\n",
" <td>10279.5000</td>\n",
" <td>47751.33</td>\n",
" </tr>\n",
" <tr>\n",
" <th>log_indexprice</th>\n",
" <td>369.0</td>\n",
" <td>3.610542</td>\n",
" <td>0.482481</td>\n",
" <td>2.23</td>\n",
" <td>3.32</td>\n",
" <td>3.60</td>\n",
" <td>3.9800</td>\n",
" <td>4.68</td>\n",
" </tr>\n",
" <tr>\n",
" <th>inflationrate</th>\n",
" <td>326.0</td>\n",
" <td>0.041748</td>\n",
" <td>0.039579</td>\n",
" <td>-0.04</td>\n",
" <td>0.02</td>\n",
" <td>0.03</td>\n",
" <td>0.0575</td>\n",
" <td>0.24</td>\n",
" </tr>\n",
" <tr>\n",
" <th>oil prices</th>\n",
" <td>369.0</td>\n",
" <td>39.743171</td>\n",
" <td>25.452654</td>\n",
" <td>11.35</td>\n",
" <td>19.41</td>\n",
" <td>28.52</td>\n",
" <td>57.8800</td>\n",
" <td>98.56</td>\n",
" </tr>\n",
" <tr>\n",
" <th>exchange_rate</th>\n",
" <td>367.0</td>\n",
" <td>27.897548</td>\n",
" <td>49.620521</td>\n",
" <td>0.90</td>\n",
" <td>1.33</td>\n",
" <td>5.44</td>\n",
" <td>15.0550</td>\n",
" <td>249.05</td>\n",
" </tr>\n",
" <tr>\n",
" <th>gdppercent</th>\n",
" <td>350.0</td>\n",
" <td>0.037114</td>\n",
" <td>0.037850</td>\n",
" <td>-0.11</td>\n",
" <td>0.02</td>\n",
" <td>0.03</td>\n",
" <td>0.0600</td>\n",
" <td>0.15</td>\n",
" </tr>\n",
" <tr>\n",
" <th>percapitaincome</th>\n",
" <td>368.0</td>\n",
" <td>20719.964674</td>\n",
" <td>17435.037783</td>\n",
" <td>27.00</td>\n",
" <td>2090.25</td>\n",
" <td>19969.50</td>\n",
" <td>36384.0000</td>\n",
" <td>65280.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>unemploymentrate</th>\n",
" <td>348.0</td>\n",
" <td>0.068908</td>\n",
" <td>0.043207</td>\n",
" <td>0.02</td>\n",
" <td>0.04</td>\n",
" <td>0.06</td>\n",
" <td>0.0900</td>\n",
" <td>0.26</td>\n",
" </tr>\n",
" <tr>\n",
" <th>manufacturingoutput</th>\n",
" <td>278.0</td>\n",
" <td>328.084820</td>\n",
" <td>622.395923</td>\n",
" <td>0.59</td>\n",
" <td>80.38</td>\n",
" <td>188.16</td>\n",
" <td>271.9775</td>\n",
" <td>3868.46</td>\n",
" </tr>\n",
" <tr>\n",
" <th>tradebalance</th>\n",
" <td>365.0</td>\n",
" <td>-15.996384</td>\n",
" <td>154.557170</td>\n",
" <td>-770.93</td>\n",
" <td>-25.37</td>\n",
" <td>-0.14</td>\n",
" <td>19.0800</td>\n",
" <td>366.14</td>\n",
" </tr>\n",
" <tr>\n",
" <th>USTreasury</th>\n",
" <td>369.0</td>\n",
" <td>0.059024</td>\n",
" <td>0.033086</td>\n",
" <td>0.01</td>\n",
" <td>0.03</td>\n",
" <td>0.05</td>\n",
" <td>0.0800</td>\n",
" <td>0.14</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" count mean std min 25% \\\n",
"year 369.0 2000.000000 11.848225 1980.00 1990.00 \n",
"index price 317.0 7898.648297 7811.336862 168.61 2407.10 \n",
"log_indexprice 369.0 3.610542 0.482481 2.23 3.32 \n",
"inflationrate 326.0 0.041748 0.039579 -0.04 0.02 \n",
"oil prices 369.0 39.743171 25.452654 11.35 19.41 \n",
"exchange_rate 367.0 27.897548 49.620521 0.90 1.33 \n",
"gdppercent 350.0 0.037114 0.037850 -0.11 0.02 \n",
"percapitaincome 368.0 20719.964674 17435.037783 27.00 2090.25 \n",
"unemploymentrate 348.0 0.068908 0.043207 0.02 0.04 \n",
"manufacturingoutput 278.0 328.084820 622.395923 0.59 80.38 \n",
"tradebalance 365.0 -15.996384 154.557170 -770.93 -25.37 \n",
"USTreasury 369.0 0.059024 0.033086 0.01 0.03 \n",
"\n",
" 50% 75% max \n",
"year 2000.00 2010.0000 2020.00 \n",
"index price 5160.10 10279.5000 47751.33 \n",
"log_indexprice 3.60 3.9800 4.68 \n",
"inflationrate 0.03 0.0575 0.24 \n",
"oil prices 28.52 57.8800 98.56 \n",
"exchange_rate 5.44 15.0550 249.05 \n",
"gdppercent 0.03 0.0600 0.15 \n",
"percapitaincome 19969.50 36384.0000 65280.00 \n",
"unemploymentrate 0.06 0.0900 0.26 \n",
"manufacturingoutput 188.16 271.9775 3868.46 \n",
"tradebalance -0.14 19.0800 366.14 \n",
"USTreasury 0.05 0.0800 0.14 "
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Краткая информация о DataFrame\n",
"df.info()\n",
"\n",
"# Статистическое описание числовых столбцов\n",
"df.describe().transpose()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Проблема пропущенных данных:\n",
"\n",
"Проверка на отсутствие значений, представленная ниже, показала, что некоторые колонки DataFrame содержат пустые значения признаков.\n",
"\n",
"Решения проблемы отсутствия значений:\n",
"1. Удаление примеров с пустыми значениями (допустимо для набора данных с большим количеством наблюдений).\n",
"2. Использовать метод машинного обучения, который способен обработать пустые значения (например, деревья решений).\n",
"3. Использовать методы подстановки данных:\n",
" - Заполнить средним значением признака (среднее по колонке).\n",
" - Подставить магическое число (число за диапазоном доступных значений).\n",
" - Обучить модель для предсказания пропущенного значения на основе других значений наблюдения.\n",
"\n",
"Воспользуемся методом подстановки среднего значения признака."
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"До заполнения пустых значений:\n",
"Присутствуют ли пустые значения признаков в колонке:\n",
"stock index False\n",
"country False\n",
"year False\n",
"index price True\n",
"log_indexprice False\n",
"inflationrate True\n",
"oil prices False\n",
"exchange_rate True\n",
"gdppercent True\n",
"percapitaincome True\n",
"unemploymentrate True\n",
"manufacturingoutput True\n",
"tradebalance True\n",
"USTreasury False\n",
"dtype: bool \n",
"\n",
"Количество пустых значений признаков в колонке:\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",
"Процент пустых значений признаков в колонке:\n",
"index price процент пустых значений: 14.09%\n",
"inflationrate процент пустых значений: 11.65%\n",
"exchange_rate процент пустых значений: 0.54%\n",
"gdppercent процент пустых значений: 5.15%\n",
"percapitaincome процент пустых значений: 0.27%\n",
"unemploymentrate процент пустых значений: 5.69%\n",
"manufacturingoutput процент пустых значений: 24.66%\n",
"tradebalance процент пустых значений: 1.08%\n",
"\n",
"После заполнения пустых значений:\n",
"Присутствуют ли пустые значения признаков в колонке:\n",
"stock index False\n",
"country False\n",
"year False\n",
"index price False\n",
"log_indexprice False\n",
"inflationrate False\n",
"oil prices False\n",
"exchange_rate False\n",
"gdppercent False\n",
"percapitaincome False\n",
"unemploymentrate False\n",
"manufacturingoutput False\n",
"tradebalance False\n",
"USTreasury False\n",
"dtype: bool \n",
"\n",
"Количество пустых значений признаков в колонке:\n",
"stock index 0\n",
"country 0\n",
"year 0\n",
"index price 0\n",
"log_indexprice 0\n",
"inflationrate 0\n",
"oil prices 0\n",
"exchange_rate 0\n",
"gdppercent 0\n",
"percapitaincome 0\n",
"unemploymentrate 0\n",
"manufacturingoutput 0\n",
"tradebalance 0\n",
"USTreasury 0\n",
"dtype: int64 \n",
"\n",
"Процент пустых значений признаков в колонке:\n",
"\n"
]
}
],
"source": [
"# Заполнить пропущенные данные средним значением\n",
"def fill_null_columns(dataframe: DataFrame) -> DataFrame:\n",
" for column in dataframe.columns:\n",
" null_rate: float = dataframe[column].isnull().sum() / len(dataframe) * 100\n",
" if null_rate > 0:\n",
" # Замена пустых данных на медиану\n",
" df[column] = df[column].fillna(df[column].median())\n",
" \n",
" return dataframe\n",
"\n",
"\n",
"# Проверка пропущенных данных\n",
"print('До заполнения пустых значений:')\n",
"check_null_columns(df)\n",
"\n",
"# Заполнение пропущенных значений\n",
"df: DataFrame = fill_null_columns(df)\n",
"\n",
"# Проверка пропущенных данных\n",
"print('После заполнения пустых значений:')\n",
"check_null_columns(df)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Проблема зашумленности данных:\n",
"\n",
"Представленный ниже код помогает определить наличие выбросов в наборе данных и устранить их (при наличии), заменив значения ниже нижней границы (рассматриваемого минимума) на значения нижней границы, а значения выше верхней границы (рассматриваемого максимума) на значения верхней границы."
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Проверка наличия выбросов в колонках:\n",
"Колонка year:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 1980.0\n",
"\tМаксимальное значение: 2020.0\n",
"\t1-й квартиль (Q1): 1990.0\n",
"\t3-й квартиль (Q3): 2010.0\n",
"\n",
"Колонка index price:\n",
"\tЕсть выбросы: Да\n",
"\tКоличество выбросов: 33\n",
"\tМинимальное значение: 168.61\n",
"\tМаксимальное значение: 47751.33\n",
"\t1-й квартиль (Q1): 2846.5\n",
"\t3-й квартиль (Q3): 9484.47\n",
"\n",
"Колонка log_indexprice:\n",
"\tЕсть выбросы: Да\n",
"\tКоличество выбросов: 3\n",
"\tМинимальное значение: 2.23\n",
"\tМаксимальное значение: 4.68\n",
"\t1-й квартиль (Q1): 3.32\n",
"\t3-й квартиль (Q3): 3.98\n",
"\n",
"Колонка inflationrate:\n",
"\tЕсть выбросы: Да\n",
"\tКоличество выбросов: 38\n",
"\tМинимальное значение: -0.04\n",
"\tМаксимальное значение: 0.24\n",
"\t1-й квартиль (Q1): 0.02\n",
"\t3-й квартиль (Q3): 0.05\n",
"\n",
"Колонка oil prices:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 11.35\n",
"\tМаксимальное значение: 98.56\n",
"\t1-й квартиль (Q1): 19.41\n",
"\t3-й квартиль (Q3): 57.88\n",
"\n",
"Колонка exchange_rate:\n",
"\tЕсть выбросы: Да\n",
"\tКоличество выбросов: 85\n",
"\tМинимальное значение: 0.9\n",
"\tМаксимальное значение: 249.05\n",
"\t1-й квартиль (Q1): 1.33\n",
"\t3-й квартиль (Q3): 13.9\n",
"\n",
"Колонка gdppercent:\n",
"\tЕсть выбросы: Да\n",
"\tКоличество выбросов: 41\n",
"\tМинимальное значение: -0.11\n",
"\tМаксимальное значение: 0.15\n",
"\t1-й квартиль (Q1): 0.02\n",
"\t3-й квартиль (Q3): 0.05\n",
"\n",
"Колонка percapitaincome:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 27.0\n",
"\tМаксимальное значение: 65280.0\n",
"\t1-й квартиль (Q1): 2099.0\n",
"\t3-й квартиль (Q3): 36354.0\n",
"\n",
"Колонка unemploymentrate:\n",
"\tЕсть выбросы: Да\n",
"\tКоличество выбросов: 23\n",
"\tМинимальное значение: 0.02\n",
"\tМаксимальное значение: 0.26\n",
"\t1-й квартиль (Q1): 0.04\n",
"\t3-й квартиль (Q3): 0.08\n",
"\n",
"Колонка manufacturingoutput:\n",
"\tЕсть выбросы: Да\n",
"\tКоличество выбросов: 35\n",
"\tМинимальное значение: 0.59\n",
"\tМаксимальное значение: 3868.46\n",
"\t1-й квартиль (Q1): 101.07\n",
"\t3-й квартиль (Q3): 245.75\n",
"\n",
"Колонка tradebalance:\n",
"\tЕсть выбросы: Да\n",
"\tКоличество выбросов: 77\n",
"\tМинимальное значение: -770.93\n",
"\tМаксимальное значение: 366.14\n",
"\t1-й квартиль (Q1): -24.12\n",
"\t3-й квартиль (Q3): 18.15\n",
"\n",
"Колонка USTreasury:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 0.01\n",
"\tМаксимальное значение: 0.14\n",
"\t1-й квартиль (Q1): 0.03\n",
"\t3-й квартиль (Q3): 0.08\n",
"\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABcsAAAPdCAYAAABVyzBqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdeVwU9f8H8Be7yHKjIGdyeYK3oiYaikqiYYpHlid4p3hSnl/zKiVNRS1FzRLzKM+s0DzyRMVSEm/JFNRSLg9QbtjP7w9/OzEuIngtx+v5ePDQ/cx7Zt4zzPKe/ezMZ/SEEAJERERERERERERERBWYQtcJEBERERERERERERHpGjvLiYiIiIiIiIiIiKjCY2c5EREREREREREREVV47CwnIiIiIiIiIiIiogqPneVEREREREREREREVOGxs5yIiIiIiIiIiIiIKjx2lhMRERERERERERFRhcfOciIiIiIiIiIiIiKq8NhZTkREREREREREREQVHjvLiYiIiIiowtHT08OsWbNK/TJfFxcXFwQGBuo6DSIiqgBKQ70MDw+Hnp4e4uPjS/UyX4VZs2ZBT09P12mUWuwsJ8m2bdugp6dX6E/9+vV1nR5RheHt7S19WA0MDIS3t7dO8ykOFxcX6WSnYP5EFRHrKVHpUBbraXnGcwV6HViDiUoH1uCKbdasWXBxcQHw3xcIZYm+rhOg0mfatGlwd3eXXs+dO1eH2RAREZVNrKdEpVtmZib09flxSCM2NhYKBa+lovKBNZiInmXAgAH44IMPoFKpdJ3Kazd9+nRMmTJF12mUWjw7JC1vv/227Fu/NWvWICUlRXcJEVGpJIRAVlYWjIyMdJ0KUanEekpUuhkaGuo6BZ0rWMsrYmcBlV+swUT0LEqlEkqlUtdpvFbp6ekwMTGBvr4+LxgoAi8dIElOTg4AFOuKksLGYVKr1WjYsCH09PQQHh4utZ87dw6BgYGoXr06DA0NYWdnh8GDB+Pu3buyZWrGTHryp+Ab2NvbG/Xr10d0dDRatWoFIyMjuLq6YuXKlVrbMmPGDHh4eMDCwgImJibw8vLCoUOHZHHx8fHSenbu3CmblpWVhSpVqkBPTw8LFy7UytPGxga5ubmyeb7//ntpeQVPxn766Sf4+fnBwcEBKpUKNWrUwKeffor8/Pxn7mvN+q5cuYLevXvD3NwcVlZWGDduHLKysmSxa9euRfv27WFjYwOVSoW6desiLCxMa5ndunWDi4sLDA0NYWNjg65du+L8+fOyGM12LFmyRGt+Nzc36OnpYfTo0VLbvXv38PHHH6NBgwYwNTWFubk5OnfujLNnz8rmDQgIgKGhIS5fvixr9/X1RZUqVXD79m2p7fr163jvvfdgaWkJY2NjtGzZErt27ZLNd/jwYdnxolKpULt2bYSEhEAIUfTO/X9PO/YKu1Ws4DHz5E9BSUlJGDJkCJycnKBUKqUYU1PTYuVUGCEEXFxc0K1bN61pWVlZsLCwwIgRI6S27OxszJw5EzVr1oRKpYKjoyMmTZqE7Oxs2bzFPW5cXFzQpUsX7N27F82aNYORkRFWrVr13NtDVF6xnu6UTWM9ZT0tbfVU48nxUjX5//333wgMDETlypVhYWGBQYMGISMjQzZvdnY2JkyYAGtra5iZmaFr1674559/Cl3Pv//+i8GDB8PW1hYqlQr16tXDt99+K03PzMyEm5sb3NzckJmZKbXfu3cP9vb2aNWqVZHHuObvyNGjRzFixAhYWVnB3NwcAwcOxP3792WxRdXywsYsf/DgASZMmAAXFxeoVCpUq1YNAwcOlL0vi3u+QfQ6sAbvlE1jDWYNLq01uDBnzpxB586dYW5uDlNTU3To0AEnT57Uijt37hzatm0LIyMjVKtWDZ999hnWrl1b4rHCC/sboKmTx44dQ4sWLWBoaIjq1avju+++05r/4sWLaN++vSwPtVpd6Lp+/fVXeHl5wcTEBGZmZvDz88PFixel6QcPHoRCocCMGTNk823atAl6enqy94DmuN24cSPq1KkDQ0NDeHh44OjRo7J5NcfEpUuX0LdvX1SpUgVvvfWWbNqTNmzYgBYtWsDY2BhVqlRBmzZtsG/fvhJtS3nArxFIojmxeN6rStavX69VnABg//79uH79OgYNGgQ7OztcvHgRq1evxsWLF3Hy5EmtN2hYWJjsj++TJzr379/HO++8g969e6NPnz7YsmULRo4cCQMDAwwePBgAkJaWhjVr1qBPnz4YNmwYHj58iG+++Qa+vr74448/0LhxY9kyDQ0NsXbtWvj7+0ttO3bs0CrcBT18+BARERHo3r271LZ27VoYGhpqzRceHg5TU1MEBwfD1NQUBw8exIwZM5CWloYvvvjiqesoqHfv3nBxcUFISAhOnjyJZcuW4f79+7I/2mFhYahXrx66du0KfX19/PLLLxg1ahTUajWCgoJkyxs+fDjs7Oxw+/ZtfPXVV/Dx8UFcXByMjY219sv48eOlthMnTuDGjRta+V2/fh07d+7Ee++9B1dXVyQmJmLVqlVo27YtLl26BAcHBwDA0qVLcfDgQQQEBCAqKgpKpRKrVq3Cvn37sH79eikuMTERrVq1QkZGBsaOHQsrKyusW7cOXbt2xbZt22T7HfjvVsvMzExs3rwZ06ZNg42NDYYMGVKs/avZf5pjb+rUqUXGDh8+HF5eXgAeHys//vijbHpAQAB+++03jBkzBo0aNYJSqcTq1avx559/FjufJ+np6aF///5YsGAB7t27B0tLS2naL7/8grS0NPTv3x/A4xP9rl274tixYxg+fDjc3d1x/vx5hIaG4q+//pKdSJfkuImNjUWfPn0wYsQIDBs2DHXq1Hnu7SEqr1hPWU9ZT0t3PX2W3r17w9XVFSEhIfjzzz+xZs0a2NjYYP78+VLM0KFDsWHDBvTt2xetWrXCwYMH4efnp7WsxMREtGzZUvpga21tjV9//RVDhgxBWloaxo8fDyMjI6xbtw6tW7fG//73PyxevBgAEBQUhNTUVISHhxfryrfRo0ejcuXKmDVrFmJjYxEWFoYbN25InTAaxa3ljx49gpeXFy5fvozBgwejadOmSElJwc8//4x//vkHVatWLdH5BtHrwBrMGswaXDZr8MWLF+Hl5QVzc3NMmjQJlSpVwqpVq+Dt7Y0jR47gzTffBPD4C+h27dpBT08PU6dOhYmJCdasWfNS7476+++/0atXLwwZMgQBAQH49ttvERgYCA8PD9SrVw8AkJCQgHbt2iEvLw9TpkyBiYkJVq9eXehd1+vXr0dAQAB8fX0xf/58ZGRkICwsDG+99RbOnDkDFxcXtG/fHqNGjUJISAj8/f3RtGlT3LlzB2PGjIGPjw8+/PBD2TKPHDmCzZs3Y+zYsVCpVFixYgU6deqEP/74Q+v5DO+99x5q1aqFefPmFfnly+zZszFr1iy0atUKc+bMgYGBAX7//XccPHgQHTt2LPa2lAuC6P8tWbJEABBnz56Vtbdt21bUq1dP1rZ27VoBQMTFxQkhhMjKyhJOTk6ic+fOAoBYu3atFJuRkaG1ru+//14AEEePHpXaZs6cKQCI5OTkp+bYtm1bAUAsWrRIasvOzhaNGzcWNjY2IicnRwghRF5ensjOzpbNe//+fWFraysGDx4stcXFxQkAok+fPkJfX18kJCRI0zp06CD69u0rAIgvvvhCK88+ffqILl26SO03btwQCoVC9OnTR2s7CtsHI0aMEMbGxiIrK+up21twfV27dpW1jxo1Suv3Vdh6fH19RfXq1Ytcx5YtWwQAcfr0aakNgOjVq5fQ19eXtQ8ZMkTaL0FBQVJ7VlaWyM/Ply03Li5OqFQqMWfOHFn73r17BQDx2WefievXrwtTU1Ph7+8vixk/frwAICIjI6W2hw8fCldXV+Hi4iKt69ChQwKAOHTokCwXhUIhRo0aVeR2a0ybNk0AECkpKVJbvXr1RNu2bbVir169KgCIdevWSW2a35FGZmamUCgUYsSIEbJ5AwIChImJSbFyeprY2FgBQISFhcnau3btKlxcXIRarRZCCLF+/XqhUChk+08IIVauXCkAiOP
"text/plain": [
"<Figure size 1500x1000 with 12 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Числовые столбцы DataFrame\n",
"numeric_columns: list[str] = [\n",
" 'year',\n",
" 'index price',\n",
" 'log_indexprice',\n",
" 'inflationrate',\n",
" 'oil prices',\n",
" 'exchange_rate',\n",
" 'gdppercent',\n",
" 'percapitaincome',\n",
" 'unemploymentrate',\n",
" 'manufacturingoutput',\n",
" 'tradebalance',\n",
" 'USTreasury'\n",
"]\n",
"\n",
"# Проверка наличия выбросов в колонках\n",
"print('Проверка наличия выбросов в колонках:')\n",
"check_outliers(df, numeric_columns)\n",
"visualize_outliers(df, numeric_columns)"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Проверка наличия выбросов в колонках после их устранения:\n",
"Колонка year:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 1980.0\n",
"\tМаксимальное значение: 2020.0\n",
"\t1-й квартиль (Q1): 1990.0\n",
"\t3-й квартиль (Q3): 2010.0\n",
"\n",
"Колонка index price:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 168.61\n",
"\tМаксимальное значение: 19441.424999999996\n",
"\t1-й квартиль (Q1): 2846.5\n",
"\t3-й квартиль (Q3): 9484.47\n",
"\n",
"Колонка log_indexprice:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 2.3299999999999996\n",
"\tМаксимальное значение: 4.68\n",
"\t1-й квартиль (Q1): 3.32\n",
"\t3-й квартиль (Q3): 3.98\n",
"\n",
"Колонка inflationrate:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: -0.025000000000000005\n",
"\tМаксимальное значение: 0.095\n",
"\t1-й квартиль (Q1): 0.02\n",
"\t3-й квартиль (Q3): 0.05\n",
"\n",
"Колонка oil prices:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 11.35\n",
"\tМаксимальное значение: 98.56\n",
"\t1-й квартиль (Q1): 19.41\n",
"\t3-й квартиль (Q3): 57.88\n",
"\n",
"Колонка exchange_rate:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 0.9\n",
"\tМаксимальное значение: 32.755\n",
"\t1-й квартиль (Q1): 1.33\n",
"\t3-й квартиль (Q3): 13.9\n",
"\n",
"Колонка gdppercent:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: -0.025000000000000005\n",
"\tМаксимальное значение: 0.095\n",
"\t1-й квартиль (Q1): 0.02\n",
"\t3-й квартиль (Q3): 0.05\n",
"\n",
"Колонка percapitaincome:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 27.0\n",
"\tМаксимальное значение: 65280.0\n",
"\t1-й квартиль (Q1): 2099.0\n",
"\t3-й квартиль (Q3): 36354.0\n",
"\n",
"Колонка unemploymentrate:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 0.02\n",
"\tМаксимальное значение: 0.14\n",
"\t1-й квартиль (Q1): 0.04\n",
"\t3-й квартиль (Q3): 0.08\n",
"\n",
"Колонка manufacturingoutput:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 0.59\n",
"\tМаксимальное значение: 462.77\n",
"\t1-й квартиль (Q1): 101.07\n",
"\t3-й квартиль (Q3): 245.75\n",
"\n",
"Колонка tradebalance:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: -87.52499999999999\n",
"\tМаксимальное значение: 81.55499999999999\n",
"\t1-й квартиль (Q1): -24.12\n",
"\t3-й квартиль (Q3): 18.15\n",
"\n",
"Колонка USTreasury:\n",
"\tЕсть выбросы: Нет\n",
"\tКоличество выбросов: 0\n",
"\tМинимальное значение: 0.01\n",
"\tМаксимальное значение: 0.14\n",
"\t1-й квартиль (Q1): 0.03\n",
"\t3-й квартиль (Q3): 0.08\n",
"\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1500x1000 with 12 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Устраняем выборсы\n",
"df: DataFrame = remove_outliers(df, numeric_columns)\n",
"\n",
"# Проверка наличия выбросов в колонках\n",
"print('Проверка наличия выбросов в колонках после их устранения:')\n",
"check_outliers(df, numeric_columns)\n",
"visualize_outliers(df, numeric_columns)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Разбиение набора данных на выборки:\n",
"\n",
"Разделим выборку данных на 3 группы и проанализируем качество распределения данных.\n",
"\n",
"Стратифицированное разбиение требует, чтобы в каждом классе, по которому происходит стратификация, было минимум по два элемента, иначе метод не сможет корректно разделить данные на тренировочные, валидационные и тестовые наборы.\n",
"\n",
"Чтобы решить эту проблему введём категории для значения цены фондового рынка. Вместо того, чтобы использовать точные значения цен для стратификации, мы создадим категории, основываясь на квартилях (25%, 50%, 75%) и минимальном и максимальном значении. Это позволит создать более крупные классы, что устранит проблему с редкими значениями.\n",
"\n",
"Категории для разбиения зарплат:\n",
"- Низкая цена индекса: значения ниже первого квартиля (25%) — это цены фондовых индексов ниже 2846.50.\n",
"- Средняя цена индекса: значения между первым квартилем (25%) и третьим квартилем (75%) — это цены от 2846.50 до 9484.47.\n",
"- Высокая цена индекса: значения выше третьего квартиля (75%) и до максимального значения — это цены выше 9484.47.\n",
"\n",
"Весь набор данных состоит из 369 объектов, из которых 184 (около 49.9%) имеют средний уровень цены фондового рынка (medium), 93 (около 25.2%) низкий уровень цены (low), и 92 (около 24.9%) высокий уровень цены (high).\n",
"\n",
"Все выборки показывают одинаковое распределение классов, что свидетельствует о том, что данные были отобраны случайным образом и не содержат явного смещения.\n",
"\n",
"Однако, несмотря на сбалансированность при разбиении данных, в целом данные обладают значительным дисбалансом между классами. Это может быть проблемой при обучении модели, так как она может иметь тенденцию игнорировать низкие или высокие цены фондовых рынков (low или high), что следует учитывать при дальнейшем анализе и выборе методов обработки данных.\n",
"\n",
"Для получения более сбалансированных выборок данных необходимо воспользоваться методами приращения (аугментации) данных, а именно методами oversampling и undersampling."
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Распределение количества наблюдений по меткам (классам):\n",
"index price\n",
"5160.100 53\n",
"19441.425 33\n",
"1000.000 2\n",
"285.430 1\n",
"248.890 1\n",
" ..\n",
"1647.170 1\n",
"1986.530 1\n",
"2099.320 1\n",
"2263.410 1\n",
"203.150 1\n",
"Name: count, Length: 284, dtype: int64 \n",
"\n",
"Статистическое описание целевого признака:\n",
"count 369.000000\n",
"mean 6948.930095\n",
"std 5682.147273\n",
"min 168.610000\n",
"25% 2846.500000\n",
"50% 5160.100000\n",
"75% 9484.470000\n",
"max 19441.425000\n",
"Name: index price, dtype: float64 \n",
"\n",
"Распределение количества наблюдений по меткам (классам):\n",
"index_price_category\n",
"medium 184\n",
"low 93\n",
"high 92\n",
"Name: count, dtype: int64 \n",
"\n",
"Проверка сбалансированности выборок:\n",
"Обучающая выборка: (221, 15)\n",
"Распределение выборки данных по классам в колонке \"index_price_category\":\n",
" index_price_category\n",
"medium 110\n",
"low 56\n",
"high 55\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"medium\": 49.77%\n",
"Процент объектов класса \"low\": 25.34%\n",
"Процент объектов класса \"high\": 24.89%\n",
"\n",
"Контрольная выборка: (74, 15)\n",
"Распределение выборки данных по классам в колонке \"index_price_category\":\n",
" index_price_category\n",
"medium 37\n",
"high 19\n",
"low 18\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"medium\": 50.00%\n",
"Процент объектов класса \"high\": 25.68%\n",
"Процент объектов класса \"low\": 24.32%\n",
"\n",
"Тестовая выборка: (74, 15)\n",
"Распределение выборки данных по классам в колонке \"index_price_category\":\n",
" index_price_category\n",
"medium 37\n",
"low 19\n",
"high 18\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"medium\": 50.00%\n",
"Процент объектов класса \"low\": 25.68%\n",
"Процент объектов класса \"high\": 24.32%\n",
"\n",
"Проверка необходимости аугментации выборок:\n",
"Для обучающей выборки аугментация данных требуется\n",
"Для контрольной выборки аугментация данных требуется\n",
"Для тестовой выборки аугментация данных требуется\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1500x500 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Вывод распределения количества наблюдений по меткам (классам)\n",
"print('Распределение количества наблюдений по меткам (классам):')\n",
"print(df['index price'].value_counts(), '\\n')\n",
"\n",
"# Статистическое описание целевого признака\n",
"print('Статистическое описание целевого признака:')\n",
"print(df['index price'].describe().transpose(), '\\n')\n",
"\n",
"# Определим границы для каждой категории цен фондового рынка\n",
"bins: list[float] = [df['index price'].min() - 1, \n",
" df['index price'].quantile(0.25), \n",
" df['index price'].quantile(0.75), \n",
" df['index price'].max() + 1]\n",
"labels: list[str] = ['low', 'medium', 'high']\n",
"\n",
"# Создаем новую колонку с категориями зарплат\n",
"df['index_price_category'] = pd.cut(df['index price'], bins=bins, labels=labels)\n",
"\n",
"# Вывод распределения количества наблюдений по меткам (классам)\n",
"print('Распределение количества наблюдений по меткам (классам):')\n",
"print(df['index_price_category'].value_counts(), '\\n')\n",
"\n",
"df_train, df_val, df_test = split_stratified_into_train_val_test(\n",
" df,\n",
" stratify_colname=\"index_price_category\", \n",
" frac_train=0.60, \n",
" frac_val=0.20, \n",
" frac_test=0.20\n",
")\n",
"\n",
"# Проверка сбалансированности выборок\n",
"print('Проверка сбалансированности выборок:')\n",
"check_balance(df_train, 'Обучающая выборка', 'index_price_category')\n",
"check_balance(df_val, 'Контрольная выборка', 'index_price_category')\n",
"check_balance(df_test, 'Тестовая выборка', 'index_price_category')\n",
"\n",
"# Проверка необходимости аугментации выборок\n",
"print('Проверка необходимости аугментации выборок:')\n",
"print(f\"Для обучающей выборки аугментация данных {'не ' if not need_augmentation(df_train, 'index_price_category', 'low', 'medium') else ''}требуется\")\n",
"print(f\"Для контрольной выборки аугментация данных {'не ' if not need_augmentation(df_val, 'index_price_category', 'low', 'medium') else ''}требуется\")\n",
"print(f\"Для тестовой выборки аугментация данных {'не ' if not need_augmentation(df_test, 'index_price_category', 'low', 'medium') else ''}требуется\")\n",
" \n",
"# Визуализация сбалансированности классов\n",
"visualize_balance(df_train, df_val, df_test, 'index_price_category')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Приращение данных:"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Проверка сбалансированности выборок после применения метода oversampling:\n",
"Обучающая выборка: (335, 31)\n",
"Распределение выборки данных по классам в колонке \"index_price_category\":\n",
" index_price_category\n",
"low 115\n",
"medium 110\n",
"high 110\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"low\": 34.33%\n",
"Процент объектов класса \"medium\": 32.84%\n",
"Процент объектов класса \"high\": 32.84%\n",
"\n",
"Контрольная выборка: (110, 31)\n",
"Распределение выборки данных по классам в колонке \"index_price_category\":\n",
" index_price_category\n",
"high 40\n",
"medium 37\n",
"low 33\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"high\": 36.36%\n",
"Процент объектов класса \"medium\": 33.64%\n",
"Процент объектов класса \"low\": 30.00%\n",
"\n",
"Тестовая выборка: (115, 31)\n",
"Распределение выборки данных по классам в колонке \"index_price_category\":\n",
" index_price_category\n",
"low 42\n",
"medium 37\n",
"high 36\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"low\": 36.52%\n",
"Процент объектов класса \"medium\": 32.17%\n",
"Процент объектов класса \"high\": 31.30%\n",
"\n",
"Проверка необходимости аугментации выборок после применения метода oversampling:\n",
"Для обучающей выборки аугментация данных не требуется\n",
"Для контрольной выборки аугментация данных не требуется\n",
"Для тестовой выборки аугментация данных не требуется\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABmIAAAH/CAYAAABEn8JkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdd3zU5B8H8M9179JS6GKXPcuWMlplCSigIio/ZChDERVUhqIgiCKigAoqiDILKCBL2XtvWlZbCm2hLd17XXvj+f1RL/Z6ndA2HZ/368VLe5dLPsnl8k3yJE8UQggBIiIiIiIiIiIiIiIiKnNGcgcgIiIiIiIiIiIiIiKqrtgQQ0REREREREREREREVE7YEENERERERERERERERFRO2BBDRERERERERERERERUTtgQQ0REREREREREREREVE7YEENERERERERERERERFRO2BBDRERERERERERERERUTtgQQ0REREREREREREREVE7YEENERJRHcnIy7t27B7VaLXcUKkNCCCQmJiI4OFjuKERERPSEcnJyEB0djUePHskdhYiIiMpQRkYGwsPDkZSUJHeUMseGGKIqwMfHBz4+PpV+nHL4/PPPoVAo5I5BVZhKpcI333yDDh06wNzcHA4ODmjWrBmOHj0qd7Qq4datW9i1a5f0t5+fH/755x/5AuWRlpaGTz/9FC1atICZmRlq166N5s2bIygoSO5oVI2wRheONZqo6tm0aRPCwsKkv9etW4fIyEj5AuVx5coVjBo1Ck5OTjA3N4erqyteeukluWNRJcF6XDjWYyICgK+++gparRYAoNVqsWjRIpkT/Wfbtm3o27cvbG1tYWNjgwYNGuCbb76RO1aZK1VDzLp166BQKKR/FhYWaN68OaZOnYqYmJjyykhU7X3++edo1KgRgP9+Z1QzffXVV3ontasLHx8fjBs3DgAwbty4SnNAk52djX79+uGzzz6Dj48Ptm3bhsOHD+PYsWPo0aOH3PFKRa4anZaWhsmTJ+PChQsIDg7G+++/j5s3b5bb9EoqISEBPXr0wA8//IARI0Zg9+7dOHz4ME6cOCFtb4lKgjWadFijqSSq+jHz6dOnMXPmTISFheHgwYN45513YGQk//Wbu3fvRq9evXDnzh18+eWXOHz4MA4fPoxVq1bJHY0qCOsx6bAeEz2e9evX49tvv0VERAS+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
"text/plain": [
"<Figure size 1500x500 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Приращение данных (oversampling)\n",
"df_train_oversampled: DataFrame = oversample(df_train, 'index_price_category')\n",
"df_val_oversampled: DataFrame = oversample(df_val, 'index_price_category')\n",
"df_test_oversampled: DataFrame = oversample(df_test, 'index_price_category')\n",
"\n",
"# Проверка сбалансированности выборок\n",
"print('Проверка сбалансированности выборок после применения метода oversampling:')\n",
"check_balance(df_train_oversampled, 'Обучающая выборка', 'index_price_category')\n",
"check_balance(df_val_oversampled, 'Контрольная выборка', 'index_price_category')\n",
"check_balance(df_test_oversampled, 'Тестовая выборка', 'index_price_category')\n",
"\n",
"# Проверка необходимости аугментации выборок\n",
"print('Проверка необходимости аугментации выборок после применения метода oversampling:')\n",
"print(f\"Для обучающей выборки аугментация данных {'не ' if not need_augmentation(df_train_oversampled, 'index_price_category', 'low', 'medium') else ''}требуется\")\n",
"print(f\"Для контрольной выборки аугментация данных {'не ' if not need_augmentation(df_val_oversampled, 'index_price_category', 'low', 'medium') else ''}требуется\")\n",
"print(f\"Для тестовой выборки аугментация данных {'не ' if not need_augmentation(df_test_oversampled, 'index_price_category', 'low', 'medium') else ''}требуется\")\n",
" \n",
"# Визуализация сбалансированности классов\n",
"visualize_balance(df_train_oversampled, df_val_oversampled, df_test_oversampled, 'index_price_category')"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Проверка сбалансированности выборок после применения метода undersampling:\n",
"Обучающая выборка: (165, 31)\n",
"Распределение выборки данных по классам в колонке \"index_price_category\":\n",
" index_price_category\n",
"low 55\n",
"medium 55\n",
"high 55\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"low\": 33.33%\n",
"Процент объектов класса \"medium\": 33.33%\n",
"Процент объектов класса \"high\": 33.33%\n",
"\n",
"Контрольная выборка: (54, 31)\n",
"Распределение выборки данных по классам в колонке \"index_price_category\":\n",
" index_price_category\n",
"low 18\n",
"medium 18\n",
"high 18\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"low\": 33.33%\n",
"Процент объектов класса \"medium\": 33.33%\n",
"Процент объектов класса \"high\": 33.33%\n",
"\n",
"Тестовая выборка: (54, 31)\n",
"Распределение выборки данных по классам в колонке \"index_price_category\":\n",
" index_price_category\n",
"low 18\n",
"medium 18\n",
"high 18\n",
"Name: count, dtype: int64\n",
"Процент объектов класса \"low\": 33.33%\n",
"Процент объектов класса \"medium\": 33.33%\n",
"Процент объектов класса \"high\": 33.33%\n",
"\n",
"Проверка необходимости аугментации выборок после применения метода undersampling:\n",
"Для обучающей выборки аугментация данных не требуется\n",
"Для контрольной выборки аугментация данных не требуется\n",
"Для тестовой выборки аугментация данных не требуется\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABmIAAAH/CAYAAABEn8JkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAACsbElEQVR4nOzdd3hUZd6H8e+k91BCCR3pVVCKgAqKgoBrFzvgWteydkVdRbEirqJiAV0RBEURBRUEQVFREUGpUqRK6AklpLd53j94Z8xkkpAykzPl/lyX1y7JZOaXycncZ/KcOWMzxhgBAAAAAAAAAADA40KsHgAAAAAAAAAAACBQsRADAAAAAAAAAADgJSzEAAAAAAAAAAAAeAkLMQAAAAAAAAAAAF7CQgwAAAAAAAAAAICXsBADAAAAAAAAAADgJSzEAAAAAAAAAAAAeAkLMQAAAAAAAAAAAF7CQgwAAMUcPXpUW7duVWFhodWjwIOMMTp8+LC2bNli9SgAAKCa8vPztX//fu3du9fqUQAAgAdlZWUpJSVFR44csXoUj2MhBvADAwYM0IABA3z+Oq3wxBNPyGazWT0G/FhBQYFeeOEFnXzyyYqMjFTt2rXVpk0bffPNN1aP5hfWr1+vOXPmOP+9evVqzZs3z7qBisnIyNB//vMftWvXThEREapbt67atm2rzZs3Wz0aAgiNLhuNBvzP9OnTtXPnTue/33vvPe3Zs8e6gYpZuXKlrr76aiUlJSkyMlLJycm69NJLrR4LPoIel40eA5CkZ599Vna7XZJkt9v13HPPWTzR32bNmqWBAwcqPj5ecXFxatasmV544QWrx/K4Si3EvPfee7LZbM7/oqKi1LZtW91xxx06cOCAt2YEAt4TTzyhFi1aSPr79wzB6dlnn3X5o3agGDBggEaNGiVJGjVqlM88ocnLy9M555yjxx57TAMGDNCsWbO0aNEiffvtt+rTp4/V41WKVY3OyMjQLbfcol9++UVbtmzRXXfdpXXr1nnt9irq0KFD6tOnj1599VVddtllmjt3rhYtWqTvvvvO+XgLVASNhgONRkX4+3PmpUuX6sEHH9TOnTu1cOFC3X777QoJsf74zblz5+r000/Xhg0b9Mwzz2jRokVatGiRJk2aZPVoqCH0GA70GKiaqVOn6sUXX9Tu3bv13//+V1OnTrV6JEnS6NGjNXz4cMXHx+vtt9/WokWLtHjxYt12221Wj+ZxYVX5orFjx6ply5bKzc3Vjz/+qDfffFPz58/X+vXrFRMT4+kZgaD39ddfWz2Cz/rPf/6j0aNHWz2Gxzz77LO67LLLdNFFF1k9SlAYN26cli9froULFwbMjm5NN7pPnz7O/ySpbdu2uummmzx+O5X1wAMPaN++fVq2bJk6depk9TgIYDS6bDQawcxfnzPfc889GjBggFq2bClJuvfee5WcnGzpTIcPH9aNN96owYMHa9asWYqIiLB0Hvgmelw2egxAOr5vMmLECD300EOKjIzU9OnTrR5J33//vcaNG6fnnnsuoB6nylKlhZghQ4aoR48ekqQbb7xRdevW1UsvvaS5c+fqqquu8uiAAMSTjVJkZWUpNjZWYWFhCgur0kMZqsFx//uzwsJCTZgwQffdd1/ALMJI1jR6zpw52rBhg3JyctSlSxfLH7MOHjyoqVOn6q233mIRBl5n9fbui2i0tQKh0YHAX58zt2/fXtu2bdP69euVlJSkVq1aWT2SpkyZotzcXL333ns85qJMbBvu6LG16DF8zRVXXKGzzjpLW7duVZs2bVSvXj2rR9KLL76ovn37BsUijOSh94g5++yzJUk7duyQdPyIlfvvv19dunRRXFycEhISNGTIEK1Zs8bta3Nzc/XEE0+obdu2ioqKUnJysi655BJt27ZNkrRz506Xl3aX/K/4H8++++472Ww2ffTRR3rkkUfUsGFDxcbG6oILLlBKSorbbS9fvlznnXeeEhMTFRMTo/79++unn34q9XscMGBAqbf/xBNPuF12+vTpOvXUUxUdHa06deroyiuvLPX2y/veirPb7ZowYYI6deqkqKgoNWjQQLfccovbmxa1aNFC559/vtvt3HHHHW7XWdrs48ePd7tPpeOn7hkzZoxat26tyMhINW3aVA8++KDy8vJKva+KK+2cqs8884xCQkL0wQcfVOn+cPyS1q1bV9HR0Tr11FP1ySeflHr706dPV69evRQTE6PatWvrzDPPdDtS5quvvlL//v0VHx+vhIQE9ezZ0222WbNmOX+mSUlJuvbaa93OlTxq1CiXmWvXrq0BAwZo6dKlJ7yfTqTk/ejY1j/++GM988wzatKkiaKiojRw4EBt3brV7esnT56sVq1aKTo6Wr169Spzpor8rEeOHKmoqCht3LjR5WsHDx6s2rVrV+oNM202m+644w7NmDFD7dq1U1RUlE499VT98MMPLpdznNN2w4YNuvrqq1W7dm2dfvrpLp8rqaI/+zPOOEOxsbGKj4/XsGHD9Mcff1R4focTPY5JFdtubTabsrKyNHXqVOd25HhpsiTt2bNH//znP9WgQQNFRkaqU6dOevfdd93m+euvv3TBBRcoNjZW9evX1z333KOFCxfKZrPpu+++c7lsRbftuLg4bdu2TUOHDlV8fLyuueYajRkzRuHh4UpNTXWb4eabb1atWrWUm5tb6fvToUWLFs77ISQkRA0bNtQVV1yhXbt2Vejr33jjDXXq1EmRkZFq1KiRbr/9dh09etT5+c2bN+vIkSOKj49X//79FRMTo8TERJ1//vlav36983JLliyRzWbTZ5995nYbH3zwgWw2m5YtW+acufjPTPr797X4fb906VJdfvnlatasmfN37Z577lFOTo7L15a2fc+YMUPdunVTVFSU6tatq6uuusrtPnH8zKS/G/3FF1/IZrPp888/d2m0zWZTkyZN3Bo9ffp0de/eXWFhYQoNDVVoaKjq16/vsm2fdtppzp9Rp06d1KNHD0VGRla40aGhoS6Pm0lJSRo2bJjWr1/v0mibzabGjRuX2ej27du7XE+DBg1kt9v12WefqUePHi731YQJE9waPXPmTOdjQa1atXThhRdq8eLFZTZp+PDhSkhIUN26dfXvf/9b48ePd2m0zWbTQw895JyvsLBQMTExioiI0IYNG1xmP/fcc2Wz2VzmodF/o9F/o9E0OlAaXVorb775ZkVFRbndBydquXT8d7Bz585ut/Piiy/KZrM53++k+Myl/ec45ZHj8e7FF1/Uyy+/rObNmys6Olr9+/d32T9w+Pbbb10a8sorr5T6fTt6fPXVV7vddnR0tPM5c6NGjdye05XcjuvXry+bzeb8o8WJnjP369dPN9xwgxo0aKCIiAjZbDbddtttLs+ZzznnHNlsNr333nuKjY1V79691apVK1122WWy2WyKiIgo9zlzeTM89thjzss5Tik1duzYMp8zF39c3blzp+6//35lZmaqTp06Ltf7/PPPu5zr3vGcOTw83Ln/0rRpUz3yyCPOx0rHc2bH/3799dfq1q2bc5/k008/dc5qs9l00UUXuWxHjh6HhYXp/PPPV2FhoaTjj9EPPfSQatWq5dKaZ555xjljWegxPS4PPabH5alqj73VxE2bNumyyy5TnTp1FBUVpR49eujzzz93uYyjAytXrnT5eFpamtvzoNK23czMTDVs2NDtZ+XYH/jtt9/Ut29fRUdHq2XLlnrrrbfc5jx48KCzi1FRUTr55JPdTtNV8vE2PDxcLVq00AMPPKD8/HyXy27fvl2XX3656tSpo5iYGJ122mlu75ta1u9hyf2iytw/krRq1SoNGTJECQkJiouL08CBA/XLL7+4XMZxnTt37lT9+vWdv2ddu3Z1tr88JU+7GhMToy5duuidd95xuVzxv0OUpeT38Msvv6hz58668sorVadOHUVHR6tnz56lnn6wMj+3imyzo0aNcjtt+fTp0xUSEqLnn3/e5eMV2bYrxFTClClTjCSzYsUKl4+/8sorRpJ56623jDHGrFixwrRq1cqMHj3aTJo0yYwdO9Y0btzYJCYmmj179ji/rrCw0AwcONBIMld
"text/plain": [
"<Figure size 1500x500 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Приращение данных (undersampling)\n",
"df_train_undersampled: DataFrame = undersample(df_train, 'index_price_category')\n",
"df_val_undersampled: DataFrame = undersample(df_val, 'index_price_category')\n",
"df_test_undersampled: DataFrame = undersample(df_test, 'index_price_category')\n",
"\n",
"# Проверка сбалансированности выборок\n",
"print('Проверка сбалансированности выборок после применения метода undersampling:')\n",
"check_balance(df_train_undersampled, 'Обучающая выборка', 'index_price_category')\n",
"check_balance(df_val_undersampled, 'Контрольная выборка', 'index_price_category')\n",
"check_balance(df_test_undersampled, 'Тестовая выборка', 'index_price_category')\n",
"\n",
"# Проверка необходимости аугментации выборок\n",
"print('Проверка необходимости аугментации выборок после применения метода undersampling:')\n",
"print(f\"Для обучающей выборки аугментация данных {'не ' if not need_augmentation(df_train_undersampled, 'index_price_category', 'low', 'medium') else ''}требуется\")\n",
"print(f\"Для контрольной выборки аугментация данных {'не ' if not need_augmentation(df_val_undersampled, 'index_price_category', 'low', 'medium') else ''}требуется\")\n",
"print(f\"Для тестовой выборки аугментация данных {'не ' if not need_augmentation(df_test_undersampled, 'index_price_category', 'low', 'medium') else ''}требуется\")\n",
" \n",
"# Визуализация сбалансированности классов\n",
"visualize_balance(df_train_undersampled, df_val_undersampled, df_test_undersampled, 'index_price_category')"
]
2024-10-17 00:52:35 +04:00
}
],
"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
}