diff --git a/lab_3/lab3.ipynb b/lab_3/lab3.ipynb new file mode 100644 index 0000000..9ac7ebf --- /dev/null +++ b/lab_3/lab3.ipynb @@ -0,0 +1,1030 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Данные по инсультам\n", + "\n", + "Выведем информацию о столбцах датасета:" + ] + }, + { + "cell_type": "code", + "execution_count": 441, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Index(['id', 'gender', 'age', 'hypertension', 'heart_disease', 'ever_married',\n", + " 'work_type', 'Residence_type', 'avg_glucose_level', 'bmi',\n", + " 'smoking_status', 'stroke'],\n", + " dtype='object')\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idgenderagehypertensionheart_diseaseever_marriedwork_typeResidence_typeavg_glucose_levelbmismoking_statusstroke
09046Male67.001YesPrivateUrban228.6936.6formerly smoked1
151676Female61.000YesSelf-employedRural202.21NaNnever smoked1
231112Male80.001YesPrivateRural105.9232.5never smoked1
360182Female49.000YesPrivateUrban171.2334.4smokes1
41665Female79.010YesSelf-employedRural174.1224.0never smoked1
\n", + "
" + ], + "text/plain": [ + " id gender age hypertension heart_disease ever_married \\\n", + "0 9046 Male 67.0 0 1 Yes \n", + "1 51676 Female 61.0 0 0 Yes \n", + "2 31112 Male 80.0 0 1 Yes \n", + "3 60182 Female 49.0 0 0 Yes \n", + "4 1665 Female 79.0 1 0 Yes \n", + "\n", + " work_type Residence_type avg_glucose_level bmi smoking_status \\\n", + "0 Private Urban 228.69 36.6 formerly smoked \n", + "1 Self-employed Rural 202.21 NaN never smoked \n", + "2 Private Rural 105.92 32.5 never smoked \n", + "3 Private Urban 171.23 34.4 smokes \n", + "4 Self-employed Rural 174.12 24.0 never smoked \n", + "\n", + " stroke \n", + "0 1 \n", + "1 1 \n", + "2 1 \n", + "3 1 \n", + "4 1 " + ] + }, + "execution_count": 441, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "from sklearn.model_selection import train_test_split\n", + "from imblearn.over_sampling import RandomOverSampler\n", + "from sklearn.preprocessing import StandardScaler\n", + "import featuretools as ft\n", + "from sklearn.linear_model import LinearRegression\n", + "from sklearn.model_selection import cross_val_score\n", + "import time\n", + "from sklearn.metrics import root_mean_squared_error, r2_score, mean_absolute_error\n", + "from sklearn.ensemble import RandomForestRegressor\n", + "\n", + "df = pd.read_csv(\"..//..//static//csv//healthcare-dataset-stroke-data.csv\")\n", + "\n", + "print(df.columns)\n", + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Определим бизнес цели и цели технического проекта.\n", + "\n", + "1. Улучшение диагностики и профилактики инсульта.\n", + " * Бизнес-цель: повышение точности прогнозирования риска инсульта среди пациентов для более раннего лечебного вмешательства. Определение основных факторов риска для более целенаправленного подхода в медицинском обслуживании.\n", + " * Цель технического проекта: разработка статистической модели, которая решает задачу классификации и предсказывает возможность возникновения инсульта у пациентов на основе имеющихся данных (возраст, гипертония, заболевания сердца и пр.), с целью выявления групп риска. Внедрение этой модели в систему поддержки принятия медицинских решений для врачей.\n", + "2. Снижение расходов на лечение инсультов.\n", + " * Бизнес-цель: снижение затрат на лечение инсульта путем более эффективного распределения медицинских ресурсов и направленных профилактических мер.\n", + " * Цель технического проекта: создание системы оценки индивидуального риска инсульта для пациентов, что позволит медучреждениям проводить профилактические меры среди целевых групп, сокращая расходы на лечение.\n", + "\n", + "### И теперь проверим датасет на пустые значения:" + ] + }, + { + "cell_type": "code", + "execution_count": 442, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "id 0\n", + "gender 0\n", + "age 0\n", + "hypertension 0\n", + "heart_disease 0\n", + "ever_married 0\n", + "work_type 0\n", + "Residence_type 0\n", + "avg_glucose_level 0\n", + "bmi 201\n", + "smoking_status 0\n", + "stroke 0\n", + "dtype: int64\n", + "\n", + "id False\n", + "gender False\n", + "age False\n", + "hypertension False\n", + "heart_disease False\n", + "ever_married False\n", + "work_type False\n", + "Residence_type False\n", + "avg_glucose_level False\n", + "bmi True\n", + "smoking_status False\n", + "stroke False\n", + "dtype: bool\n", + "\n", + "bmi процент пустых значений: %3.93\n" + ] + } + ], + "source": [ + "# Количество пустых значений признаков\n", + "print(df.isnull().sum())\n", + "\n", + "print()\n", + "\n", + "# Есть ли пустые значения признаков\n", + "print(df.isnull().any())\n", + "\n", + "print()\n", + "\n", + "# Процент пустых значений признаков\n", + "for i in df.columns:\n", + " null_rate = df[i].isnull().sum() / len(df) * 100\n", + " if null_rate > 0:\n", + " print(f\"{i} процент пустых значений: %{null_rate:.2f}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "В столбце bmi можно заметить пустые значение. Заменим их на медиану:" + ] + }, + { + "cell_type": "code", + "execution_count": 443, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Количество пустых значений в каждом столбце после замены:\n", + "id 0\n", + "gender 0\n", + "age 0\n", + "hypertension 0\n", + "heart_disease 0\n", + "ever_married 0\n", + "work_type 0\n", + "Residence_type 0\n", + "avg_glucose_level 0\n", + "bmi 0\n", + "smoking_status 0\n", + "stroke 0\n", + "dtype: int64\n" + ] + } + ], + "source": [ + "# Замена значений\n", + "df[\"bmi\"] = df[\"bmi\"].fillna(df[\"bmi\"].median())\n", + "\n", + "# Проверка на пропущенные значения после замены\n", + "missing_values_after_drop = df.isnull().sum()\n", + "\n", + "# Вывод результатов после замены\n", + "print(\"\\nКоличество пустых значений в каждом столбце после замены:\")\n", + "print(missing_values_after_drop)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Можно перейти к созданию выборок" + ] + }, + { + "cell_type": "code", + "execution_count": 444, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Размер обучающей выборки: (2503, 11)\n", + "Размер контрольной выборки: (1074, 11)\n", + "Размер тестовой выборки: (1533, 11)\n" + ] + } + ], + "source": [ + "# Разделение данных на признаки (X) и целевую переменную (y)\n", + "# В данном случае мы хотим предсказать 'stroke'\n", + "X = df.drop(columns=['stroke'])\n", + "y = df['stroke']\n", + "\n", + "# Разбиение данных на обучающую и тестовую выборки\n", + "# Сначала разделим на обучающую и тестовую\n", + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)\n", + "\n", + "# Затем разделим обучающую выборку на обучающую и контрольную\n", + "X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.3)\n", + "\n", + "# Проверка размеров выборок\n", + "print(\"Размер обучающей выборки:\", X_train.shape)\n", + "print(\"Размер контрольной выборки:\", X_val.shape)\n", + "print(\"Размер тестовой выборки:\", X_test.shape)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Оценим сбалансированность выборок:" + ] + }, + { + "cell_type": "code", + "execution_count": 445, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Распределение классов в обучающей выборке:\n", + "stroke\n", + "0 0.955653\n", + "1 0.044347\n", + "Name: proportion, dtype: float64\n", + "\n", + "Распределение классов в контрольной выборке:\n", + "stroke\n", + "0 0.954376\n", + "1 0.045624\n", + "Name: proportion, dtype: float64\n", + "\n", + "Распределение классов в тестовой выборке:\n", + "stroke\n", + "0 0.941944\n", + "1 0.058056\n", + "Name: proportion, dtype: float64\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABboAAAHyCAYAAAAtJXgGAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABpfElEQVR4nO3dd3RU1d7G8ScJ6SEgpFJM6KGDoQiItECA0PQKUq4EVEABFfCigkoAS0QUQUApChbwiqDgVZQqKGIEAVGQIiVID4QWagKZ/f7ByrwMM4FQZHLw+1kra2X27HPO78xkZp95cmYfD2OMEQAAAAAAAAAAFuXp7gIAAAAAAAAAALgRBN0AAAAAAAAAAEsj6AYAAAAAAAAAWBpBNwAAAAAAAADA0gi6AQAAAAAAAACWRtANAAAAAAAAALA0gm4AAAAAAAAAgKURdAMAAAAAAAAALI2gGwAAAACug81mU3p6unbu3OnuUgAAAP7xCLoBAAAAII8OHjyoAQMGKCoqSj4+PgoNDVWlSpWUkZHh7tIAAAD+0Qq4uwAAAICb7YMPPlDPnj3tt319fXXnnXeqRYsWevHFFxUeHu7G6gBY1fbt29WkSROdP39eTz75pO666y4VKFBA/v7+CgwMdHd5AAAA/2gE3QAA4LY1cuRIlSpVSufOndOPP/6od999V9988402btyogIAAd5cHwGL69OkjHx8f/fzzzypevLi7ywEAAMAlCLoBAMBtq1WrVqpVq5Yk6dFHH1XRokU1ZswYffnll+rSpYubqwNgJWvXrtV3332nRYsWEXIDAADkQ8zRDQAA/jGaNm0qSUpNTZUkHT16VP/5z39UtWpVBQUFKTg4WK1atdJvv/3mtOy5c+c0fPhwlS9fXn5+foqMjNT999+vHTt2SJJ27dolDw+PXH8aN25sX9fy5cvl4eGhWbNmaejQoYqIiFBgYKDatWunPXv2OG171apVatmypQoVKqSAgAA1atRIK1eudLmPjRs3drn94cOHO/WdMWOGYmNj5e/vryJFiqhz584ut3+lfbuUzWbT2LFjVblyZfn5+Sk8PFx9+vTRsWPHHPpFR0erTZs2Ttvp37+/0zpd1T569Ginx1SSMjMzlZSUpLJly8rX11clS5bUM888o8zMTJeP1aUuf9xCQkKUkJCgjRs35mnZKlWqaO3atapfv778/f1VqlQpTZo0yaFfVlaWhg0bptjYWBUqVEiBgYFq2LChli1b5tBv69atatq0qSIiIuz78dhjj+no0aNO2+7Ro8dVn+8ePXooOjraYbk9e/bI399fHh4e2rVrl6T/f54/+OADh77Dhw93+bz079/fqZ42bdo4bCtnnW+88UYuj57z+qdPny4PDw9NmzbNod+rr74qDw8PffPNN7muS7r495XzOHh6eioiIkIPPvigdu/efUN1/fzzz/Lz89OOHTtUuXJl+fr6KiIiQn369HH53MyePdv++goJCdG///1v7du3z6FPjx49FBQUpJ07dyo+Pl6BgYEqVqyYRo4cKWOMU72XPjcnT55UbGysSpUqpQMHDtjb33jjDdWvX19FixaVv7+/YmNjNWfOHIft3uhjDAAAkB9xRjcAAPjHyAmlixYtKknauXOn5s2bp44dO6pUqVJKS0vT5MmT1ahRI23atEnFihWTJGVnZ6tNmzZaunSpOnfurKeeekonT57U4sWLtXHjRpUpU8a+jS5duqh169YO2x0yZIjLel555RV5eHjo2Wef1aFDhzR27FjFxcVp/fr18vf3lyR99913atWqlWJjY5WUlCRPT09Nnz5dTZs21YoVK1SnTh2n9ZYoUULJycmSpFOnTunxxx93ue0XX3xRnTp10qOPPqrDhw9r/Pjxuvfee/Xrr7+qcOHCTsv07t1bDRs2lCR98cUXmjt3rsP9ffr0sc+P/uSTTyo1NVUTJkzQr7/+qpUrV8rb29vl43Atjh8/bt+3S9lsNrVr104//vijevfurYoVK2rDhg1666239Oeff2revHlXXXdMTIyef/55GWO0Y8cOjRkzRq1bt3YISHNz7NgxtW7dWp06dVKXLl302Wef6fHHH5ePj48efvhhSVJGRobee+89denSRb169dLJkyf1/vvvKz4+XqtXr1aNGjUkSadPn1aJEiXUtm1bBQcHa+PGjZo4caL27dunr776ymnbISEheuutt+y3H3rooavWO2zYMJ07d+6q/dyhZ8+e+uKLLzRo0CA1b95cJUuW1IYNGzRixAg98sgjTq8vVxo2bKjevXvLZrNp48aNGjt2rPbv368VK1Zcd11HjhzRuXPn9Pjjj6tp06Z67LHHtGPHDk2cOFGrVq3SqlWr5OvrK+n/rxNQu3ZtJScnKy0tTePGjdPKlSudXl/Z2dlq2bKl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6MUXX1R8fLzat2+vnTt3asKECapevboeffRRSRfnuB81apR69uypRo0aqUuXLkpLS9O4ceMUHR2tgQMHOqzXz89PCxYsUGJiourWratvv/1W8+fP19ChQ684j33v3r31ySef6LHHHtPGjRsVEBCghIQEjRkzRi1btlTXrl116NAhTZw4UWXLltXvv/9+Ux9jAACAfMcAAADcZqZPn24kmV9++eWK/c6dO2eefvppExkZafz9/U2DBg1MSkqKadSokWnUqJFD3zNnzpjnn3/elCpVynh7e5uIiAjzwAMPmB07dhhjjElNTTWSzOjRo522U7lyZYf1LVu2zEgy//3vf82QIUNMWFiY8ff3NwkJCeavv/5yWv7XX381999/vylatKjx9fU1UVFRplOnTmbp0qUO277aT2JiosN6P//8c3PPPfeYwMBAExgYaGJiYky/fv3M1q1bjTHGPPHEE+bee+81CxYscKopKSnJuDqUnDJliomNjTX+/v6mYMGCpmrVquaZZ54x+/fvt/eJiooyCQkJTsv269fPaZ2SjIeHh1m7dq1Du6vnKCsry4waNcpUrlzZ+Pr6mjvuuMPExsaaESNGmBMnTjht7/L1XfpYFS5c2DRo0MB88803V1wuZ9nKlSubNWvWmHr16hk/Pz8TFRVlJkyY4NDPZrOZV1991URFRRlfX19Ts2ZN8/XXX5vExEQTFRVl7zdnzhxTu3ZtExwcbPz9/U3ZsmXN008/bQ4fPmyMMWbv3r2mZMmSZsCAAS73S5JJSkqy305MTDSSzFNPPeXQL+d1kpqaesX9c/VcSzL9+vVz6puQkOCwL5f/bXp6epoSJUqYxMREs3fvXpfrv//++03BggXNrl27HNb95ZdfGklm1KhRV6w3KirKYZshISGmRYsWJiUl5YbqyjFx4kQTExNjvL29TXh4uOnTp485cuSIU79Zs2aZmjVrGl9fX1OkSBHTrVs3+7pzJCYmmsDAQLNjxw7TokULExAQYMLDw01SUpLJzs52qnf69OkOy2/dutX4+fmZgQMH2tvef/99U65cOePr62tiYmLM9OnTb/pjDAAAkB95GHMD37cFAADANVu+fLmaNGmi2bNnX/dZzpfatWuXSpUqpdTUVKc5fXMMHz5cu3btcnkBQtyYxo0bKz09XRs3bnR3KbCYHj16aM6cOS6nJgIAAMC14fto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sKHL+++9915FR0dr/vz59rYjR45oypQpCgoK0pNPPqnQ0FDNmDFD999/v2bOnKkuXbooKChI9913n2bNmqUxY8Y4fL36v//9r4wx6tat2zXV+ssvv+inn35S586dVaJECe3atUvvvvuuGjdurE2bNikgIMDlctu3b1fjxo0VEBCgwYMHKyAgQFOnTlVcXJwWL16se++995rqyM3s2bN15swZPf744ypatKhWr16t8ePHa+/evZo9e7a9X0pKijp16qTq1avrtddeU6FChZSenq6BAwfmeVtvvfWWQkJClJGRoWnTpqlXr16Kjo5WXFzcddefl+dVks6ePavGjRtr+/bt6t+/v0qVKqXZs2erR48eOn78uNM/Nz766COdPHlS/fr107lz5zRu3Dg1bdpUGzZsUHh4uMtaFi1apIcfflj9+/d3mEZl8eLF2rlzp3r27KmIiAj98ccfmjJliv744w/9/PPPeZ7jDgCsYseOHWrZsqV8fX21cOFCRUZGOvXJOQO8du3aSk5OVlpamsaNG6eVK1fq119/VeHCha9pm88//7weffRRSbKPT7179871WOH777/XrFmz9OSTT8rX11fvvPOOWrZsqdWrV9uD6D/++EMNGzZUcHCwnnnmGXl7e2vy5Mlq3Lixvv/+e9WtW9dpvTExMXr++ecd6vi7jRs3Tu3atVO3bt2UlZWlTz/9VB07dtTXX3+thIQEe7/Bgwdr0qRJeuSRR9SgQQN5e3vriy++0Ny5c/O0nZx9M8Zox44dGjNmjFq3bu0ykM6rnH/69u/fX7GxsXrttdd0+PBhvf322/rxxx/166+/KiQkRJK0ZMkStWrVSqVLl9bw4cN19uxZjR8/Xg0aNNC6deuc/gHQqVMnRUdHKzk5WT///LPefvttHTt2TB999FGu9Tz66KNavny5Fi9erEqVKtnb3333XVWuXFnt2rVTgQIF9NVXX6lv376y2Wzq16/fde8/ANzubDab2rVrpx9//FG9e/dWxYoVtWHDBr311lv6888/HU5QGjFihIYPH6769etr5MiR8vHx0apVq/Tdd9+pRYsWGjt2rE6dOiVJ2rx5s1599VUNHTrUPkVKTphsjFG7du20bNkyPfLII6pRo4YWLlyowYMHa9++fXrrrbccarzvvvt0//3368KFC0pJSdGUKVN09uxZ+1QsGRkZeu+999Sl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euONN1SuXDmXZxPdbNnZ2WrevLmOHj2qZ599VjExMQoMDNS+ffvUo0cPh/o6d+6sdevWafz48ZoyZcp1bW/GjBkKDw/XuXPn9N1336lfv37y8/NTjx497H38/Pz01VdfSbr4z4pp06ZpwIABioyMVKdOnZzWeS3P698hPT1dgYGB+uqrr9ShQwclJycrKSnJoU+nTp30008/afDgwapRo4aCgoJks9nUsmXLPJ/pBgBWMXr0aPs/hqdMmaK7775bQ4YM0TvvvHPd67x0bMixYsWKXOd/dJeDBw8qPj7+qv2io6M1depUSRfnzXz77bf10EMPqXTp0vZv/EhS+/btnS7s+MILL+jgwYP22ytWrFC7du1077336p133lFkZKS8vb01ffp0p/B8ypQp6tKli8M/7q9FtWrV7B9Sc+bRbty4sdatW6eIiAinuo0xSk1N1ciRI9WmTRuXH8Bv5Tie2xmBq1evVq9evRQYGKiXX35ZHTt2dPiQv2PHDjVr1kwxMTEaM2aMSpYsKR8fH33zzTd66623GMsB4ApsNpuqVq2qMWPGuLy/ZMmSt7giZw899JC6d+8um82mnTt36qWXXlKbNm20ZMkSeXh4aMaMGerRo4c6dOigwYMHKywsTF5eXkpOTtaOHTsc1jVr1ix169bN6XggMDAwT7W0aNFCgwcPliTt3btXo0aNUpMmTbRmzRqHMbN3797q2LGjsrOztXnzZg0fPlwdOnTQH3/84bROd39mli5eEPOVV17RL7/8ooEDB6ply5YO3wi7luMZwBWCblhamzZtNHXqVP3444+65557nO5fsWKFdu3apT59+tjbSpUqpa1btzr13bJliyQ5XMCoSpUqqlmzpmbOnKkSJUpo9+7dGj9+vNOy77//voYNG6YdO3bYP+Q0b97coc+cOXOUmJho/2AoXfxK76VXcb5UbGysGjVqpKCgoDzXe702bNigP//8Ux9++KG6d+9ub1+8eLFTX09PT73xxhvasGGDUlNT9c477ygtLc1hOperadCggb3uNm3a6I8//lBycrJD0O3l5eVwccqEhAQVKVJECxYscBl05/V5jYqK0u+//y6bzeZwVndOv6ioKIflXX0Y//PPP50e94CAAC1YsEAxMTEaOHCgXn31VXXq1Ml+tsCxY8e0dOlSjRgxQsOGDbvi+gHgdnDpxZJr166tfv36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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Функция для анализа сбалансированности\n", + "def analyze_balance(y_train, y_val, y_test, y_name):\n", + " # Распределение классов\n", + " print(\"Распределение классов в обучающей выборке:\")\n", + " print(y_train.value_counts(normalize=True))\n", + " \n", + " print(\"\\nРаспределение классов в контрольной выборке:\")\n", + " print(y_val.value_counts(normalize=True))\n", + " \n", + " print(\"\\nРаспределение классов в тестовой выборке:\")\n", + " print(y_test.value_counts(normalize=True))\n", + "\n", + " # Создание фигуры и осей для трех столбчатых диаграмм\n", + " fig, axes = plt.subplots(1, 3, figsize=(18, 5), sharey=True)\n", + " fig.suptitle('Распределение в различных выборках')\n", + "\n", + " # Обучающая выборка\n", + " sns.barplot(x=y_train.value_counts().index, y=y_train.value_counts(normalize=True), ax=axes[0])\n", + " axes[0].set_title('Обучающая выборка')\n", + " axes[0].set_xlabel(y_name)\n", + " axes[0].set_ylabel('Доля')\n", + "\n", + " # Контрольная выборка\n", + " sns.barplot(x=y_val.value_counts().index, y=y_val.value_counts(normalize=True), ax=axes[1])\n", + " axes[1].set_title('Контрольная выборка')\n", + " axes[1].set_xlabel(y_name)\n", + "\n", + " # Тестовая выборка\n", + " sns.barplot(x=y_test.value_counts().index, y=y_test.value_counts(normalize=True), ax=axes[2])\n", + " axes[2].set_title('Тестовая выборка')\n", + " axes[2].set_xlabel(y_name)\n", + "\n", + " plt.show()\n", + "\n", + "analyze_balance(y_train, y_val, y_test, 'stroke')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Легко заметить, что выборки несбалансированны. Необходимо сбалансировать обучающую и контрольную выборки, чтобы получить лучшие результаты при обучении модели. Для балансировки применим RandomOverSampler:" + ] + }, + { + "cell_type": "code", + "execution_count": 446, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Распределение классов в обучающей выборке:\n", + "stroke\n", + "0 0.5\n", + "1 0.5\n", + "Name: proportion, dtype: float64\n", + "\n", + "Распределение классов в контрольной выборке:\n", + "stroke\n", + "0 0.5\n", + "1 0.5\n", + "Name: proportion, dtype: float64\n", + "\n", + "Распределение классов в тестовой выборке:\n", + "stroke\n", + "0 0.941944\n", + "1 0.058056\n", + "Name: proportion, dtype: float64\n" + ] + }, + { + "data": { + "image/png": "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X3p6+lWvMN67d6/GjRunl156SYGBgU7br1SpkqKiohzWmT1dzeXbdyW7pkOHDiklJUVfffWVqlWrpqCgoKsuW6BAAfXq1ct+28fHR7169dLBgwe1evVqSZKXl5d8fHwkXbwC/ciRI7pw4YJq1arl8PeW7fjx40pLS9OiRYv03Xff6f7773fqk5mZecXHxZXBgwfrnnvuUbt27Rzag4ODJUl79uzJ1XrOnj3r9BieP3/eZd/Tp08rPT1dR48edZiSIydhYWGaMGGCFixYoJiYGK1du1ZTp05V4cKFc1XbuXPnlJ6eroMHD2rBggX68ccf1bRp0xuuS5IGDhwoLy8v++1HH31UoaGh+u677yRJq1at0sGDB9WnTx+H52JCQoKioqLs/S516TQw2dPCZGZmauHChU59Bw0apBkzZujzzz93+YmO7E+DSBc/aXD8+HHFxMQ4/Y3d6DEGAADIb5i6BAAA3LImTJigu+66SwUKFFBoaKgqVqxoD7ali2Hj2LFj9e677yo1NVVZWVn2+7KnN5EuTnlSsWJFFSiQt6dOFSpUcLjt4eGh8uXL2+dM3rp1qyQpMTExx3UcP35cd9xxh/12enq603ovt3XrVhljcux3+RQjx44dkySncPnydR4/flwhISEu7z948KDD7fnz59uD1dxKSkpSiRIl1KtXL6c5h7du3arNmzfnuM7Lt+/Kr7/+6rB8hQoVNGfOnFz9M6NEiRIqWLCgQ9tdd90l6eL8yvfee68k6aOPPtJbb72lP//80yEULlOmjNM64+PjtWLFCklS8+bNNXPmTKc+x44du+LjcrlffvlF33zzjRYtWuQ0JYu/v79q1qypyZMnKzY21v73cfr0aZfr+uCDD/TBBx84tUdERDi1JSUlKSkpSZLk5+enJk2aaMyYMVf8W+3QoYOmT5+u7777Tj179nQZVOfks88+02effWa/Xbt2bb3//vs3VFf230FUVJRDu5eXlypUqGB/3v7999+SpIoVKzqtIyoqSr/88otDm6enp8qWLevQdunfzqUmTZqk5cuXS5LT3PfZvv32W73yyitau3atw/z0rv6Ob+QYAwAA5DcE3QAA4JZVp04d1apVK8f7X3vtNb300kvq3r27Xn75ZRUrVkyenp56+umnna6UdofsGkaNGmWfv/lyl4acmZmZ2r9/v5o1a3bV9Xp4eOiHH35wuDLV1Tol6cCBA5IuXgF6pXWGhIRoxowZLu+/PICuW7euXnnlFYe28ePH6+uvv3a5/ObNm/Xhhx9q+vTpLuf6ttlsuvvuuzV69GiXy5cuXTrH2rNVq1ZNb731liTp0KFDeuedd9SoUSOtWbPmivueW9OnT1fXrl3Vtm1bDRo0SCEhIfLy8lJycrJ9/vhLjRs3Tunp6dq0aZOSk5P1xBNPaPr06Q59Dhw44DJYzslzzz2n+Ph4NWnSxOlLJyVp4sSJatOmjerXr3/VdbVp08bpCylffPFF+9/LpXr27Kl27dopKytLmzdv1rBhw9S2bVv98ccfOa7/8OHDWrVqlSRp06ZNstlsDv+oupK4uDgNGjRI0sUr1EeOHKnGjRtr1apVDlc8X0tdly7nLsuXL9err76q3377TQMGDFDz5s0dPnGwdOlStW7dWvfff7/effddhYeHy9vbW9OmTdOnn37qtL4bOcYAAAD5DUE3AAC4bc2ePVuNGzd2uir12LFjDuFRuXLltGLFCp0/fz5PvlAxW/YV29mMMdq2bZuqVatm364kFS5cWLGxsVdd37p163T+/PkrhvvZ6zXGqEyZMvYrR69k06ZN8vDwcHmF6qXrXLhwoRo0aJCrQDAoKMhpn670hZGDBw9WjRo19Mgjj+S4/XXr1qlp06bXPZ3MHXfc4VBTo0aNVKJECU2bNi3HLxTNtm/fPp06dcrhqu6//vpLkhQZGSnp4t9b2bJl9eWXXzrUmH1F8eVq164tSWrRooVCQkLUpUsXvfDCC6pUqZKki1OtbNu2Tc2bN8/V/s2ZM0cpKSkup0nJVqdOHe3YsUPr16/XiRMnJEkff/yxPvnkE6e+pUqVcnoMx4wZ4zLorlChgr1vfHy8Tp8+rRdeeOGKX/TZt29fnThxQsnJyRo8eLDGjBmjgQMH5mpfw8PDHWqrWLGi6tevrzlz5qhjx47XVVf2VfdbtmxxuALbZrNp69atqlmzpqT/v6J9y5Yt9qlzsm3ZssXpHxM2m007duxweC5e/reTrXv37hoyZIj27dunypUra8CAAQ6PzRdffCE/Pz/NmzfPYUqbadOmuTxON3KMAQAA8hv+XQ8AAG5bXl5eTvPyzpo1S3v37nVo+9e//qX09HSNHz/eaR25ndfXlY8//tgeJkoXg9D9+/erRYsWkqTo6GiVK1dOb775pk6ePOm0/KFDh5xq9/LyUqtWra643YceekheXl4aPny4U/3GGB0+fNh++8KFC/riiy9Up06dK06R0b59e2VlZenll192uu/ChQv26U+uR0pKir7++mu9/vrrOYbY7du31969ezVlyhSn+86cOaNTp05d83bPnDkjSQ7TP+TkwoULmjRpkv12ZmamJk2apODgYEVHR0uS/er5S4/5ihUrlJKSctX1p6enO9Xy9ddf68yZM05hqitZWVkaMmSIOnXqlOOnA7L5+/urbt26io2NVWxsrNO0Gnkh+9MKrj5RIF18LsycOVOvv/66nn/+eXXo0EEvvviiPQC+Vrl9LK9UV9OmTeXr66t33nnH4RMfM2bMUFpamv15V6tWLYWEhGjixIkO2/vhhx+0efNmJSQkOK370tcWY4zGjx8vb29vp6lEYmJiJF2cKmfkyJGaPn265s+fb7/fy8tLHh4eDtMw7dy50+U/kfL6GAMAALgbV3QDAIDbVqtWrTRixAh169ZN9evX14YNGzRjxgynYK9Lly76+OOPNXDgQK1cuVIxMTE6deqUFi5cqD59+qhNmzbXtf1ixYrpvvvuU7du3ZSWlqYxY8aofPny6tGjh6SLc/e+//77atGihapUqaJu3bqpZMmS2rt3rxYvXqzChQvrm2++0alTpzRhwgS98847uuuuu7RkyRL7NrID8vXr1yslJUX16tVTuXLl9Morr2jw4MHauXOn2rZtq0KFCik1NVVfffWVevbsqf/85z9auHChXnrpJa1fv17ffPPNFfelYcOG6tWrl5KTk7V27VrFxcXJ29tbW7du1axZszR27Fg9/PDD13Wc5s+fr2bNml3xqvZHH31Un3/+uZ544gktXrxYDRo0UFZWlv788099/vnnmjdv3lWvdE9LS7NPDZKenq5JkyapQIECV/3HgfT/wePOnTt11113aebMmVq7dq0mT55s/xRAq1at9OWXX+rBBx9UQkKCUlNTNXHiRFWuXNnhHxkjRozQ3r17VbVqVfn6+mrNmjWaNm2aqlWrpmrVqun06dNKSkrSu+++q/r16ysuLu6q9e3Zs0c+Pj72Lzq92bZs2aK5c+fKZrNp06ZNGjVqlGrXrm3/YthLHTx4UL1791bjxo3tU6OMHz9eixcvVteuXfXLL79cdXqNHTt22B/LvXv3avz48SpcuLBTcHwtdRUrVkwvvvii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tM09e/bIy8tLycnJkqSuXbu6/Dith4eHhg0bZr/9999/q0+fPqpYsaL8/f1VvHhxtWvXTjt37nRYbsmSJfLw8NCSJUvsbb/99puaNWumQoUKqWDBgmrUqJGWLl3qsNyHH34oDw8PrVq1yt6Wnp7uVIcktWrVyqnmpUuXql27drrzzjvl6+ur0qVLa8CAATpz5ozTvs2ePVu1atVSoUKF5OHhYf958803nfq6qjH7JyAgQHfffbfef/99h35du3ZVYGDgFdd1+X7l5nHNdvDgQT322GMKDQ2Vn5+fqlevro8++sihz86dO+379PbbbysiIkL+/v5q2LChNm7c6FTv5cdz+vTp8vT01Ouvv25vW79+vbp27aqyZcvKz89PYWFh6t69uw4fPnzFfQUAK1u7dq3atGmj8PBwzZs3z2XIPWvWLEVHR8vf319BQUH697//rb179zr0yWlsmD17tsO42ahRI4exxtVPNg8PD/Xr108zZsxQxYoV5efnp+joaP38889O2/n999/VokULFS5cWIGBgWratKmWL1/ucp9zquHDDz906FO1atWrHr/sGi/naix/8803Vb9+fRUvXlz+/v6Kjo7W7NmznZY9efKknnnmGZUtW1be3t4ONaanp1+xnsv3LSgoSAkJCU5jY051Z8s+J8g+D/rtt99ks9mUmZmpWrVqyc/PT8WLF1fHjh21a9cup+V//PFHxcTEqGDBgipatKjatGmjzZs3O/QZNmyYPDw89Oeff6p9+/YqXLiwihcvrqeeekpnz551qvfS84oLFy6oZcuWKlasmDZt2mRvnzZtmpo0aaKQkBD5+vqqcuXKeu+99654zAAAF507d05JSUkqX768/T3ns88+q3Pnzjn1nT59uurUqaOAgADdcccduv/++zV//nxJUmRk5BXH+UvHx1OnTumZZ55R6dKl5evrq4oVK+rNN990CuMvXd7Ly0slS5ZUz549dezYMXufzMxMDR06VNHR0SpSpIgKFiyomJgYLV682Kn+7Pecd955p7y8vOzrvtr73Mv3z9PTU2FhYXrkkUccxsNL36/mJHsczLZ8+XL5+flp+/btqlKlinx9fRUWFqZevXrpyJEjTstfy/nZjh07FB8fr4IFC6pEiRIaMWKEwzHOrvfSc6ETJ04oOjpaZcqU0f79++3tuT2fAVxh6hJY2jfffKPIyEjFxMS4vP/+++9XZGSkvvvuO3vb4cOHNXnyZAUGBurJJ59UcHCwpk+froceekgzZsxQx44dFRgYqAcffFAzZ87U6NGjHT5e/d///lfGGHXu3Pmaav3tt9/066+/qkOHDipVqpR27typ9957T40aNdKmTZsUEBDgcrlt27apUaNGCggI0KBBgxQQEKApU6YoNjZWCxYs0P33339NdeRk1qxZOn36tHr37q3ixYtr5cqVGjdunPbs2aNZs2bZ+6WkpKh9+/aqXr26Xn/9dRUpUkTp6ekaMGBArrf19ttvKygoSBkZGZo6dap69OihyMhIxcbGXnf9uXlcJenMmTNq1KiRtm3bpn79+qlMmTKaNWuWunbtqmPHjjn9c+Pjjz/WiRMn1LdvX509e1Zjx45VkyZNtGHDBoWGhrqsZf78+erevbv69evnMI3KggULtGPHDnXr1k1hYWH6448/NHnyZP3xxx9avnx5rue4AwCr2L59u5o3by5fX1/NmzdP4eHhTn2yrwCvXbu2kpOTlZaWprFjx2rZsmX6/fffVbRo0Wva5gsvvKDHH39ckuzjU8+ePXM8V/jpp580c+ZMPfnkk/L19dW7776r5s2ba+XKlfYg+o8//lBMTIwKFy6sZ599Vt7e3po0aZIaNWqkn376SXXr1nVab1RUlF544QWHOv5pY8eOVevWrdW5c2dlZmbqs88+U7t27fTtt98qISHB3m/QoEGaOHGiHnvsMTVo0EDe3t768ssv9dVXX+VqO9n7ZozR9u3bNXr0aLVs2dJlIJ1b2f/07devn6Kjo/X666/r0KFDeuedd/TLL7/o999/V1BQkCRp4cKFatGihcqWLathw4bpzJkzGjdunBo0aKA1a9Y4/QOgffv2ioyMVHJyspYvX6533nlHR48e1ccff5xjPY8//riWLFmiBQsWqHLlyvb29957T1WqVFHr1q1VoEABffPNN+rTp49sNpv69u173fsPALc6m82m1q1b65dfflHPnj1VqVIlbdiwQW+//bb++usvhwuUhg8frmHDhql+/foaMWKEfHx8tGLFCv3444+Ki4vTmDFjdPLkSUnS5s2b9dprr2nIkCH2KVKyw2RjjFq3bq3FixfrscceU40aNTRv3jwNGjRIe/fu1dtvv+1Q44MPPqiHHnpIFy5cUEpKiiZPnqwzZ87Yp2LJyMjQ+++/r44d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uXPtU5e8+uqrioiIUM2aNZ2upC9QoIDeeOMNdenSRTExMercubN9WpRSpUrpueees/cdNWqUWrRooXr16umxxx7TmTNnNG7cOBUpUkTDhg1zqjc1NVWtW7dW8+bNlZKSounTp6tTp06qXr16jvsYHx+vf//733r22Wf1wAMPKDw8XHFxcfLx8dEDDzygXr166eTJk5oyZYpCQkK0f//+az6OAHA7efTRR/X555/riSee0OLFi9WgQQNlZWXpzz//1Oeff6558+apVq1aKl++vF544QW9/PLLiomJ0UMPPSRfX1/99ttvKlGihJKTk3O9zQceeECNGzfWCy+8oJ07d6p69eqaP3++vv76az399NMOOYF0cdrT6dOnyxij7du328egWrVqSbr4nv7LL7/Ugw8+qISEBKWmpmrixImqXLmyTp486bCuvn376syZMy7n1c6NHTt22MfavXv3avz48SpcuLBTcLxlyxbNnTvXfhX8qFGjVLt2bZUsWdJpncWKFdOLL76ol156SfHx8WrTpo127Nih8ePHq3r16nr88ccl6ZrPz/z8/DR37lwlJiaqbt26+uGHH/Tdd99pyJAh9k/HudKzZ099+umneuKJJ7Rx40b7HOO5PZ8BXDLALWD9+vWmY8eOJjw83Hh7e5uwsDDTsWNHs2HDBpf9t2/fbh5++GFTpEgR4+fnZ2rXrm3mzJmT4/pbtmxpJJlff/011zVJMklJSfbbR48eNd26dTNBQUEmMDDQxMfHmz///NNERESYxMREe7/FixcbSWbx4sX2ttWrV5u4uDgTGBhoAgICzP33329++uknh+1NmzbNSLrmn2ybNm0ysbGxJjAw0AQFBZkePXqYdevWGUlm2rRpxhhjzp49a6pVq2buu+8+c+HCBfuyqampRpIZNWrUFY/J5TX6+PiY8uXLm6FDh5qzZ8/a+yUmJjr0CwwMNPfcc4/55JNPcjy+xuT+cU1LS7M/Fj4+Pubuu++276OrfXrrrbdM6dKlja+vr4mJiTHr1q1z6JuYmGgiIiKcttOtWzdTuHBhs2fPHmOMMXv27DEPPvigKVq0qClSpIhp166d2bdvn8t9AQCryn6t/+2331ze36ZNGxMQEGB27Nhhb5s5c6apWbOm8fX1NcWKFTOdO3e2v3ZmS0xMNAULFnRa36xZs5zGzWzZr+WXv8Znk2T69u1r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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ros = RandomOverSampler(random_state=42)\n", + "\n", + "# Применение RandomOverSampler для балансировки выборок\n", + "X_train_resampled, y_train_resampled = ros.fit_resample(X_train, y_train)\n", + "X_val_resampled, y_val_resampled = ros.fit_resample(X_val, y_val)\n", + "\n", + "# Проверка сбалансированности после RandomOverSampler\n", + "analyze_balance(y_train_resampled, y_val_resampled, y_test, 'stroke')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Выборки сбалансированы.\n", + "\n", + "### Перейдем к конструированию признаков\n", + "\n", + "Для начала применим унитарное кодирование категориальных признаков (one-hot encoding), переведя их в бинарные вектора:" + ] + }, + { + "cell_type": "code", + "execution_count": 447, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " id age hypertension heart_disease avg_glucose_level bmi \\\n", + "0 16605 57.0 0 0 106.24 32.3 \n", + "1 12015 14.0 0 0 99.87 25.2 \n", + "2 26474 44.0 0 0 97.16 33.1 \n", + "3 31143 22.0 0 0 107.52 41.6 \n", + "4 2447 63.0 0 0 85.04 29.7 \n", + "\n", + " gender_Male gender_Other ever_married_Yes work_type_Never_worked \\\n", + "0 True False True False \n", + "1 True False False False \n", + "2 False False True False \n", + "3 False False False False \n", + "4 False False True False \n", + "\n", + " work_type_Private work_type_Self-employed work_type_children \\\n", + "0 True False False \n", + "1 False False True \n", + "2 False False False \n", + "3 True False False \n", + "4 True False False \n", + "\n", + " Residence_type_Urban smoking_status_formerly smoked \\\n", + "0 True False \n", + "1 True False \n", + "2 True False \n", + "3 False False \n", + "4 True True \n", + "\n", + " smoking_status_never smoked smoking_status_smokes \n", + "0 True False \n", + "1 False False \n", + "2 False False \n", + "3 False False \n", + "4 False False \n" + ] + } + ], + "source": [ + "# Определение категориальных признаков\n", + "categorical_features = ['gender', 'ever_married', 'work_type', 'Residence_type', 'smoking_status']\n", + "\n", + "# Применение one-hot encoding к обучающей выборке\n", + "X_train_encoded = pd.get_dummies(X_train_resampled, columns=categorical_features, drop_first=True)\n", + "\n", + "# Применение one-hot encoding к контрольной выборке\n", + "X_val_encoded = pd.get_dummies(X_val_resampled, columns=categorical_features, drop_first=True)\n", + "\n", + "# Применение one-hot encoding к тестовой выборке\n", + "X_test_encoded = pd.get_dummies(X_test, columns=categorical_features, drop_first=True)\n", + "\n", + "print(X_train_encoded.head())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Далее к числовым признакам, а именно к колонке age, применим дискретизацию (позволяет преобразовать данные из числового представления в категориальное):" + ] + }, + { + "cell_type": "code", + "execution_count": 448, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " id hypertension heart_disease avg_glucose_level bmi gender_Male \\\n", + "0 16605 0 0 106.24 32.3 True \n", + "1 12015 0 0 99.87 25.2 True \n", + "2 26474 0 0 97.16 33.1 False \n", + "3 31143 0 0 107.52 41.6 False \n", + "4 2447 0 0 85.04 29.7 False \n", + "\n", + " gender_Other ever_married_Yes work_type_Never_worked work_type_Private \\\n", + "0 False True False True \n", + "1 False False False False \n", + "2 False True False False \n", + "3 False False False True \n", + "4 False True False True \n", + "\n", + " work_type_Self-employed work_type_children Residence_type_Urban \\\n", + "0 False False True \n", + "1 False True True \n", + "2 False False True \n", + "3 False False False \n", + "4 False False True \n", + "\n", + " smoking_status_formerly smoked smoking_status_never smoked \\\n", + "0 False True \n", + "1 False False \n", + "2 False False \n", + "3 False False \n", + "4 True False \n", + "\n", + " smoking_status_smokes age_bin \n", + "0 False old \n", + "1 False young \n", + "2 False middle-aged \n", + "3 False young \n", + "4 False old \n" + ] + } + ], + "source": [ + "# Определение числовых признаков для дискретизации\n", + "numerical_features = ['age']\n", + "\n", + "# Функция для дискретизации числовых признаков\n", + "def discretize_features(df, features, bins, labels):\n", + " for feature in features:\n", + " df[f'{feature}_bin'] = pd.cut(df[feature], bins=bins, labels=labels)\n", + " df.drop(columns=[feature], inplace=True)\n", + " return df\n", + "\n", + "# Заданные интервалы и метки\n", + "age_bins = [0, 25, 55, 100]\n", + "age_labels = [\"young\", \"middle-aged\", \"old\"]\n", + "\n", + "# Применение дискретизации к обучающей, контрольной и тестовой выборкам\n", + "X_train_encoded = discretize_features(X_train_encoded, numerical_features, bins=age_bins, labels=age_labels)\n", + "X_val_encoded = discretize_features(X_val_encoded, numerical_features, bins=age_bins, labels=age_labels)\n", + "X_test_encoded = discretize_features(X_test_encoded, numerical_features, bins=age_bins, labels=age_labels)\n", + "\n", + "print(X_train_encoded.head())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Применим ручной синтез признаков. Это создание новых признаков на основе существующих, учитывая экспертные знания и логику предметной области. К примеру, в этом случае можно создать признак, в котором вычисляется насколько уровень глюкозы отклоняется от среднего для возрастной группы пациента. Такой признак может быть полезен для выделения пациентов с нетипичными данными." + ] + }, + { + "cell_type": "code", + "execution_count": 449, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " id hypertension heart_disease avg_glucose_level bmi gender_Male \\\n", + "0 16605 0 0 106.24 32.3 True \n", + "1 12015 0 0 99.87 25.2 True \n", + "2 26474 0 0 97.16 33.1 False \n", + "3 31143 0 0 107.52 41.6 False \n", + "4 2447 0 0 85.04 29.7 False \n", + "\n", + " gender_Other ever_married_Yes work_type_Never_worked work_type_Private \\\n", + "0 False True False True \n", + "1 False False False False \n", + "2 False True False False \n", + "3 False False False True \n", + "4 False True False True \n", + "\n", + " work_type_Self-employed work_type_children Residence_type_Urban \\\n", + "0 False False True \n", + "1 False True True \n", + "2 False False True \n", + "3 False False False \n", + "4 False False True \n", + "\n", + " smoking_status_formerly smoked smoking_status_never smoked \\\n", + "0 False True \n", + "1 False False \n", + "2 False False \n", + "3 False False \n", + "4 True False \n", + "\n", + " smoking_status_smokes age_bin glucose_age_deviation \n", + "0 False old -27.642870 \n", + "1 False young 6.088032 \n", + "2 False middle-aged -6.217053 \n", + "3 False young 13.738032 \n", + "4 False old -48.842870 \n" + ] + } + ], + "source": [ + "age_glucose_mean = X_train_encoded.groupby('age_bin', observed=False)['avg_glucose_level'].transform('mean')\n", + "X_train_encoded['glucose_age_deviation'] = X_train_encoded['avg_glucose_level'] - age_glucose_mean\n", + "\n", + "age_glucose_mean = X_val_encoded.groupby('age_bin', observed=False)['avg_glucose_level'].transform('mean')\n", + "X_val_encoded['glucose_age_deviation'] = X_val_encoded['avg_glucose_level'] - age_glucose_mean\n", + "\n", + "age_glucose_mean = X_test_encoded.groupby('age_bin', observed=False)['avg_glucose_level'].transform('mean')\n", + "X_test_encoded['glucose_age_deviation'] = X_test_encoded['avg_glucose_level'] - age_glucose_mean\n", + "\n", + "print(X_train_encoded.head())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Теперь используем масштабирование признаков, что позволяет привести все числовые признаки к одинаковым или очень похожим диапазонам значений либо распределениям. По результатам многочисленных исследований масштабирование признаков позволяет получить более качественную модель за счет снижения доминирования одних признаков над другими." + ] + }, + { + "cell_type": "code", + "execution_count": 450, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " id hypertension heart_disease avg_glucose_level bmi \\\n", + "0 16605 0 0 -0.244097 0.426328 \n", + "1 12015 0 0 -0.360110 -0.596170 \n", + "2 26474 0 0 -0.409465 0.541539 \n", + "3 31143 0 0 -0.220785 1.765656 \n", + "4 2447 0 0 -0.630199 0.051892 \n", + "\n", + " gender_Male gender_Other ever_married_Yes work_type_Never_worked \\\n", + "0 True False True False \n", + "1 True False False False \n", + "2 False False True False \n", + "3 False False False False \n", + "4 False False True False \n", + "\n", + " work_type_Private work_type_Self-employed work_type_children \\\n", + "0 True False False \n", + "1 False False True \n", + "2 False False False \n", + "3 True False False \n", + "4 True False False \n", + "\n", + " Residence_type_Urban smoking_status_formerly smoked \\\n", + "0 True False \n", + "1 True False \n", + "2 True False \n", + "3 False False \n", + "4 True True \n", + "\n", + " smoking_status_never smoked smoking_status_smokes age_bin \\\n", + "0 True False old \n", + "1 False False young \n", + "2 False False middle-aged \n", + "3 False False young \n", + "4 False False old \n", + "\n", + " glucose_age_deviation \n", + "0 -0.528807 \n", + "1 0.116464 \n", + "2 -0.118932 \n", + "3 0.262808 \n", + "4 -0.934362 \n" + ] + } + ], + "source": [ + "# Пример масштабирования числовых признаков\n", + "numerical_features = ['avg_glucose_level', 'bmi', 'glucose_age_deviation']\n", + "\n", + "scaler = StandardScaler()\n", + "X_train_encoded[numerical_features] = scaler.fit_transform(X_train_encoded[numerical_features])\n", + "X_val_encoded[numerical_features] = scaler.transform(X_val_encoded[numerical_features])\n", + "X_test_encoded[numerical_features] = scaler.transform(X_test_encoded[numerical_features])\n", + "\n", + "print(X_train_encoded.head())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "И также попробуем сконструировать признаки, используя фреймворк Featuretools:" + ] + }, + { + "cell_type": "code", + "execution_count": 451, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " id hypertension heart_disease avg_glucose_level bmi \\\n", + "index \n", + "0 16605 0 0 -0.244097 0.426328 \n", + "1 12015 0 0 -0.360110 -0.596170 \n", + "2 26474 0 0 -0.409465 0.541539 \n", + "3 31143 0 0 -0.220785 1.765656 \n", + "4 2447 0 0 -0.630199 0.051892 \n", + "\n", + " gender_Male gender_Other ever_married_Yes work_type_Never_worked \\\n", + "index \n", + "0 True False True False \n", + "1 True False False False \n", + "2 False False True False \n", + "3 False False False False \n", + "4 False False True False \n", + "\n", + " work_type_Private work_type_Self-employed work_type_children \\\n", + "index \n", + "0 True False False \n", + "1 False False True \n", + "2 False False False \n", + "3 True False False \n", + "4 True False False \n", + "\n", + " Residence_type_Urban smoking_status_formerly smoked \\\n", + "index \n", + "0 True False \n", + "1 True False \n", + "2 True False \n", + "3 False False \n", + "4 True True \n", + "\n", + " smoking_status_never smoked smoking_status_smokes age_bin \\\n", + "index \n", + "0 True False old \n", + "1 False False young \n", + "2 False False middle-aged \n", + "3 False False young \n", + "4 False False old \n", + "\n", + " glucose_age_deviation \n", + "index \n", + "0 -0.528807 \n", + "1 0.116464 \n", + "2 -0.118932 \n", + "3 0.262808 \n", + "4 -0.934362 \n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Users\\Ilya\\Desktop\\AIM\\aimenv\\Lib\\site-packages\\woodwork\\type_sys\\utils.py:33: UserWarning: Could not infer format, so each element will be parsed individually, falling back to `dateutil`. To ensure parsing is consistent and as-expected, please specify a format.\n", + " pd.to_datetime(\n" + ] + } + ], + "source": [ + "data = X_train_encoded.copy() # Используем предобработанные данные\n", + "\n", + "es = ft.EntitySet(id=\"patients\")\n", + "\n", + "es = es.add_dataframe(dataframe_name=\"strokes_data\", dataframe=data, index=\"index\", make_index=True)\n", + "\n", + "feature_matrix, feature_defs = ft.dfs(\n", + " entityset=es, \n", + " target_dataframe_name=\"strokes_data\",\n", + " max_depth=1\n", + ")\n", + "\n", + "print(feature_matrix.head())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Оценим качество набора признаков.\n", + "\n", + "Представим основные оценки качества наборов признаков: \n", + "\n", + "* Предсказательная способность Метрики: RMSE, MAE, R²\n", + "\n", + " Методы: Обучение модели на обучающей выборке и оценка на контрольной и тестовой выборках.\n", + "\n", + "* Скорость вычисления \n", + "\n", + " Методы: Измерение времени выполнения генерации признаков и обучения модели.\n", + "\n", + "* Надежность \n", + "\n", + " Методы: Кросс-валидация, анализ чувствительности модели к изменениям в данных.\n", + "\n", + "* Корреляция \n", + "\n", + " Методы: Анализ корреляционной матрицы признаков, удаление мультиколлинеарных признаков.\n", + "\n", + "* Цельность \n", + "\n", + " Методы: Проверка логической связи между признаками и целевой переменной, интерпретация результатов модели." + ] + }, + { + "cell_type": "code", + "execution_count": 452, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Время обучения модели: 0.01 секунд\n", + "Среднеквадратичная ошибка: 0.41\n" + ] + } + ], + "source": [ + "X_train_encoded = pd.get_dummies(X_train_encoded, drop_first=True)\n", + "X_val_encoded = pd.get_dummies(X_val_encoded, drop_first=True)\n", + "X_test_encoded = pd.get_dummies(X_test_encoded, drop_first=True)\n", + "\n", + "all_columns = X_train_encoded.columns\n", + "X_train_encoded = X_train_encoded.reindex(columns=all_columns, fill_value=0)\n", + "X_val_encoded = X_val_encoded.reindex(columns=all_columns, fill_value=0)\n", + "X_test_encoded = X_test_encoded.reindex(columns=all_columns, fill_value=0)\n", + "\n", + "# Обучение модели\n", + "model = LinearRegression()\n", + "\n", + "# Начинаем отсчет времени\n", + "start_time = time.time()\n", + "model.fit(X_train_encoded, y_train_resampled)\n", + "\n", + "# Время обучения модели\n", + "train_time = time.time() - start_time\n", + "\n", + "# Предсказания и оценка модели и вычисляем среднеквадратичную ошибку\n", + "predictions = model.predict(X_val_encoded)\n", + "mse = root_mean_squared_error(y_val_resampled, predictions)\n", + "\n", + "print(f'Время обучения модели: {train_time:.2f} секунд')\n", + "print(f'Среднеквадратичная ошибка: {mse:.2f}')" + ] + }, + { + "cell_type": "code", + "execution_count": 453, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RMSE: 0.24109840514907446\n", + "R²: -0.06295721700021817\n", + "MAE: 0.10402478799739073 \n", + "\n", + "Кросс-валидация RMSE: 0.1197518340742331 \n", + "\n", + "Train RMSE: 0.037396456827854585\n", + "Train R²: 0.9944060200668896\n", + "Train MAE: 0.010727424749163881\n", + "\n" + ] + } + ], + "source": [ + "# Выбор модели\n", + "model = RandomForestRegressor(random_state=42)\n", + "\n", + "# Обучение модели\n", + "model.fit(X_train_encoded, y_train_resampled)\n", + "\n", + "# Предсказание и оценка\n", + "y_pred = model.predict(X_test_encoded)\n", + "\n", + "rmse = root_mean_squared_error(y_test, y_pred)\n", + "r2 = r2_score(y_test, y_pred)\n", + "mae = mean_absolute_error(y_test, y_pred)\n", + "\n", + "print()\n", + "print(f\"RMSE: {rmse}\")\n", + "print(f\"R²: {r2}\")\n", + "print(f\"MAE: {mae} \\n\")\n", + "\n", + "# Кросс-валидация\n", + "scores = cross_val_score(model, X_train_encoded, y_train_resampled, cv=5, scoring='neg_mean_squared_error')\n", + "rmse_cv = (-scores.mean())**0.5\n", + "print(f\"Кросс-валидация RMSE: {rmse_cv} \\n\")\n", + "\n", + "# Проверка на переобучение\n", + "y_train_pred = model.predict(X_train_encoded)\n", + "\n", + "rmse_train = root_mean_squared_error(y_train_resampled, y_train_pred)\n", + "r2_train = r2_score(y_train_resampled, y_train_pred)\n", + "mae_train = mean_absolute_error(y_train_resampled, y_train_pred)\n", + "\n", + "print(f\"Train RMSE: {rmse_train}\")\n", + "print(f\"Train R²: {r2_train}\")\n", + "print(f\"Train MAE: {mae_train}\")\n", + "print()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Можно заметить, что модель хорошо подстроилась под тренировочные данные (Низкий Train RMSE и высокое значение Train R²). Однако высокий RMSE и отрицательный R² на тестовом наборе свидетельствуют о том, что модель не обобщила зависимости и плохо предсказывает новые данные, поэтому можно сделать вывод о том, что получившийся набор признаков, к сожалению, далек от идеала. " + ] + } + ], + "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 +} diff --git a/lab_3/requirements.txt b/lab_3/requirements.txt new file mode 100644 index 0000000..035855b Binary files /dev/null and b/lab_3/requirements.txt differ