{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Набор данных для анализа и прогнозирования сердечного приступа" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Вывод всех столбцов" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Index(['HeartDisease', 'BMI', 'Smoking', 'AlcoholDrinking', 'Stroke',\n", " 'PhysicalHealth', 'MentalHealth', 'DiffWalking', 'Sex', 'AgeCategory',\n", " 'Race', 'Diabetic', 'PhysicalActivity', 'GenHealth', 'SleepTime',\n", " 'Asthma', 'KidneyDisease', 'SkinCancer'],\n", " dtype='object')\n" ] } ], "source": [ "import pandas as pd \n", "df = pd.read_csv(\"..//static//csv//heart_2020_cleaned.csv\")\n", "print(df.columns)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Бизнес-цели: \n", "1. Разработка персонализированных программ профилактики сердечно-сосудистых заболеваний.\n", "Цель технического проекта: создание модели машинного обучения, которая будет прогнозировать риск сердечного приступа для каждого пациента на основе его индивидуальных факторов риска, и разработка онлайн-платформы или приложения для предоставления персонализированных рекомендаций по профилактике.\n", "2. Улучшение качества медицинской \n", "Цель технического проекта: использование данных для выявления групп населения с наибольшим риском сердечного приступа и разработки целевых программ профилактики и раннего выявления заболеваний." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Выполним разбиение на 3 выборки: обучающую, контрольную и тестовую" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Размер обучающей выборки: 156699\n", "Размер контрольной выборки: 67157\n", "Размер тестовой выборки: 95939\n" ] } ], "source": [ "import pandas as pd\n", "from sklearn.model_selection import train_test_split\n", "\n", "df = pd.read_csv(\"..//static//csv//heart_2020_cleaned.csv\")\n", "\n", "# Разделение на обучающую и тестовую выборки (например, 70% обучающая, 30% тестовая)\n", "train_df, test_df = train_test_split(df, test_size=0.3, random_state=42)\n", "\n", "# Разделение обучающей выборки на обучающую и контрольную (например, 70% обучающая, 30% контрольная)\n", "train_df, val_df = train_test_split(train_df, test_size=0.3, random_state=42)\n", "\n", "# Вывод размеров выборок\n", "print(\"Размер обучающей выборки:\", len(train_df))\n", "print(\"Размер контрольной выборки:\", len(val_df))\n", "print(\"Размер тестовой выборки:\", len(test_df))" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Распределение классов в HeartDisease:\n", "HeartDisease\n", "No 292422\n", "Yes 27373\n", "Name: count, dtype: int64\n" ] }, { "data": { "image/png": "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z18xSOaNaxiGqlWrppo1a1513F9++UU2m63AoyAXj/n999+refPmhfrQ8vb2zrdNV7qYfPjw4WrYsKG6du162fVv375djzzyyHWfks079err66slS5bo1VdfVYcOHfIFwsLsj6+++kpubm5asWKFw2nC2bNn5+s7NzdXv/zyy2WDc97rYNeuXapRo0aBNVWqVJEk7du3z+F+SXnT8ubncXNzc9j/TzzxhMqVK6fp06fr/fffv+x23eiy16Kwr6m1a9fqxIkT+vrrrxUSEmJOz/uWb2Fd7+vmyy+/1NmzZxUWFnbV2gcffFAPPvigxo8fr3nz5qlHjx764osv1K9fv5u2vYGBgQoMDNSIESO0efNmNW/eXLNmzdK4ceOu+b0A1uKaKtxRnJ2dZRiGw7SFCxfm+wp6586ddfz4cYevTOe5dPlr8cknnzhch/Hll1/q6NGjat++vSQpKChI1atX13//+1+dOXMm3/KX3sl54cKFcnZ2vupdqTt16iRnZ2eNHj06X/+GYejEiRPm8wsXLuirr75S06ZNr/i/1i5duignJ0djx47NN+/ChQvmKbPrER8fryVLluitt9667Adfly5d9Oeff+rDDz/MN+/s2bPKzMy86npq1qxpXtczbdo05ebm6pVXXnGoKez+cHZ2ls1mczilfPDgwXzBsWPHjnJyctKYMWPyHVHJ+9m0bdtWZcqUUXR0dL7rzvJqGjduLB8fH82aNcvhVOPy5cu1Z88eh28bFiQ7O1sXLlwo1O0nrFz2Sgr7mso7wnLxazk7O1szZ868pvWVLl36ml+n27dv16BBg1S2bFlFRERctu7UqVP5ftfyQnTefrN6ezMyMnThwgWHaYGBgXJycjLXeS3vBbAeR6pwR3nsscc0ZswY9e7dWw899JB27typuXPn6t5773Woe+655/TJJ58oMjJSW7duVYsWLZSZmanvv/9e//rXv/SPf/zjutZfrlw5Pfzww+rdu7dSUlI0ZcoU1ahRQ88//7wkycnJSR999JHat2+vevXqqXfv3rrnnnv0559/as2aNbLb7fr222+VmZmpGTNm6N1331XNmjW1du1acx15YWzHjh2Kj49XcHCwqlevrnHjxmn48OE6ePCgOnbsqDJlyigpKUmLFi1S//799dprr+n777/Xm2++qR07dujbb7+94ra0bNlSL7zwgqKjo5WYmKi2bduqZMmS2r9/vxYuXKipU6fmu3FiYa1cuVKPPvroFY/WPfvss1qwYIFefPFFrVmzRs2bN1dOTo727t2rBQsWaMWKFVc9gncxPz8/TZgwQf369dM///lPdejQ4Zr2R3h4uCZNmqR27drpmWee0bFjxzRjxgzVqFFDO3bsMOtq1KihN954Q2PHjlWLFi3UqVMnubq66scff5S/v7+io6Nlt9s1efJk9evXT02aNNEzzzyjsmXLavv27frrr780Z84clSxZUm+//bZ69+6tli1bqnv37uYtFapWrarBgwc79JeZmelwCu/TTz/VuXPn9OSTT15139zIsteisK+phx56SGXLllXPnj318ssvy2az6dNPP73m//AEBQXpvffe07hx41SjRg35+Pg4HPXbsGGDzp07Z36pZdOmTfrmm2/k6empRYsWXfF08Jw5czRz5kw9+eSTql69uk6fPq0PP/xQdrvdvAWL1du7evVqDRgwQE8//bRq1qypCxcu6NNPP5Wzs7M6d+4sSYV+L8BNcqu/bghcj7yvM1/p68uG8fctFV599VWjYsWKhru7u9G8eXMjPj7e4ev1ef766y/jjTfeMKpVq2aULFnS8PPzM5566injwIEDhmFc3y0VPv/8c2P48OGGj4+P4e7uboSHhxv/+9//8i3/888/G506dTLKly9vuLq6GlWqVDG6dOlixMXFOaz7ao+ePXs6jPvVV18ZDz/8sFG6dGmjdOnSRu3atY2IiAhj3759hmEYxsCBA42QkBAjNjY2X08F3ULAMP7+en1QUJDh7u5ulClTxggMDDSGDh1qHDlyxKy51lsq2Gw2IyEhwWF6QT+j7Oxs4+233zbq1atnuLq6GmXLljWCgoKM0aNHG+np6fnWd7XxDMMw2rRpY1SuXNk4ffr0Ne+P//u//zPuu+8+w9XV1ahdu7Yxe/bsy+63jz/+2HjggQfMvlu2bGmsWrXKoeabb74xHnroIcPd3d2w2+1G06ZNjc8//9yhZv78+eY45cqVM3r06GHeQiRPz549HV4XHh4eRqNGjYxPP/30ivvoRpfN2/bU1NQC51/udVGY19SmTZuMBx980HB3dzf8/f2NoUOHGitWrDAkGWvWrDHrWrZsadSrV6/A9ScnJxvh4eFGmTJlDEnm6yHv9zXvUbJkSaNChQpGSEiIMX78eOPYsWP5xrr0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eHi4srOztXnzZs2ZM0cxMTGKiooya5KSkhQeHq7WrVsrMTFRgwYNUr9+/bRixQqzZv78+YqMjNTIkSP1008/qUGDBgoLC9OxY8cK3QsAALh72QzDMIq6iTypqany8fHRunXrFBISovT0dFWoUEHz5s3TU089JUnau3ev6tSpo/j4eD344INavny5HnvsMR05ckS+vr6SpFmzZmnYsGFKTU2Vi4uLhg0bpmXLlmnXrl3murp166a0tDTFxsZKkpo1a6YmTZpo+vTpkqTc3FwFBARo4MCBev311wvVy9VkZGTI09NT6enpstvtlu67iwUN+eSmjQ0UVwkTnivqFgAUU4X9/L6trqlKT0+XJJUrV06SlJCQoPPnzys0NNSsqV27tipXrqz4+HhJUnx8vAIDA81AJUlhYWHKyMjQ7t27zZqLx8iryRsjOztbCQkJDjVOTk4KDQ01awrTy6WysrKUkZHh8AAAAHem2yZU5ebmatCgQWrevLnq168vSUpOTpaLi4u8vLwcan19fZWcnGzWXByo8ubnzbtSTUZGhs6ePavjx48rJyenwJqLx7haL5eKjo6Wp6en+QgICCjk3gAAAMXNbROqIiIitGvXLn3xxRdF3Yplhg8frvT0dPNx+PDhom4JAADcJCWKugFJGjBggJYuXar169erUqVK5nQ/Pz9lZ2crLS3N4QhRSkqK/Pz8zJpLv6WX9428i2su/ZZeSkqK7Ha73N3d5ezsLGdn5wJrLh7jar1cytXVVa6urtewJwAAQHFVpEeqDMPQgAEDtGjRIq1evVrVqlVzmB8UFKSSJUsqLi7OnLZv3z4dOnRIwcHBkqTg4GDt3LnT4Vt6q1atkt1uV926dc2ai8fIq8kbw8XFRUFBQQ41ubm5iouLM2sK0wsAALh7FemRqoiICM2bN09LlixRmTJlzGuTPD095e7uLk9PT/Xt21eRkZEqV66c7Ha7Bg4cqODgYPPbdm3btlXdunX17LPP6p133lFycrJGjBihiIgI8yjRiy++qOnTp2vo0KHq06ePVq9erQULFmjZsmVmL5GRkerZs6caN26spk2basqUKcrMzFTv3r3Nnq7WCwAAuHsVaah67733JEmtWrVymD579mz16tVLkjR58mQ5OTmpc+fOysrKUlhYmGbOnGnWOjs7a+nSpXrppZcUHBys0qVLq2fPnhozZoxZ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9dcLvT0ZGRny9PRUenq67Hb79e6Wqwoa8slNGxsorhImPFfULQAopgr7+X3bH6nav3+//P39de+996pHjx46dOiQJCkhIUHnz59XaGioWVu7dm1VrlxZ8fHxkqT4+HgFBgaagUqSwsLClJGRod27d5s1F4+RV5M3RnZ2thISEhxqnJycFBoaatYAAACUKOoGrqRZs2aKiYlRrVq1dPToUY0ePVotWrTQrl27lJycLBcXF3l5eTks4+vrq+TkZElScnKyQ6DKm58370o1GRkZOnv2rE6dOqWcnJwCa/bu3XvF/rOyspSVlWU+z8jIKPzGAwCAYuW2DlXt27c3/33//ferWbNmqlKlihYsWCB3d/ci7KxwoqOjNXr06KJuAwAA3AK3/em/i3l5ealmzZr67bff5Ofnp+zsbKWlpTnUpKSkyM/PT5Lk5+eX79uAec+vVmO32+Xu7i5vb285OzsXWJM3xuUMHz5c6enp5uPw4cPXvM0AAKB4KFah6syZMzpw4IAqVqyooKAglSxZUnFxceb8ffv26dChQwoODpYkBQcHa+fOnQ7f0lu1apXsdrvq1q1r1lw8Rl5N3hguLi4KCgpyqMnNzVVcXJxZczmurq6y2+0ODwAAcGe6rUPVa6+9pnXr1ungwYPavHmznnzySTk7O6t79+7y9PRU3759FRkZqTVr1ighIUG9e/dWcHCwHnzwQUlS27ZtVbduXT377LPavn27VqxYoREjRigiIkKurq6SpBdffFG///67hg4dqr1792rmzJlasGCBBg8ebPYRGRmpDz/8UHPmzNGePXv00ksvKTMzU7179y6S/QIAAG4/t/U1VX/88Ye6d++uEydOqEKFCnr44Yf1ww8/qEKFCpKkyZMny8nJSZ07d1ZWVpbCwsI0c+ZMc3lnZ2ctXbpUL730koKDg1W6dGn17NlTY8aMMWuqVaumZcuWafDgwZo6daoqVaqkjz76SGFhYWZN165dlZqaqqioKCUnJ6thw4aKjY3Nd/E6AAC4e93W96m603CfKqDocJ8qANfrjrlPFQAAQHFAqAIAALAAoQoAAMAChCoAAAALEKoAAAAsQKgCAACwAKEKAADAAoQqAAAACxCqAAAALECoAgAAsAChCgAAwAKEKgAAAAsQqgAAACxAqAIAALAAoQoAAMAChCoAAAALEKoAAAAsQKgCAACwAKEK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LyUmJqpWrVp6+eWXtXLlSofxz5w5o/LlyzusIykpyeEUIoAbU6KoGwCAyyldurRq1KjhMO2PP/4w/33mzBm98MILevnll/MtW7lyZWVmZiosLExhYWGaO3euKlSooEOHDiksLEzZ2dn51nUjTpw4odTUVFWrVq3A+f369VNYWJiWLVumlStXKjo6WhMnTtTAgQN15swZPf7443r77bfzLVexYkVJ0uOPP64qVaroww8/lL+/v3Jzc1W/fn1zOxo1aqSkpCQtX75c33//vbp06aLQ0FB9+eWXOnPmjCpWrKi1a9fmG9/Ly+uGthvA/0eoAlBsNWrUSL/88ku+4JVn586dOnHihN566y0FBARIkrZt21aosV1cXJSTk1PoXqZOnSonJ6cCbwORJyAgQC+++KJefPFFDR8+XB9++KEGDhyoRo0a6auvvlLVqlVVokT+t+UTJ05o3759+vDDD9WiRQtJf1+gfym73a6uXbuqa9eueuqpp9SuXTudPHlSjRo1UnJyskqUKOFwnRUAa3H6D0CxNWzYMG3evFkDBgxQYmKi9u/fryVLlpgXqleuXFkuLi6aNm2afv/9d33zzTcaO3ZsocauWrWqkpKSlJiYqOPHjysrK8ucd/r0aSUnJ+vw4cNav369+vfvr3Hjxmn8+PGXDXiDBg3SihUrlJSUpJ9++klr1qxRnTp1JP19EfvJkyfVvXt3/fjjjzpw4IBWrFih3r17KycnR2XLllX58uX1wQcf6LffftPq1asVGRnpMP6kSZP0+eefa+/evfr111+1cOFC+fn5mbd7CA4OVseOHbVy5UodPHhQmzdv1htvvFHokAng6ghVAIqt+++/X+vWrdOvv/6qFi1a6IEHHlBUVJT8/f0lSRUqVFBMTIwWLlyounXr6q233tJ///vfQo3duXNntWvXTq1bt1aFChX0+eefm/OioqJUsWJF1ahRQ88++6zS09MVFxenYcOGXXa8nJwcRUREqE6dOmrXrp1q1qypmTNnSpL8/f21adMm5eTkqG3btgoMDNSgQYPk5eUlJycnOTk56YsvvlBCQoLq16+vwYMHa8KECQ7jlylTRu+8844aN26sJk2a6ODBg/ruu+/k5OQkm82m7777TiEhIerdu7dq1qypbt266X//+598fX2vdbcDuAybYRhGUTcBAABQ3HGkCgAAwAKEKgAAAAsQqgAAACxAqAIAALAAoQoAAMAChCoAAAALEKoAAAAsQKgCAACwAKEKAADAAoQqAAAACxCqAAAALECoAgAAsMD/A8EDBhsbeGvMAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Распределение классов в Обучающей выборке:\n", "HeartDisease\n", "No 143331\n", "Yes 13368\n", "Name: count, dtype: int64\n" ] }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Распределение классов в Контрольной выборке:\n", "HeartDisease\n", "No 61442\n", "Yes 5715\n", "Name: count, dtype: int64\n" ] }, { "data": { "image/png": "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BQVOdxZZ3R8eHh5yc3NzOOV78OBBp2DYuXNnubu7a+zYsU5HN+3fm3bt2ql06dIaP36803Vf9pomTZqoYsWKmjlzpsOpwKVLl2rPnj0Od+sVJi8vTxcuXLD0eIbruax08Qijm5ub/vOf/5jTIiIi5OnpqalTpzr8jH7wwQfKysr6w+25HhYuXOjwWbBlyxZt3rzZfH9WqlRJjRo10uzZsx1+vnft2qXly5c73UX72WefydPT0zzKdi3sPxuFHRn+Ix07dlRaWprmzp1rTrtw4YKmTZsmX19ftW7d2qnPHTt2FHqXalGcPXtWkhweO1CYgoKCK25fx44dlZ+f7/QZbD+ybP95sO/zy+9Uu7zO7siRIw531GVnZ+ujjz5So0aNnI4I2u+UjYqKUo8ePTRs2DCHvzDRrVs3JSUladmyZU79Z2ZmXvXatOKOI02QJHXq1Eljx45V3759ddddd2nnzp365JNPHH6zlS5esP3RRx8pJiZGW7ZsUcuWLZWTk6OVK1fqP//5j/71r38Vaf1ly5bV3Xffrb59+yo9PV1TpkxRaGioeXjd3d1d77//vjp06KC6deuqb9++uvXWW/Xbb79pzZo1stls+vrrr5WTk6O33npLU6dOVY0aNRye+WIPWzt27FBSUpLCw8N1++236+WXXzZv1+3cubNKly6t1NRUffnllxowYICee+45rVy5Ui+99JJ27Nihr7/++qrb0rp1az355JMaP368UlJS1K5dO5UsWVL79+/X/PnzFR8fr65duxZpPy1fvlz33XffVX+De/TRRzVv3jw99dRTWrNmjVq0aKH8/Hzt3btX8+bN07Jly/7wCNylAgMDNWnSJPXv31///ve/1bFjx2vaH1FRUXrzzTfVvn17PfLIIzp27JjeeusthYaGaseOHWZdaGioXnjhBY0bN04tW7bUQw89JC8vL23dulVBQUEaP368bDabJk+erP79+6tp06Z65JFHVKZMGW3fvl2///67Zs+erZIlS2rixInq27evWrdurZ49e5qPHAgJCXG6piQnJ8fhFNt///tfnTt3zuGi2Cv5M8sWpkqVKho3bpxiYmI0d+5cde/eXRUqVFBsbKzGjBmj9u3b64EHHtC+ffs0Y8YMNW3aVP/+97+LtK5rERoaqrvvvlsDBw5Ubm6upkyZonLlyjmcfpk0aZI6dOig8PBw9evXz3zkgJ+fn/l8sf3792vUqFH69NNPNXLkSKfrcgpjv9hYunjB+cSJE+Xn56d77733mrdjwIABeuedd9SnTx8lJycrJCREn3/+uTZu3KgpU6Y4Pe5h+fLleuKJJ656JPVqkpKSVKJECfP03LRp03THHXc4HblJSkrS8ePHzdNzq1at0nPPPVfomB07dlRERIReeOEFpaamqlGjRlq9erUWLFigp556yrzer2HDhurdu7feffddZWZmqnXr1tqyZYtmz56tzp07O+2/GjVqqF+/ftq6dasCAgL04YcfKj093emI8OXi4+NVu3ZtDR482LzGbdiwYfrqq6/UqVMn9enTR2FhYcrJydHOnTv1+eef6+DBgw5nMG4oLrlnD38bK7e0GsbFRw48++yzRqVKlQwfHx+jRYsWRlJSktPtroZx8fbxF154wahWrZpRsmRJIzAw0Ojatatx4MABwzCK9siBTz/91IiNjTUqVqxo+Pj4GFFRUcYvv/zitPwPP/xgPPTQQ0a5cuUMLy8vo2rVqka3bt2MVatWOaz7j16X3zK8YMEC4+677zZKlSpllCpVyqhVq5YRHR1t7Nu3zzAMwxg8eLDRqlUrIzEx0amnwm6xN4yLt5+HhYUZPj4+RunSpY369esbw4cPN44cOWLWXOsjB9zc3Izk5GSH6YV9j/Ly8oyJEycadevWNby8vIwyZcoYYWFhxpgxY4ysrCyn9f3ReIZhGG3atDGqVKlinD59+pr3xwcffGBUr17d8PLyMmrVqmXMmjXrivvtww8/NO644w6z79atWxsrVqxwqPnqq6+Mu+66y/Dx8TFsNptx5513Gp9++qlDzdy5c81xypYta/Tq1cvhtnnDuPjYgEt/Lnx9fY3GjRsb//3vf6+6j/7ssvZtz8jIcJp34cIFo3HjxkZgYKBx6tQpc/r06dONWrVqGSVLljQCAgKMgQMHOsw3jL/ukQOTJk0y3njjDSM4ONjw8vIyWrZsaWzfvt2pfuXKlUaLFi3M78v9999v/Pjjj+b8Tz/91KhXr54RHx/v8OiQK/VhvxXe/ipfvrzRrl0747vvviu0x8td/nljGIaRnp5u9O3b1yhfvrzh6elp1K9f3+nRAJc+auG3335zmFe1alXLjxywv9zd3Y3KlSsbvXv3dvgZtH8+21+enp5GaGioERcXZ+Tm5hqGUfj78cyZM8bQoUONoKAgo2TJkkZoaKgxYcIEp0d1nD9/3hgzZoz5WR0cHGzExsYa586dc9qmqKgoY9myZUaDBg3M9+n8+fMd6i595MClZs+ebUgyvvrqK3Pa6dOnjdjYWCM0NNTw9PQ0ypcvb9x1113G66+/buTl5V11/xVnbobxJ86pAH/S2rVrde+992r+/PlFPvpyqYMHD6patWpKTU0t9GF60sUHBR48eFAJCQl/en3Azcz+fpo0adIVj3zgxhcSEqJ69epp8eLFrm6l2OOaJgAAAAu4pgk3FV9fX/Xq1euqFyY3aNDA4c4VAACsIDThplK+fHnzwtwreeihh/6mbgAANxOuaQIAALCAa5oAAAAsIDQBAABYwDVN10lBQYGOHDmi0qVL/yV/6wcAAFx/hmHo9OnTCgoKcvpjzpcjNF0nR44csfSHUAEAQPFz+PBhVa5c+ao1hKbrxP74/cOHD1v60wAAAMD1srOzFRwc7PRndApDaLpO7KfkbDYboQkAgBuMlUtruBAcAADAAkITAACABYQmAAAACwhNAAAAFhCaAAAALCA0AQAAWEBoAgAAsIDQBAAAYAGhCQAAwAJCEwAAgAWEJgAAAAsITQAAABYQmgAAACwgNAEAAFhAaAIAALCghKsbwLUJG/aRq1sAip3kSY+5ugUA/wAcaQIAALCA0AQAAGABoQkAAMACl4em3377Tf/+979Vrlw5+fj4qH79+tq2bZs53zAMxcXFqVKlSvLx8VFERIT279/vMMbJkyfVq1cv2Ww2+fv7q1+/fjpz5oxDzY4dO9SyZUt5e3srODhYr732mlMv8+fPV61ateTt7a369evrm2+++Ws2GgAA3HBcGppOnTqlFi1aqGTJklq6dKl+/PFHvfHGGypTpoxZ89prr2nq1KmaOXOmNm/erFKlSikyMlLnzp0za3r16qXdu3drxYoVWrx4sdavX68BAwaY87Ozs9WuXTtVrVpVycnJmjRpkkaPHq13333XrNm0aZN69uypfv366YcfflDnzp3VuXNn7dq16+/ZGQAAoFhzMwzDcNXKR44cqY0bN2rDhg2FzjcMQ0FBQXr22Wf13HPPSZKysrIUEBCghIQE9ejRQ3v27FGdOnW0detWNWnSRJKUmJiojh076tdff1VQUJDefvttvfDCC0pLS5Onp6e57oULF2rv3r2SpO7duysnJ0eLFy8219+8eXM1atRIM2fO/MNtyc7Olp+fn7KysmSz2f7Ufrka7p4DnHH3HICiupb/v116pOmrr75SkyZN9PDDD6tixYq644479N5775nzU1NTlZaWpoiICHOan5+fmjVrpqSkJElSUlKS/P39zcAkSREREXJ3d9fmzZvNmlatWpmBSZIiIyO1b98+nTp1yqy5dD32Gvt6Lpebm6vs7GyHFwAAuHm5NDT973//09tvv63q1atr2bJlGjhwoJ5++mnNnj1bkpSWliZJCggIcFguICDAnJeWlqaKFSs6zC9RooTKli3rUFPYGJeu40o19vmXGz9+vPz8/MxXcHDwNW8/AAC4cbg0NBUUFKhx48Z69dVXdccdd2jAgAF64oknLJ0Oc7XY2FhlZWWZr8OHD7u6JQAA8BdyaWiqVKmS6tSp4zCtdu3aOnTokCQpMDBQkpSenu5Qk56ebs4LDAzUsWPHHOZfuHBBJ0+edKgpbIxL13GlGvv8y3l5eclmszm8AADAzculoalFixbat2+fw7SffvpJVatWlSRVq1ZNgYGBWrVqlTk/OztbmzdvVnh4uCQpPDxcmZmZSk5ONmtWr16tgoICNWvWzKxZv369zp8/b9asWLFCNWvWNO/UCw8Pd1iPvca+HgAA8M/m0tA0dOhQfffdd3r11Vf1888/a86cOXr33XcVHR0tSXJzc9OQIUP08ssv66uvvtLOnTv12GOPKSgoSJ07d5Z08chU+/bt9cQTT2jLli3auHGjBg0apB49eigoKEiS9Mgjj8jT01P9+vXT7t27NXfuXMXHxysmJsbs5ZlnnlFiYqLeeOMN7d27V6NHj9a2bds0aNCgv32/AACA4self7C3adOm+vLLLxUbG6uxY8eqWrVqmjJlinr16mXWDB8+XDk5ORowYIAyMzN19913KzExUd7e3mbNJ598okGDBqlt27Zyd3dXly5dNHXqVHO+n5+fli9frujoaIWFhal8+fKKi4tzeJbTXXfdpTlz5ujFF1/U888/r+rVq2vhwoWqV6/e37MzAABAsebS5zTdTHhOE+A6PKcJQFHdMM9pAgAAuFEQmgAAACwgNAEAAFhAaAIAALCA0AQAAGABoQkAAMACQhMAAIAFhCYAAAALCE0AAAAWEJoAAAAsIDQBAABYQGgCAACwgNAEAABgAaEJAADAAkITAACABYQmAAAACwhN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LHhOE+A6PKcJQFHdUM9pAgAAuBEQmgAAACwgNAEAAFhAaAIAALCA0AQAAGABoQkAAMACQhMAAIAFhCYAAAALCE0AAAAWEJoAAAAsIDQBAABYQGgCAACwgNAEAABgAaEJAADAAkITAACABYQmAAAACwhNAAAAFhCaAAAALCA0AQAAWEBoAgAAsKBIoalNmzbKzMx0mp6dna02bdr82Z4AAACKnSKFprVr1yovL89p+rlz57Rhw4Y/3RQAAEBxU+Jainfs2GH++8cff1RaWpr5dX5+vhITE3Xrrbdev+4AAACKiWsKTY0aNZKbm5vc3NwKPQ3n4+OjadOmXbfmAAAAiotrCk2pqakyDEO33XabtmzZogoVKpjzPD09VbFiRXl4eFz3JgEAAFztmkJT1apVJUkFBQV/STMAAADF1TWFpkvt379fa9as0bFjx5xCVFxc3J9uDAAAoDgpUmh67733NHDgQJUvX16BgYFyc3Mz57m5uRGaAADATadIoenll1/WK6+8ohEjRlzvfgAAAIqlIj2n6dSpU3r44Yevdy8AAADFVpFC08MPP6zly5df714AAACKrSKdngsNDdVLL72k7777TvXr11fJkiUd5j/99NPXpTkAAIDiokih6d1335Wvr6/WrVundevWOcxzc3MjNAEAgJtOkUJTamrq9e4DAACgWCvSNU0AAAD/NEU60vT4449fdf6HH35YpGYAAACKqyKFplOnTjl8ff78ee3atUuZmZmF/iFfAACAG12RQtOXX37pNK2goEADBw7U7bff/qebAgAAKG6u2zVN7u7uiomJ0eTJk6/XkAAAAMXGdb0Q/MCBA7pw4cL1HBIAAKBYKNLpuZiYGIevDcPQ0aNHtWTJEvXu3fu6NAYAAFCcFCk0/fDDDw5fu7u7q0KFCnrjjTf+8M46AACAG1GRQtOaNWuudx8AAADFWpFCk11GRob27dsnSapZs6YqVKhwXZoCAAAobop0IXhOTo4ef/xxVapUSa1atVKrVq0UFBSkfv366ffff7/ePQIAALhckUJTTEyM1q1bp6+//lqZmZnKzMzUokWLtG7dOj377LPXu0cAAACXK1JoWrBggT744AN16NBBNptNNptNHTt21HvvvafPP//c8jhvv/22GjRoYI4RHh6upUuXmvPPnTun6OholStXTr6+vurSpYvS09Mdxjh06JCioqJ0yy23qGLFiho2bJjTYw/Wrl2rxo0by8vLS6GhoUpISHDq5a233lJISIi8vb3VrFkzbdmy5dp2CgAAuKkVKTT9/vvvCggIcJpesWLFazo9V7lyZU2YMEHJycnatm2b2rRpo3/961/avXu3JGno0KH6+uuvNX/+fK1bt05HjhzRQw89ZC6fn5+vqKgo5eXladOmTZo9e7YSEhIUFxdn1qSmpioqKkr33nuvUlJSNGTIEPXv31/Lli0za+bOnauYmBiNGjVK33//vRo2bKjIyEgdO3asKLsHAADchNwMwzCudaG2bduqXLly+uijj+Tt7S1JOnv2rHr37q2TJ09q5cqVRW6obNmymjRpkrp27aoKFSpozpw56tq1qyRp7969ql27tpKSktS8eXMtXbpUnTp10pEjR8wQN3PmTI0YMUIZGRny9PTUiBEjtGTJEu3atctcR48ePZSZmanExERJUrNmzdS0aVNNnz5d0sU/CRMcHKzBgwdr5MiRlvrOzs6Wn5+fsrKyZLPZirz9fyRs2Ed/2djAjSp50mOubgHADepa/v8u0pGmKVOmaOPGjapcubLatm2rtm3bKjg4WBs3blR8fHyRms7Pz9dnn32mnJwchYeHKzk5WefPn1dERIRZU6tWLVWpUkVJSUmSpKSkJNWvX9/hqFdkZKSys7PNo1VJSUkOY9hr7GPk5eUpOTnZocbd3V0RERFmTWFyc3OVnZ3t8AIAADevIj1yoH79+tq/f78++eQT7d27V5LUs2dP9erVSz4+Ptc01s6dOxUeHq5z587J19dXX375perUqaOUlBR5enrK39/foT4gIEBpaWmSpLS0NKfThPav/6gmOztbZ8+e1alTp5Sfn19ojX3bCjN+/HiNGTPmmrYVAADcuIoUmsaPH6+AgAA98cQTDtM//PBDZWRkaMSIEZbHqlmzplJSUpSVlaXPP/9cvXv31rp164rS1t8qNjbW4c/JZGdnKzg42IUdAQCAv1KRTs+98847qlWrltP0unXraubMmdc0lqenp0JDQxUWFqbx48erYcOGio+PV2BgoPLy8pSZmelQn56ersDAQElSYGCg09109q//qMZms8nHx0fly5eXh4dHoTX2MQrj5eVl3vVnfwEAgJtXkUJTWlqaKlWq5DS9QoUKOnr06J9qqKCgQLm5uQoLC1PJkiW1atUqc96+fft0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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Распределение классов в Тестовой выборке:\n", "HeartDisease\n", "No 87649\n", "Yes 8290\n", "Name: count, dtype: int64\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAk0AAAHHCAYAAACiOWx7AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABGQ0lEQVR4nO3dd3gUdfv+/XOTkCIhhJYmAXLTS25KKAYEBCKhyRdFKSLSBNQAYpCm0kGaSBURC6CCIiBFkNCbiJQgTQGRO0iRhFCSQCiBZJ4//GUelg04BGSDvl/HscfBzlzzmWtms5uTmdmJzTAMQwAAALgjF2c3AAAA8DAgNAEAAFhAaAIAALCA0AQAAGABoQkAAMACQhMAAIAFhCYAAAALCE0AAAAWuDm7AQAA/q2uXr2q8+fPy83NTX5+fs5uB3+BI00AgH+cadOmKSkpyXw+adIkpaamOq+hm6xdu1bNmzeXr6+vvLy89Oijj+q1115zdluwgNAES2bPni2bzWY+PD09VapUKfXo0UMJCQnObg/4Vzl27Jjd+/FOj2PHjjm7Xaf49ttvNXToUJ04cUJz587VoEGD5OXl5ey2NH36dEVGRio5OVmTJ0/WmjVrtGbNGg0fPtzZrcECTs/hrgwfPlwhISG6evWqvv/+e33wwQf67rvvdODAAT3yyCPObg/4VyhUqJA+//xzu2kTJkzQyZMnNXHiRIfaf6M333xTzZs31+TJk+Xi4qIJEybIxcW5xwmOHDmi6OhodevWTdOnT5fNZnNqP7h7Nv5gL6yYPXu2OnXqpJ07d6pq1arm9D59+ui9997TvHnz1LZtWyd2CPy7NWvWTAcOHPjXHlnKSlJSkg4ePKjg4GAVLlzY2e2oZ8+e+vbbb3XkyBHlypXL2e0gGzg9h3tSv359SVJcXJwk6fz583rjjTcUGhoqb29v+fj4qHHjxtq7d6/DslevXtXQoUNVqlQpeXp6KjAwUM8884yOHj0q6a9PQTzxxBPmWBs3bpTNZtP8+fP15ptvKiAgQLlz51bz5s114sQJh3Vv375djRo1Ut68efXII4+obt262rp1a5bb+MQTT2S5/qFDhzrUfvHFFwoLC5OXl5fy58+vNm3aZLn+O23bzTIyMjRp0iSVL19enp6e8vf3V/fu3XXhwgW7umLFiqlZs2YO6+nRo4fDmFn1Pn78eId9KknXrl3TkCFDVKJECXl4eCg4OFj9+vXTtWvXstxXN3viiSccxhs1apRcXFw0b968bO2Pd999VzVr1lSBAgXk5eWlsLAwLVy4MMv1f/HFF6pevboeeeQR5cuXT3Xq1NHq1avtalauXKm6desqT5488vHxUbVq1Rx6W7BggfmaFixYUC+88IJOnTplV9OxY0e7nvPly6cnnnhCW7Zs+cv9dC/L3o2kpCT17t1bwcHB8vDwUIkSJTR27FhlZGTY1WVkZGjy5MkKDQ2Vp6enChUqpEaNGmnXrl2S9JenA29+zc+cOaMuXbrI399fnp6eqlixoubMmWO3vltf+1y5cqlYsWLq27ev0tLS7Gr/97//6bnnnlP+/Pn1yCOP6LHHHtOKFSvsajI/CzZu3ChfX1+Fh4ercOHCatq06W3ft1ktn/nw8PBQqVKlNHr0aN18jGHo0KGy2Ww6e/bsbccqVqyYOnbsaD7/8ccfFRYWpldffVX+/v7y8PBQhQoV9NFHHzksm5qaqj59+pivV+nSpfXuu+/q1uMcNptNPXr00Ny5c1W6dGl5enoqLCxMmzdvtqvL7PdmGzZskIeHh15++WW76adOnVLnzp3NHsuXL69PP/30jvvt34LTc7gnmQGnQIECkv78UFuyZImee+45hYSEKCEhQR9++KHq1q2rX375RUFBQZKk9PR0NWvWTOvWrVObNm302muv6eLFi1qzZo0OHDig4sWLm+to27atmjRpYrfegQMHZtnPqFGjZLPZ1L9/f505c0aTJk1SRESE9uzZY17PsH79ejVu3FhhYWEaMmSIXFxcNGvWLNWvX19btmxR9erVHcYtXLiwRo8eLUm6dOmSXnnllSzXPWjQILVq1UovvfSSEhMTNXXqVNWpU0c//fSTfH19HZbp1q2bateuLUn65ptvtHjxYrv53bt3N4/y9erVS3FxcZo2bZp++uknbd269b78bzUpKcnctptlZGSoefPm+v7779WtWzeVLVtW+/fv18SJE/Xrr79qyZIld7WeWbNm6e2339aECRP0/PPPZ1nzV/tj8uTJat68udq1a6e0tDR99dVXeu6557R8+XI1bdrUrBs2bJiGDh2qmjVravjw4XJ3d9f27du1fv16NWzYUNKfR087d+6s8uXLa+DAgfL19dVPP/2kmJgYs7/MfV+tWjWNHj1aCQkJmjx5srZu3erw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+/dr7ty5+s9//mNX9+KLL+qzzz5TdHS0duzYodq1ays1NVVr167Vq6++qv/7v//L1vrz58+vxx9/XJ06dVJCQoImTZqkEiVKqGvXrpL+vDbh448/VuPGjVW+fHl16tRJjz76qE6dOqUNGzbIx8dH3377rVJTU/X+++9rypQpKlWqlDZu3GiuIzNs7du3T9u2bVN4eLiKFy+ukSNHauDAgTp27JhatGihPHnyKC4uTosXL1a3bt30xhtvaO3atRo0aJD27dunb7/99o7bUrduXXXv3l2jR4/Wnj171LBhQ+XKlUtHjhzRggULNHnyZD377LPZ2k+rV6/Wk08+ecf/TbZv315ff/21Xn75ZW3YsEG1atVSenq6Dh06pK+//lqrVq36yyNwNwsICND48eP10ksv6YUXXlCTJk3uan80bdpU7733nho1aqTnn39eZ86c0fvvv68SJUpo3759Zl2JEiX01ltvacSIEapdu7aeeeYZeXh4aOfOnQoKCtLo0aPl4+OjiRMn6qWXXlK1atX0/PPPK1++fNq7d68uX76sOXPmKFeuXBo7dqw6deqkunXrqm3btuYtB4oVK2Z3vY305y/wm0+xff7557p69eodvwp/P5a1om/fvlq2bJmaNWumjh07KiwsTKmpqdq/f78WLlyoY8eOqWDBgqpXr57at2+vKVOm6MiRI2rUqJEyMjK0ZcsW1atXTz169LC8zm7duunDDz9Ux44dFRsbq2LFimnhwoXaunWrJk2a5HC9zrZt2+Tm5maenps6daoqV65sHn0ZMGCAvvzySzVu3Fi9evVS/vz5NWfOHMXFxWnRokUO1wmtXr1ao0aNsruW8m6sWbNGJ0+eNE/PzZ07V82bN5e7u7td3fr16+1Oz/3222+3/Vp+ly5d9MEHH6hjx47atWuXQkJCtGTJEq1bt05jxowxe33qqadUr149vfXWWzp27JgqVqyo1atXa+nSperdu7fdLVmkP6/Ni4yMtLvlgKQsw28mm82mjz/+WJUqVdKQIUM0btw4SdKYMWO0YcMG1ahRQ127dlW5cuV0/vx57d69W2vXrtX58+eztT//MR701/XwcMr8avHOnTvvWHf16lWjT58+RmBgoOHl5WXUqlXL2LZtm93XzzNdvnzZeOutt4yQkBAjV65cRkBAgPHss88aR48eNQwje7cc+PLLL42BAwca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6tVLI0eOVK1atTRkyBDt27fPbjs2bNhgtx1lypSRJPMU3JEjR9S2bVv95z//kY+Pj3kUKXM7OnbsqD179qh06dLq1auXVq9ebTf+pUuXVKBAAbt1xMXF2Z3iA3Dv3JzdAIB/p9y5c6tEiRJ2006ePGn++9KlS+revbt69erlsGyRIkWUmpqqyMhIRUZGau7cuSpUqJCOHz+uyMhIpaWlOazrXpw7d06JiYkKCQnJcv5LL72kyMhIrVixQqtXr9bo0aM1YcIE9ezZU5cuXdJTTz2lsWPHOiwXGBgoSXrqqadUtGhRffTRRwoKClJGRoYqVKhgbkeVKlUUFxenlStXau3atWrVqpUiIiK0cOFCXbp0SYGBgdq4caPD+L6+vve03QDsEZoA5EhVqlTRL7/84hCsMu3fv1/nzp3TmDFjFBwcLEnatWuXpbHd3d2Vnp5uuZfJkyfLxcUly9skZAoODtbLL7+sl19+WQMHDtRHH32knj17qkqVKlq0aJGKFSsmNzfHj9xz587p8OHD+uijj1S7dm1Jf14AfysfHx+1bt1arVu31rPPPqtGjRrp/PnzqlKliuLj4+Xm5mZ3nROA+4/TcwBypP79++uHH35Qjx49tGfPHh05ckRLly41LwQvUqSI3N3dNXXqVP3vf//TsmXLNGLECEtjFytWTHFxcdqzZ4/Onj2ra9eumfMuXryo+Ph4nThxQps3b1a3bt00cuRIjRo16rYBrnfv3lq1apXi4uK0e/dubdiwQWXLlpX050Xi58+fV9u2bbVz504dPXpUq1atUqdOnZSenq58+fKpQIECmjlzpn777TetX79e0dHRduO/9957+vLLL3Xo0CH9+uuvWrBggQICAszbIYSHh6tFixZavXq1jh07ph9++EFvvfWW5RAJwBpCE4Ac6b///a82bdqkX3/9VbVr11blypU1ePBgBQUFSZIKFSqk2bNna8GCBSpXrpzGjBmjd99919LYLVu2VKNGjVSvXj0VKlRIX375pTlv8ODBCgwMVIkSJdS+fXslJydr3bp16t+//23HS09PV1RUlMqWLatGjRqpVKlSmj59uiQpKChIW7duVXp6uho2bKjQ0FD17t1bvr6+cnFxkYuLi7766ivFxsaqQoUKev311zV+/Hi78fPkyaNx48apatWqqlatmo4dO6bvvvtOLi4ustls+u6771SnTh116tRJpUqVUps2bfT777/L39//bnc7gDuwGYZhOLsJAACAnI4jTQAAABYQmgAAACwgNAEAAFhAaAIAALCA0AQAAGABoQkAAMACQhMAAIAFhCYAAAALCE0AAAAWEJoAAAAsIDQBAABYQGgCAACw4P8D9HJIA7hu5D8AAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "\n", "# Проверка распределения классов в целевой переменной\n", "class_distribution = df['HeartDisease'].value_counts()\n", "print(\"Распределение классов в HeartDisease:\")\n", "print(class_distribution)\n", "\n", "# Визуализация распределения классов\n", "sns.countplot(x='HeartDisease', data=df)\n", "plt.title('Распределение классов в HeartDisease')\n", "plt.show()\n", "\n", "# Проверка сбалансированности для каждой выборки\n", "def check_balance(df, title):\n", " class_distribution = df['HeartDisease'].value_counts()\n", " print(f\"Распределение классов в {title}:\")\n", " print(class_distribution)\n", " sns.countplot(x='HeartDisease', data=df)\n", " plt.title(f'Распределение классов в {title}')\n", " plt.show()\n", "\n", "# Проверка сбалансированности для обучающей, контрольной и тестовой выборок\n", "check_balance(train_df, 'Обучающей выборке')\n", "check_balance(val_df, 'Контрольной выборке')\n", "check_balance(test_df, 'Тестовой выборке')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Можно заметить, что данные не сбалансированы - во всех выборках количество значений \"No\" превышает \"Yes\" в среднем в 10 раз. Для балансировки данных будет применен метод upsampling " ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Размер обучающей выборки до upsampling: 156699\n", "Размер контрольной выборки: 67157\n", "Размер тестовой выборки: 95939\n", "\n", "Распределение классов в всем датасете:\n", "Класс No: 292422 (91.44%)\n", "Класс Yes: 27373 (8.56%)\n", "\n", "Распределение классов в Обучающей выборке до upsampling:\n", "Класс No: 143331 (91.47%)\n", "Класс Yes: 13368 (8.53%)\n", "Размер обучающей выборки после upsampling: 286662\n", "\n", "Распределение классов в Обучающей выборке после upsampling:\n", "Класс No: 143331 (50.00%)\n", "Класс Yes: 143331 (50.00%)\n", "\n", "Распределение классов в Контрольной выборке:\n", "Класс No: 61442 (91.49%)\n", "Класс Yes: 5715 (8.51%)\n", "\n", "Распределение классов в Тестовой выборке:\n", "Класс No: 87649 (91.36%)\n", "Класс Yes: 8290 (8.64%)\n" ] } ], "source": [ "import pandas as pd\n", "from sklearn.model_selection import train_test_split\n", "from imblearn.over_sampling import RandomOverSampler\n", "\n", "# Разделение на обучающую и тестовую выборки (например, 70% обучающая, 30% тестовая)\n", "train_df, test_df = train_test_split(df, test_size=0.3, random_state=42)\n", "\n", "# Разделение обучающей выборки на обучающую и контрольную (например, 70% обучающая, 30% контрольная)\n", "train_df, val_df = train_test_split(train_df, test_size=0.3, random_state=42)\n", "\n", "# Вывод размеров выборок\n", "print(\"Размер обучающей выборки до upsampling:\", len(train_df))\n", "print(\"Размер контрольной выборки:\", len(val_df))\n", "print(\"Размер тестовой выборки:\", len(test_df))\n", "\n", "# Функция для проверки балансировки данных\n", "def check_balance(df, title):\n", " class_distribution = df['HeartDisease'].value_counts()\n", " print(f\"\\nРаспределение классов в {title}:\")\n", " for cls, count in class_distribution.items():\n", " print(f\"Класс {cls}: {count} ({count / len(df) * 100:.2f}%)\")\n", "\n", "# Проверка балансировки для всего датасета\n", "check_balance(df, 'всем датасете')\n", "\n", "# Проверка балансировки для обучающей выборки до upsampling\n", "check_balance(train_df, 'Обучающей выборке до upsampling')\n", "\n", "# Применение upsampling к обучающей выборке\n", "X_train = train_df.drop('HeartDisease', axis=1) # Отделяем признаки от целевой переменной\n", "y_train = train_df['HeartDisease'] # Целевая переменная\n", "\n", "# Инициализация RandomOverSampler\n", "ros = RandomOverSampler(random_state=42)\n", "\n", "# Применение upsampling\n", "X_train_resampled, y_train_resampled = ros.fit_resample(X_train, y_train)\n", "\n", "# Создание нового DataFrame с балансированными данными\n", "train_df_resampled = pd.concat([X_train_resampled, y_train_resampled], axis=1)\n", "\n", "# Вывод размеров выборок после upsampling\n", "print(\"Размер обучающей выборки после upsampling:\", len(train_df_resampled))\n", "\n", "# Проверка балансировки для обучающей выборки после upsampling\n", "check_balance(train_df_resampled, 'Обучающей выборке после upsampling')\n", "\n", "# Проверка балансировки для контрольной и тестовой выборок (они не должны измениться)\n", "check_balance(val_df, 'Контрольной выборке')\n", "check_balance(test_df, 'Тестовой выборке')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Данные были сбалансированы. Теперь можно перейти к конструированию признаков. Поставлены следующие задачи:\n", "\n", "1. Разработка персонализированных программ профилактики сердечно-сосудистых заболеваний\n", "2. Улучшение качества медицинской помощи" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Унитарное кодирование категориальных признаков (one-hot encoding)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "from sklearn.model_selection import train_test_split\n", "from imblearn.over_sampling import RandomOverSampler\n", "\n", "# Определение категориальных признаков\n", "categorical_features = [\n", " 'Smoking', 'AlcoholDrinking', 'Stroke', 'DiffWalking', 'Sex', 'AgeCategory', 'Race',\n", " 'Diabetic', 'PhysicalActivity', 'GenHealth', 'Asthma', 'KidneyDisease', 'SkinCancer'\n", "]\n", "\n", "# Применение one-hot encoding к обучающей выборке\n", "train_df_resampled_encoded = pd.get_dummies(train_df_resampled, columns=categorical_features)\n", "\n", "# Применение one-hot encoding к контрольной выборке\n", "val_df_encoded = pd.get_dummies(val_df, columns=categorical_features)\n", "\n", "# Применение one-hot encoding к тестовой выборке\n", "test_df_encoded = pd.get_dummies(test_df, columns=categorical_features)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Дискретизация числовых признаков" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "from sklearn.model_selection import train_test_split\n", "from imblearn.over_sampling import RandomOverSampler\n", "\n", "# Загрузка данных\n", "df = pd.read_csv(\"..//static//csv//heart_2020_cleaned.csv\")\n", "\n", "# Разделение на обучающую и тестовую выборки (например, 70% обучающая, 30% тестовая)\n", "train_df, test_df = train_test_split(df, test_size=0.3, random_state=42)\n", "\n", "# Разделение обучающей выборки на обучающую и контрольную (например, 70% обучающая, 30% контрольная)\n", "train_df, val_df = train_test_split(train_df, test_size=0.3, random_state=42)\n", "\n", "# Применение upsampling к обучающей выборке\n", "X_train = train_df.drop('HeartDisease', axis=1) # Отделяем признаки от целевой переменной\n", "y_train = train_df['HeartDisease'] # Целевая переменная\n", "\n", "# Инициализация RandomOverSampler\n", "ros = RandomOverSampler(random_state=42)\n", "\n", "# Применение upsampling\n", "X_train_resampled, y_train_resampled = ros.fit_resample(X_train, y_train)\n", "\n", "# Создание нового DataFrame с балансированными данными\n", "train_df_resampled = pd.concat([X_train_resampled, y_train_resampled], axis=1)\n", "\n", "# Определение числовых признаков для дискретизации\n", "numerical_features = ['BMI', 'PhysicalHealth', 'MentalHealth', 'SleepTime']\n", "\n", "# Функция для дискретизации числовых признаков\n", "def discretize_features(df, features, bins=5, labels=False):\n", " for feature in features:\n", " df[f'{feature}_bin'] = pd.cut(df[feature], bins=bins, labels=labels)\n", " return df\n", "\n", "# Применение дискретизации к обучающей, контрольной и тестовой выборкам\n", "train_df_resampled = discretize_features(train_df_resampled, numerical_features)\n", "val_df = discretize_features(val_df, numerical_features)\n", "test_df = discretize_features(test_df, numerical_features)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ручной синтез. \n", "Создание новых признаков на основе экспертных знаний и логики предметной области. Например, для данных о продаже автомобилей можно создать признак \"возраст автомобиля\" как разницу между текущим годом и годом выпуска." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "\n", "# Загрузка данных\n", "df = pd.read_csv(\"..//static//csv//heart_2020_cleaned.csv\")\n", "\n", "# Разделение на обучающую и тестовую выборки (например, 70% обучающая, 30% тестовая)\n", "train_df, test_df = train_test_split(df, test_size=0.3, random_state=42)\n", "\n", "# Разделение обучающей выборки на обучающую и контрольную (например, 70% обучающая, 30% контрольная)\n", "train_df, val_df = train_test_split(train_df, test_size=0.3, random_state=42)\n", "\n", "# Применение upsampling к обучающей выборке\n", "X_train = train_df.drop('HeartDisease', axis=1) # Отделяем признаки от целевой переменной\n", "y_train = train_df['HeartDisease'] # Целевая переменная\n", "\n", "# Инициализация RandomOverSampler\n", "ros = RandomOverSampler(random_state=42)\n", "\n", "# Применение upsampling\n", "X_train_resampled, y_train_resampled = ros.fit_resample(X_train, y_train)\n", "\n", "# Создание нового DataFrame с балансированными данными\n", "train_df_resampled = pd.concat([X_train_resampled, y_train_resampled], axis=1)\n", "\n", "# Создание нового признака \"Age\" на основе категориального признака \"AgeCategory\"\n", "age_mapping = {\n", " '18-24': 21,\n", " '25-29': 27,\n", " '30-34': 32,\n", " '35-39': 37,\n", " '40-44': 42,\n", " '45-49': 47,\n", " '50-54': 52,\n", " '55-59': 57,\n", " '60-64': 62,\n", " '65-69': 67,\n", " '70-74': 72,\n", " '75-79': 77,\n", " '80 or older': 80\n", "}\n", "\n", "train_df_resampled['Age'] = train_df_resampled['AgeCategory'].map(age_mapping)\n", "val_df['Age'] = val_df['AgeCategory'].map(age_mapping)\n", "test_df['Age'] = test_df['AgeCategory'].map(age_mapping)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Масштабирование признаков - это процесс преобразования числовых признаков таким образом, чтобы они имели одинаковый масштаб. Это важно для многих алгоритмов машинного обучения, которые чувствительны к масштабу признаков, таких как линейная регрессия, метод опорных векторов (SVM) и нейронные сети." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "from sklearn.model_selection import train_test_split\n", "from imblearn.over_sampling import RandomOverSampler\n", "from sklearn.preprocessing import StandardScaler\n", "\n", "# Загрузка данных\n", "df = pd.read_csv(\"..//static//csv//heart_2020_cleaned.csv\")\n", "\n", "# Разделение на обучающую и тестовую выборки (например, 70% обучающая, 30% тестовая)\n", "train_df, test_df = train_test_split(df, test_size=0.3, random_state=42)\n", "\n", "# Разделение обучающей выборки на обучающую и контрольную (например, 70% обучающая, 30% контрольная)\n", "train_df, val_df = train_test_split(train_df, test_size=0.3, random_state=42)\n", "\n", "# Применение upsampling к обучающей выборке\n", "X_train = train_df.drop('HeartDisease', axis=1) # Отделяем признаки от целевой переменной\n", "y_train = train_df['HeartDisease'] # Целевая переменная\n", "\n", "# Инициализация RandomOverSampler\n", "ros = RandomOverSampler(random_state=42)\n", "\n", "# Применение upsampling\n", "X_train_resampled, y_train_resampled = ros.fit_resample(X_train, y_train)\n", "\n", "# Создание нового DataFrame с балансированными данными\n", "train_df_resampled = pd.concat([X_train_resampled, y_train_resampled], axis=1)\n", "\n", "# Создание нового признака \"Age\" на основе категориального признака \"AgeCategory\"\n", "age_mapping = {\n", " '18-24': 21,\n", " '25-29': 27,\n", " '30-34': 32,\n", " '35-39': 37,\n", " '40-44': 42,\n", " '45-49': 47,\n", " '50-54': 52,\n", " '55-59': 57,\n", " '60-64': 62,\n", " '65-69': 67,\n", " '70-74': 72,\n", " '75-79': 77,\n", " '80 or older': 80\n", "}\n", "\n", "train_df_resampled['Age'] = train_df_resampled['AgeCategory'].map(age_mapping)\n", "val_df['Age'] = val_df['AgeCategory'].map(age_mapping)\n", "test_df['Age'] = test_df['AgeCategory'].map(age_mapping)\n", "\n", "# Определение числовых признаков для масштабирования\n", "numerical_features_to_scale = ['BMI', 'PhysicalHealth', 'MentalHealth', 'SleepTime', 'Age']\n", "\n", "# Инициализация StandardScaler\n", "scaler = StandardScaler()\n", "\n", "# Масштабирование числовых признаков в обучающей выборке\n", "train_df_resampled[numerical_features_to_scale] = scaler.fit_transform(train_df_resampled[numerical_features_to_scale])\n", "\n", "# Масштабирование числовых признаков в контрольной и тестовой выборках\n", "val_df[numerical_features_to_scale] = scaler.transform(val_df[numerical_features_to_scale])\n", "test_df[numerical_features_to_scale] = scaler.transform(test_df[numerical_features_to_scale])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Конструирование признаков с применением фреймворка Featuretools" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\entityset\\entityset.py:1733: UserWarning: index id not found in dataframe, creating new integer column\n", " warnings.warn(\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\synthesis\\deep_feature_synthesis.py:169: UserWarning: Only one dataframe in entityset, changing max_depth to 1 since deeper features cannot be created\n", " warnings.warn(\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", " df = pd.concat([df, default_df], sort=True)\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", " df = pd.concat([df, default_df], sort=True)\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", " df = pd.concat([df, default_df], sort=True)\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", " df = pd.concat([df, default_df], sort=True)\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", " df = pd.concat([df, default_df], sort=True)\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\woodwork\\logical_types.py:841: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n", " series = series.replace(ww.config.get_option(\"nan_values\"), np.nan)\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", " df = pd.concat([df, default_df], sort=True)\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", " df = pd.concat([df, default_df], sort=True)\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", " df = pd.concat([df, default_df], sort=True)\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", " df = pd.concat([df, default_df], sort=True)\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", " df = pd.concat([df, default_df], sort=True)\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\woodwork\\logical_types.py:841: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n", " series = series.replace(ww.config.get_option(\"nan_values\"), np.nan)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Обучающая выборка после конструирования признаков:\n", " HeartDisease BMI Smoking AlcoholDrinking Stroke PhysicalHealth \\\n", "id \n", "0 False 32.23 False False False 0.0 \n", "1 False 29.53 False False False 0.0 \n", "2 False 30.13 False False False 0.0 \n", "3 False 35.43 False False False 0.0 \n", "4 False 29.53 False False False 0.0 \n", "\n", " MentalHealth DiffWalking Sex AgeCategory Race Diabetic \\\n", "id \n", "0 0.0 True Male 75-79 White Yes \n", "1 0.0 True Female 50-54 White No \n", "2 0.0 False Male 50-54 White No \n", "3 15.0 False Female 18-24 Hispanic No \n", "4 0.0 True Female 65-69 White Yes \n", "\n", " PhysicalActivity GenHealth SleepTime Asthma KidneyDisease SkinCancer \\\n", "id \n", "0 True Fair 6.0 False True True \n", "1 True Very good 8.0 False False False \n", "2 True Excellent 7.0 False False False \n", "3 True Good 7.0 False False False \n", "4 False Good 10.0 False False False \n", "\n", " Age \n", "id \n", "0 77 \n", "1 52 \n", "2 52 \n", "3 21 \n", "4 67 \n", "Контрольная выборка после конструирования признаков:\n", " HeartDisease BMI Smoking AlcoholDrinking Stroke PhysicalHealth \\\n", "id \n", "80125 False 22.71 False False False 0.0 \n", "116296 False 25.80 False False False 0.0 \n", "18780 False 17.74 True False False 0.0 \n", "233006 NaN NaN \n", "182306 NaN NaN \n", "\n", " MentalHealth DiffWalking Sex AgeCategory Race Diabetic \\\n", "id \n", "80125 0.0 False Male 25-29 White No \n", "116296 0.0 False Male 50-54 Hispanic No \n", "18780 0.0 False Female 65-69 White No \n", "233006 NaN NaN NaN NaN NaN \n", "182306 NaN NaN NaN NaN NaN \n", "\n", " PhysicalActivity GenHealth SleepTime Asthma KidneyDisease \\\n", "id \n", "80125 True Excellent 8.0 False False \n", "116296 True Good 7.0 False False \n", "18780 True Good 7.0 False False \n", "233006 NaN NaN \n", "182306 NaN NaN \n", "\n", " SkinCancer Age \n", "id \n", "80125 False 27 \n", "116296 False 52 \n", "18780 False 67 \n", "233006 \n", "182306 \n", "Тестовая выборка после конструирования признаков:\n", " HeartDisease BMI Smoking AlcoholDrinking Stroke PhysicalHealth \\\n", "id \n", "271884 NaN NaN \n", "270361 NaN NaN \n", "219060 NaN NaN \n", "24010 False 26.5 False False False 14.0 \n", "181930 NaN NaN \n", "\n", " MentalHealth DiffWalking Sex AgeCategory Race Diabetic \\\n", "id \n", "271884 NaN NaN NaN NaN NaN \n", "270361 NaN NaN NaN NaN NaN \n", "219060 NaN NaN NaN NaN NaN \n", "24010 0.0 True Male 75-79 White Yes \n", "181930 NaN NaN NaN NaN NaN \n", "\n", " PhysicalActivity GenHealth SleepTime Asthma KidneyDisease \\\n", "id \n", "271884 NaN NaN \n", "270361 NaN NaN \n", "219060 NaN NaN \n", "24010 True Excellent 9.0 False False \n", "181930 NaN NaN \n", "\n", " SkinCancer Age \n", "id \n", "271884 \n", "270361 \n", "219060 \n", "24010 False 77 \n", "181930 \n" ] } ], "source": [ "import pandas as pd\n", "from sklearn.model_selection import train_test_split\n", "import featuretools as ft\n", "\n", "# Загрузка данных\n", "df = pd.read_csv(\"..//static//csv//heart_2020_cleaned.csv\")\n", "\n", "# Разделение на обучающую и тестовую выборки (например, 70% обучающая, 30% тестовая)\n", "train_df, test_df = train_test_split(df, test_size=0.3, random_state=42)\n", "\n", "# Разделение обучающей выборки на обучающую и контрольную (например, 70% обучающая, 30% контрольная)\n", "train_df, val_df = train_test_split(train_df, test_size=0.3, random_state=42)\n", "\n", "# Создание нового признака \"Age\" на основе категориального признака \"AgeCategory\"\n", "age_mapping = {\n", " '18-24': 21,\n", " '25-29': 27,\n", " '30-34': 32,\n", " '35-39': 37,\n", " '40-44': 42,\n", " '45-49': 47,\n", " '50-54': 52,\n", " '55-59': 57,\n", " '60-64': 62,\n", " '65-69': 67,\n", " '70-74': 72,\n", " '75-79': 77,\n", " '80 or older': 80\n", "}\n", "\n", "train_df['Age'] = train_df['AgeCategory'].map(age_mapping)\n", "val_df['Age'] = val_df['AgeCategory'].map(age_mapping)\n", "test_df['Age'] = test_df['AgeCategory'].map(age_mapping)\n", "\n", "# Определение сущностей\n", "es = ft.EntitySet(id='heart_data')\n", "es = es.add_dataframe(dataframe_name='train', dataframe=train_df, index='id')\n", "\n", "# Генерация признаков\n", "feature_matrix, feature_defs = ft.dfs(entityset=es, target_dataframe_name='train', max_depth=2)\n", "\n", "# Преобразование признаков для контрольной и тестовой выборок\n", "val_feature_matrix = ft.calculate_feature_matrix(features=feature_defs, entityset=es, instance_ids=val_df.index)\n", "test_feature_matrix = ft.calculate_feature_matrix(features=feature_defs, entityset=es, instance_ids=test_df.index)\n", "\n", "# Вывод первых нескольких строк для проверки\n", "print(\"Обучающая выборка после конструирования признаков:\")\n", "print(feature_matrix.head())\n", "print(\"Контрольная выборка после конструирования признаков:\")\n", "print(val_feature_matrix.head())\n", "print(\"Тестовая выборка после конструирования признаков:\")\n", "print(test_feature_matrix.head())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Оценка качества каждого набора признаков\n", "\n", "Предсказательная способность\n", "Метрики: RMSE, MAE, R²\n", "\n", "Методы: Обучение модели на обучающей выборке и оценка на контрольной и тестовой выборках.\n", "\n", "Скорость вычисления\n", "Методы: Измерение времени выполнения генерации признаков и обучения модели.\n", "\n", "Надежность\n", "Методы: Кросс-валидация, анализ чувствительности модели к изменениям в данных.\n", "\n", "Корреляция\n", "Методы: Анализ корреляционной матрицы признаков, удаление мультиколлинеарных признаков.\n", "\n", "Цельность\n", "Методы: Проверка логической связи между признаками и целевой переменной, интерпретация результатов модели." ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Размер обучающей выборки: 156699\n", "Размер контрольной выборки: 67157\n", "Размер тестовой выборки: 95939\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\entityset\\entityset.py:1733: UserWarning: index id not found in dataframe, creating new integer column\n", " warnings.warn(\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\synthesis\\deep_feature_synthesis.py:169: UserWarning: Only one dataframe in entityset, changing max_depth to 1 since deeper features cannot be created\n", " warnings.warn(\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", " df = pd.concat([df, default_df], sort=True)\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", " df = pd.concat([df, default_df], sort=True)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Feature Importance:\n", " feature importance\n", "0 HeartDisease 0.851120\n", "1 BMI 0.014203\n", "9 Stroke_No 0.012600\n", "2 PhysicalHealth 0.008628\n", "12 DiffWalking_Yes 0.008111\n", "11 DiffWalking_No 0.007721\n", "36 Diabetic_Yes 0.007583\n", "10 Stroke_Yes 0.007551\n", "4 SleepTime 0.007525\n", "43 GenHealth_Poor 0.006605\n", "27 AgeCategory_80 or older 0.006269\n", "34 Diabetic_No 0.005300\n", "3 MentalHealth 0.005102\n", "41 GenHealth_Fair 0.004277\n", "48 KidneyDisease_Yes 0.003435\n", "47 KidneyDisease_No 0.003086\n", "13 Sex_Female 0.002607\n", "26 AgeCategory_75-79 0.002567\n", "25 AgeCategory_70-74 0.002462\n", "14 Sex_Male 0.002457\n", "6 Smoking_Yes 0.002127\n", "5 Smoking_No 0.001934\n", "42 GenHealth_Good 0.001787\n", "44 GenHealth_Very good 0.001734\n", "33 Race_White 0.001731\n", "50 SkinCancer_Yes 0.001687\n", "38 PhysicalActivity_No 0.001658\n", "39 PhysicalActivity_Yes 0.001585\n", "49 SkinCancer_No 0.001513\n", "40 GenHealth_Excellent 0.001451\n", "24 AgeCategory_65-69 0.001318\n", "46 Asthma_Yes 0.001315\n", "45 Asthma_No 0.001256\n", "23 AgeCategory_60-64 0.001091\n", "30 Race_Black 0.000885\n", "22 AgeCategory_55-59 0.000853\n", "31 Race_Hispanic 0.000825\n", "21 AgeCategory_50-54 0.000715\n", "32 Race_Other 0.000699\n", "7 AlcoholDrinking_No 0.000560\n", "8 AlcoholDrinking_Yes 0.000550\n", "20 AgeCategory_45-49 0.000520\n", "28 Race_American Indian/Alaskan Native 0.000503\n", "35 Diabetic_No, borderline diabetes 0.000479\n", "19 AgeCategory_40-44 0.000444\n", "18 AgeCategory_35-39 0.000412\n", "17 AgeCategory_30-34 0.000267\n", "29 Race_Asian 0.000260\n", "15 AgeCategory_18-24 0.000231\n", "16 AgeCategory_25-29 0.000217\n", "37 Diabetic_Yes (during pregnancy) 0.000184\n" ] } ], "source": [ "import pandas as pd\n", "from sklearn.model_selection import train_test_split\n", "from imblearn.over_sampling import RandomOverSampler\n", "import featuretools as ft\n", "from sklearn.ensemble import RandomForestClassifier\n", "\n", "# Загрузка данных\n", "df = pd.read_csv(\"..//static//csv//heart_2020_cleaned.csv\")\n", "\n", "# Разделение на обучающую и тестовую выборки (например, 70% обучающая, 30% тестовая)\n", "train_df, test_df = train_test_split(df, test_size=0.3, random_state=42)\n", "\n", "# Разделение обучающей выборки на обучающую и контрольную (например, 70% обучающая, 30% контрольная)\n", "train_df, val_df = train_test_split(train_df, test_size=0.3, random_state=42)\n", "\n", "# Вывод размеров выборок\n", "print(\"Размер обучающей выборки:\", len(train_df))\n", "print(\"Размер контрольной выборки:\", len(val_df))\n", "print(\"Размер тестовой выборки:\", len(test_df))\n", "\n", "# Определение категориальных признаков\n", "categorical_features = [\n", " 'Smoking', 'AlcoholDrinking', 'Stroke', 'DiffWalking', 'Sex', 'AgeCategory', 'Race',\n", " 'Diabetic', 'PhysicalActivity', 'GenHealth', 'Asthma', 'KidneyDisease', 'SkinCancer'\n", "]\n", "\n", "# Применение one-hot encoding к обучающей выборке\n", "train_df_encoded = pd.get_dummies(train_df, columns=categorical_features)\n", "\n", "# Применение one-hot encoding к контрольной выборке\n", "val_df_encoded = pd.get_dummies(val_df, columns=categorical_features)\n", "\n", "# Применение one-hot encoding к тестовой выборке\n", "test_df_encoded = pd.get_dummies(test_df, columns=categorical_features)\n", "\n", "# Определение сущностей\n", "es = ft.EntitySet(id='heart_data')\n", "es = es.add_dataframe(dataframe_name='heart', dataframe=train_df_encoded, index='id')\n", "\n", "# Генерация признаков\n", "feature_matrix, feature_defs = ft.dfs(entityset=es, target_dataframe_name='heart', max_depth=2)\n", "\n", "# Преобразование признаков для контрольной и тестовой выборок\n", "val_feature_matrix = ft.calculate_feature_matrix(features=feature_defs, entityset=es, instance_ids=val_df_encoded.index)\n", "test_feature_matrix = ft.calculate_feature_matrix(features=feature_defs, entityset=es, instance_ids=test_df_encoded.index)\n", "\n", "# Оценка важности признаков\n", "X = feature_matrix\n", "y = train_df_encoded['HeartDisease']\n", "\n", "# Разделение данных на обучающую и тестовую выборки\n", "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n", "\n", "# Обучение модели\n", "model = RandomForestClassifier(n_estimators=100, random_state=42)\n", "model.fit(X_train, y_train)\n", "\n", "# Получение важности признаков\n", "importances = model.feature_importances_\n", "feature_names = feature_matrix.columns\n", "\n", "# Сортировка признаков по важности\n", "feature_importance = pd.DataFrame({'feature': feature_names, 'importance': importances})\n", "feature_importance = feature_importance.sort_values(by='importance', ascending=False)\n", "\n", "print(\"Feature Importance:\")\n", "print(feature_importance)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Размер обучающей выборки: 156699\n", "Размер контрольной выборки: 67157\n", "Размер тестовой выборки: 95939\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\entityset\\entityset.py:1733: UserWarning: index id not found in dataframe, creating new integer column\n", " warnings.warn(\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\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", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\synthesis\\deep_feature_synthesis.py:169: UserWarning: Only one dataframe in entityset, changing max_depth to 1 since deeper features cannot be created\n", " warnings.warn(\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", " df = pd.concat([df, default_df], sort=True)\n", "c:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\featuretools\\computational_backends\\feature_set_calculator.py:143: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", " df = pd.concat([df, default_df], sort=True)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Accuracy: 0.9977068603095739\n", "Precision: 0.9982521847690387\n", "Recall: 0.9753598438643571\n", "F1 Score: 0.9866732477788747\n", "ROC AUC: 0.9875985227973351\n" ] }, { "ename": "KeyboardInterrupt", "evalue": "", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[31], line 84\u001b[0m\n\u001b[0;32m 81\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mROC AUC: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mroc_auc\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 83\u001b[0m \u001b[38;5;66;03m# Кросс-валидация\u001b[39;00m\n\u001b[1;32m---> 84\u001b[0m scores \u001b[38;5;241m=\u001b[39m \u001b[43mcross_val_score\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mX_train\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my_train\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcv\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m5\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mscoring\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43maccuracy\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m 85\u001b[0m accuracy_cv \u001b[38;5;241m=\u001b[39m scores\u001b[38;5;241m.\u001b[39mmean()\n\u001b[0;32m 86\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCross-validated Accuracy: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00maccuracy_cv\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n", "File \u001b[1;32mc:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\sklearn\\utils\\_param_validation.py:213\u001b[0m, in \u001b[0;36mvalidate_params..decorator..wrapper\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 207\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 208\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m config_context(\n\u001b[0;32m 209\u001b[0m skip_parameter_validation\u001b[38;5;241m=\u001b[39m(\n\u001b[0;32m 210\u001b[0m prefer_skip_nested_validation \u001b[38;5;129;01mor\u001b[39;00m global_skip_validation\n\u001b[0;32m 211\u001b[0m )\n\u001b[0;32m 212\u001b[0m ):\n\u001b[1;32m--> 213\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 214\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m InvalidParameterError \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m 215\u001b[0m \u001b[38;5;66;03m# When the function is just a wrapper around an estimator, we allow\u001b[39;00m\n\u001b[0;32m 216\u001b[0m \u001b[38;5;66;03m# the function to delegate validation to the estimator, but we replace\u001b[39;00m\n\u001b[0;32m 217\u001b[0m \u001b[38;5;66;03m# the name of the estimator by the name of the function in the error\u001b[39;00m\n\u001b[0;32m 218\u001b[0m \u001b[38;5;66;03m# message to avoid confusion.\u001b[39;00m\n\u001b[0;32m 219\u001b[0m msg \u001b[38;5;241m=\u001b[39m re\u001b[38;5;241m.\u001b[39msub(\n\u001b[0;32m 220\u001b[0m \u001b[38;5;124mr\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mparameter of \u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124mw+ must be\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m 221\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mparameter of \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfunc\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__qualname__\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m must be\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m 222\u001b[0m \u001b[38;5;28mstr\u001b[39m(e),\n\u001b[0;32m 223\u001b[0m )\n", "File \u001b[1;32mc:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\sklearn\\model_selection\\_validation.py:712\u001b[0m, in \u001b[0;36mcross_val_score\u001b[1;34m(estimator, X, y, groups, scoring, cv, n_jobs, verbose, fit_params, params, pre_dispatch, error_score)\u001b[0m\n\u001b[0;32m 709\u001b[0m \u001b[38;5;66;03m# To ensure multimetric format is not supported\u001b[39;00m\n\u001b[0;32m 710\u001b[0m scorer \u001b[38;5;241m=\u001b[39m check_scoring(estimator, scoring\u001b[38;5;241m=\u001b[39mscoring)\n\u001b[1;32m--> 712\u001b[0m cv_results \u001b[38;5;241m=\u001b[39m \u001b[43mcross_validate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 713\u001b[0m \u001b[43m \u001b[49m\u001b[43mestimator\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mestimator\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 714\u001b[0m \u001b[43m \u001b[49m\u001b[43mX\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mX\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 715\u001b[0m \u001b[43m \u001b[49m\u001b[43my\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43my\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 716\u001b[0m \u001b[43m \u001b[49m\u001b[43mgroups\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mgroups\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 717\u001b[0m \u001b[43m \u001b[49m\u001b[43mscoring\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m{\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mscore\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mscorer\u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 718\u001b[0m \u001b[43m \u001b[49m\u001b[43mcv\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcv\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 719\u001b[0m \u001b[43m \u001b[49m\u001b[43mn_jobs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mn_jobs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 720\u001b[0m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mverbose\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 721\u001b[0m \u001b[43m \u001b[49m\u001b[43mfit_params\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfit_params\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 722\u001b[0m \u001b[43m \u001b[49m\u001b[43mparams\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mparams\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 723\u001b[0m \u001b[43m \u001b[49m\u001b[43mpre_dispatch\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mpre_dispatch\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 724\u001b[0m \u001b[43m \u001b[49m\u001b[43merror_score\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43merror_score\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 725\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 726\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m cv_results[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtest_score\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n", "File \u001b[1;32mc:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\sklearn\\utils\\_param_validation.py:213\u001b[0m, in \u001b[0;36mvalidate_params..decorator..wrapper\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 207\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 208\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m config_context(\n\u001b[0;32m 209\u001b[0m skip_parameter_validation\u001b[38;5;241m=\u001b[39m(\n\u001b[0;32m 210\u001b[0m prefer_skip_nested_validation \u001b[38;5;129;01mor\u001b[39;00m global_skip_validation\n\u001b[0;32m 211\u001b[0m )\n\u001b[0;32m 212\u001b[0m ):\n\u001b[1;32m--> 213\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 214\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m InvalidParameterError \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m 215\u001b[0m \u001b[38;5;66;03m# When the function is just a wrapper around an estimator, we allow\u001b[39;00m\n\u001b[0;32m 216\u001b[0m \u001b[38;5;66;03m# the function to delegate validation to the estimator, but we replace\u001b[39;00m\n\u001b[0;32m 217\u001b[0m \u001b[38;5;66;03m# the name of the estimator by the name of the function in the error\u001b[39;00m\n\u001b[0;32m 218\u001b[0m \u001b[38;5;66;03m# message to avoid confusion.\u001b[39;00m\n\u001b[0;32m 219\u001b[0m msg \u001b[38;5;241m=\u001b[39m re\u001b[38;5;241m.\u001b[39msub(\n\u001b[0;32m 220\u001b[0m \u001b[38;5;124mr\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mparameter of \u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124mw+ must be\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m 221\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mparameter of \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfunc\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__qualname__\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m must be\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m 222\u001b[0m \u001b[38;5;28mstr\u001b[39m(e),\n\u001b[0;32m 223\u001b[0m )\n", "File \u001b[1;32mc:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\sklearn\\model_selection\\_validation.py:423\u001b[0m, in \u001b[0;36mcross_validate\u001b[1;34m(estimator, X, y, groups, scoring, cv, n_jobs, verbose, fit_params, params, pre_dispatch, return_train_score, return_estimator, return_indices, error_score)\u001b[0m\n\u001b[0;32m 420\u001b[0m \u001b[38;5;66;03m# We clone the estimator to make sure that all the folds are\u001b[39;00m\n\u001b[0;32m 421\u001b[0m \u001b[38;5;66;03m# independent, and that it is pickle-able.\u001b[39;00m\n\u001b[0;32m 422\u001b[0m parallel \u001b[38;5;241m=\u001b[39m Parallel(n_jobs\u001b[38;5;241m=\u001b[39mn_jobs, verbose\u001b[38;5;241m=\u001b[39mverbose, pre_dispatch\u001b[38;5;241m=\u001b[39mpre_dispatch)\n\u001b[1;32m--> 423\u001b[0m results \u001b[38;5;241m=\u001b[39m \u001b[43mparallel\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 424\u001b[0m \u001b[43m \u001b[49m\u001b[43mdelayed\u001b[49m\u001b[43m(\u001b[49m\u001b[43m_fit_and_score\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 425\u001b[0m \u001b[43m \u001b[49m\u001b[43mclone\u001b[49m\u001b[43m(\u001b[49m\u001b[43mestimator\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 426\u001b[0m \u001b[43m \u001b[49m\u001b[43mX\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 427\u001b[0m \u001b[43m \u001b[49m\u001b[43my\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 428\u001b[0m \u001b[43m \u001b[49m\u001b[43mscorer\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mscorers\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 429\u001b[0m \u001b[43m \u001b[49m\u001b[43mtrain\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtrain\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 430\u001b[0m \u001b[43m \u001b[49m\u001b[43mtest\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtest\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 431\u001b[0m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mverbose\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 432\u001b[0m \u001b[43m \u001b[49m\u001b[43mparameters\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[0;32m 433\u001b[0m \u001b[43m \u001b[49m\u001b[43mfit_params\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrouted_params\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mestimator\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfit\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 434\u001b[0m \u001b[43m \u001b[49m\u001b[43mscore_params\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrouted_params\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mscorer\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mscore\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 435\u001b[0m \u001b[43m \u001b[49m\u001b[43mreturn_train_score\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mreturn_train_score\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 436\u001b[0m \u001b[43m \u001b[49m\u001b[43mreturn_times\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[0;32m 437\u001b[0m \u001b[43m \u001b[49m\u001b[43mreturn_estimator\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mreturn_estimator\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 438\u001b[0m \u001b[43m \u001b[49m\u001b[43merror_score\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43merror_score\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 439\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 440\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mtrain\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtest\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mindices\u001b[49m\n\u001b[0;32m 441\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 443\u001b[0m _warn_or_raise_about_fit_failures(results, error_score)\n\u001b[0;32m 445\u001b[0m \u001b[38;5;66;03m# For callable scoring, the return type is only know after calling. If the\u001b[39;00m\n\u001b[0;32m 446\u001b[0m \u001b[38;5;66;03m# return type is a dictionary, the error scores can now be inserted with\u001b[39;00m\n\u001b[0;32m 447\u001b[0m \u001b[38;5;66;03m# the correct key.\u001b[39;00m\n", "File \u001b[1;32mc:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\sklearn\\utils\\parallel.py:74\u001b[0m, in \u001b[0;36mParallel.__call__\u001b[1;34m(self, iterable)\u001b[0m\n\u001b[0;32m 69\u001b[0m config \u001b[38;5;241m=\u001b[39m get_config()\n\u001b[0;32m 70\u001b[0m iterable_with_config \u001b[38;5;241m=\u001b[39m (\n\u001b[0;32m 71\u001b[0m (_with_config(delayed_func, config), args, kwargs)\n\u001b[0;32m 72\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m delayed_func, args, kwargs \u001b[38;5;129;01min\u001b[39;00m iterable\n\u001b[0;32m 73\u001b[0m )\n\u001b[1;32m---> 74\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;21;43m__call__\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43miterable_with_config\u001b[49m\u001b[43m)\u001b[49m\n", "File \u001b[1;32mc:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\joblib\\parallel.py:1918\u001b[0m, in \u001b[0;36mParallel.__call__\u001b[1;34m(self, iterable)\u001b[0m\n\u001b[0;32m 1916\u001b[0m output \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_sequential_output(iterable)\n\u001b[0;32m 1917\u001b[0m \u001b[38;5;28mnext\u001b[39m(output)\n\u001b[1;32m-> 1918\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m output \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mreturn_generator \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28;43mlist\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43moutput\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1920\u001b[0m \u001b[38;5;66;03m# Let's create an ID that uniquely identifies the current call. If the\u001b[39;00m\n\u001b[0;32m 1921\u001b[0m \u001b[38;5;66;03m# call is interrupted early and that the same instance is immediately\u001b[39;00m\n\u001b[0;32m 1922\u001b[0m \u001b[38;5;66;03m# re-used, this id will be used to prevent workers that were\u001b[39;00m\n\u001b[0;32m 1923\u001b[0m \u001b[38;5;66;03m# concurrently finalizing a task from the previous call to run the\u001b[39;00m\n\u001b[0;32m 1924\u001b[0m \u001b[38;5;66;03m# callback.\u001b[39;00m\n\u001b[0;32m 1925\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock:\n", "File \u001b[1;32mc:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\joblib\\parallel.py:1847\u001b[0m, in \u001b[0;36mParallel._get_sequential_output\u001b[1;34m(self, iterable)\u001b[0m\n\u001b[0;32m 1845\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mn_dispatched_batches \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[0;32m 1846\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mn_dispatched_tasks \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[1;32m-> 1847\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1848\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mn_completed_tasks \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[0;32m 1849\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mprint_progress()\n", "File \u001b[1;32mc:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\sklearn\\utils\\parallel.py:136\u001b[0m, in \u001b[0;36m_FuncWrapper.__call__\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 134\u001b[0m config \u001b[38;5;241m=\u001b[39m {}\n\u001b[0;32m 135\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m config_context(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mconfig):\n\u001b[1;32m--> 136\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfunction\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", "File \u001b[1;32mc:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\sklearn\\model_selection\\_validation.py:888\u001b[0m, in \u001b[0;36m_fit_and_score\u001b[1;34m(estimator, X, y, scorer, train, test, verbose, parameters, fit_params, score_params, return_train_score, return_parameters, return_n_test_samples, return_times, return_estimator, split_progress, candidate_progress, error_score)\u001b[0m\n\u001b[0;32m 886\u001b[0m estimator\u001b[38;5;241m.\u001b[39mfit(X_train, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mfit_params)\n\u001b[0;32m 887\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 888\u001b[0m \u001b[43mestimator\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mX_train\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my_train\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mfit_params\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 890\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m:\n\u001b[0;32m 891\u001b[0m \u001b[38;5;66;03m# Note fit time as time until error\u001b[39;00m\n\u001b[0;32m 892\u001b[0m fit_time \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mtime() \u001b[38;5;241m-\u001b[39m start_time\n", "File \u001b[1;32mc:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\sklearn\\base.py:1473\u001b[0m, in \u001b[0;36m_fit_context..decorator..wrapper\u001b[1;34m(estimator, *args, **kwargs)\u001b[0m\n\u001b[0;32m 1466\u001b[0m estimator\u001b[38;5;241m.\u001b[39m_validate_params()\n\u001b[0;32m 1468\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m config_context(\n\u001b[0;32m 1469\u001b[0m skip_parameter_validation\u001b[38;5;241m=\u001b[39m(\n\u001b[0;32m 1470\u001b[0m prefer_skip_nested_validation \u001b[38;5;129;01mor\u001b[39;00m global_skip_validation\n\u001b[0;32m 1471\u001b[0m )\n\u001b[0;32m 1472\u001b[0m ):\n\u001b[1;32m-> 1473\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfit_method\u001b[49m\u001b[43m(\u001b[49m\u001b[43mestimator\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", "File \u001b[1;32mc:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\sklearn\\ensemble\\_forest.py:489\u001b[0m, in \u001b[0;36mBaseForest.fit\u001b[1;34m(self, X, y, sample_weight)\u001b[0m\n\u001b[0;32m 478\u001b[0m trees \u001b[38;5;241m=\u001b[39m [\n\u001b[0;32m 479\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_make_estimator(append\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m, random_state\u001b[38;5;241m=\u001b[39mrandom_state)\n\u001b[0;32m 480\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(n_more_estimators)\n\u001b[0;32m 481\u001b[0m ]\n\u001b[0;32m 483\u001b[0m \u001b[38;5;66;03m# Parallel loop: we prefer the threading backend as the Cython code\u001b[39;00m\n\u001b[0;32m 484\u001b[0m \u001b[38;5;66;03m# for fitting the trees is internally releasing the Python GIL\u001b[39;00m\n\u001b[0;32m 485\u001b[0m \u001b[38;5;66;03m# making threading more efficient than multiprocessing in\u001b[39;00m\n\u001b[0;32m 486\u001b[0m \u001b[38;5;66;03m# that case. However, for joblib 0.12+ we respect any\u001b[39;00m\n\u001b[0;32m 487\u001b[0m \u001b[38;5;66;03m# parallel_backend contexts set at a higher level,\u001b[39;00m\n\u001b[0;32m 488\u001b[0m \u001b[38;5;66;03m# since correctness does not rely on using threads.\u001b[39;00m\n\u001b[1;32m--> 489\u001b[0m trees \u001b[38;5;241m=\u001b[39m \u001b[43mParallel\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 490\u001b[0m \u001b[43m \u001b[49m\u001b[43mn_jobs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mn_jobs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 491\u001b[0m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mverbose\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 492\u001b[0m \u001b[43m \u001b[49m\u001b[43mprefer\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mthreads\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 493\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 494\u001b[0m \u001b[43m \u001b[49m\u001b[43mdelayed\u001b[49m\u001b[43m(\u001b[49m\u001b[43m_parallel_build_trees\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 495\u001b[0m \u001b[43m \u001b[49m\u001b[43mt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 496\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbootstrap\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 497\u001b[0m \u001b[43m \u001b[49m\u001b[43mX\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 498\u001b[0m \u001b[43m \u001b[49m\u001b[43my\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 499\u001b[0m \u001b[43m \u001b[49m\u001b[43msample_weight\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 500\u001b[0m \u001b[43m \u001b[49m\u001b[43mi\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 501\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mlen\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mtrees\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 502\u001b[0m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mverbose\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 503\u001b[0m \u001b[43m \u001b[49m\u001b[43mclass_weight\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mclass_weight\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 504\u001b[0m \u001b[43m \u001b[49m\u001b[43mn_samples_bootstrap\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mn_samples_bootstrap\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 505\u001b[0m \u001b[43m \u001b[49m\u001b[43mmissing_values_in_feature_mask\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmissing_values_in_feature_mask\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 506\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 507\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mi\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mt\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43menumerate\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mtrees\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 508\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 510\u001b[0m \u001b[38;5;66;03m# Collect newly grown trees\u001b[39;00m\n\u001b[0;32m 511\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mestimators_\u001b[38;5;241m.\u001b[39mextend(trees)\n", "File \u001b[1;32mc:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\sklearn\\utils\\parallel.py:74\u001b[0m, in \u001b[0;36mParallel.__call__\u001b[1;34m(self, iterable)\u001b[0m\n\u001b[0;32m 69\u001b[0m config \u001b[38;5;241m=\u001b[39m get_config()\n\u001b[0;32m 70\u001b[0m iterable_with_config \u001b[38;5;241m=\u001b[39m (\n\u001b[0;32m 71\u001b[0m (_with_config(delayed_func, config), args, kwargs)\n\u001b[0;32m 72\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m delayed_func, args, kwargs \u001b[38;5;129;01min\u001b[39;00m iterable\n\u001b[0;32m 73\u001b[0m )\n\u001b[1;32m---> 74\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;21;43m__call__\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43miterable_with_config\u001b[49m\u001b[43m)\u001b[49m\n", "File \u001b[1;32mc:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\joblib\\parallel.py:1918\u001b[0m, in \u001b[0;36mParallel.__call__\u001b[1;34m(self, iterable)\u001b[0m\n\u001b[0;32m 1916\u001b[0m output \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_sequential_output(iterable)\n\u001b[0;32m 1917\u001b[0m \u001b[38;5;28mnext\u001b[39m(output)\n\u001b[1;32m-> 1918\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m output \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mreturn_generator \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28;43mlist\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43moutput\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1920\u001b[0m \u001b[38;5;66;03m# Let's create an ID that uniquely identifies the current call. If the\u001b[39;00m\n\u001b[0;32m 1921\u001b[0m \u001b[38;5;66;03m# call is interrupted early and that the same instance is immediately\u001b[39;00m\n\u001b[0;32m 1922\u001b[0m \u001b[38;5;66;03m# re-used, this id will be used to prevent workers that were\u001b[39;00m\n\u001b[0;32m 1923\u001b[0m \u001b[38;5;66;03m# concurrently finalizing a task from the previous call to run the\u001b[39;00m\n\u001b[0;32m 1924\u001b[0m \u001b[38;5;66;03m# callback.\u001b[39;00m\n\u001b[0;32m 1925\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock:\n", "File \u001b[1;32mc:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\joblib\\parallel.py:1847\u001b[0m, in \u001b[0;36mParallel._get_sequential_output\u001b[1;34m(self, iterable)\u001b[0m\n\u001b[0;32m 1845\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mn_dispatched_batches \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[0;32m 1846\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mn_dispatched_tasks \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[1;32m-> 1847\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1848\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mn_completed_tasks \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[0;32m 1849\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mprint_progress()\n", "File \u001b[1;32mc:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\sklearn\\utils\\parallel.py:136\u001b[0m, in \u001b[0;36m_FuncWrapper.__call__\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 134\u001b[0m config \u001b[38;5;241m=\u001b[39m {}\n\u001b[0;32m 135\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m config_context(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mconfig):\n\u001b[1;32m--> 136\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfunction\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", "File \u001b[1;32mc:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\sklearn\\ensemble\\_forest.py:192\u001b[0m, in \u001b[0;36m_parallel_build_trees\u001b[1;34m(tree, bootstrap, X, y, sample_weight, tree_idx, n_trees, verbose, class_weight, n_samples_bootstrap, missing_values_in_feature_mask)\u001b[0m\n\u001b[0;32m 189\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m class_weight \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mbalanced_subsample\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[0;32m 190\u001b[0m curr_sample_weight \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m=\u001b[39m compute_sample_weight(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mbalanced\u001b[39m\u001b[38;5;124m\"\u001b[39m, y, indices\u001b[38;5;241m=\u001b[39mindices)\n\u001b[1;32m--> 192\u001b[0m \u001b[43mtree\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_fit\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 193\u001b[0m \u001b[43m \u001b[49m\u001b[43mX\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 194\u001b[0m \u001b[43m \u001b[49m\u001b[43my\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 195\u001b[0m \u001b[43m \u001b[49m\u001b[43msample_weight\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcurr_sample_weight\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 196\u001b[0m \u001b[43m \u001b[49m\u001b[43mcheck_input\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[0;32m 197\u001b[0m \u001b[43m \u001b[49m\u001b[43mmissing_values_in_feature_mask\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmissing_values_in_feature_mask\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 198\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 199\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 200\u001b[0m tree\u001b[38;5;241m.\u001b[39m_fit(\n\u001b[0;32m 201\u001b[0m X,\n\u001b[0;32m 202\u001b[0m y,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 205\u001b[0m missing_values_in_feature_mask\u001b[38;5;241m=\u001b[39mmissing_values_in_feature_mask,\n\u001b[0;32m 206\u001b[0m )\n", "File \u001b[1;32mc:\\storage\\university\\3 course\\AIM\\AIM-PIbd-32-Chubykina-P-P\\aimenv\\Lib\\site-packages\\sklearn\\tree\\_classes.py:472\u001b[0m, in \u001b[0;36mBaseDecisionTree._fit\u001b[1;34m(self, X, y, sample_weight, check_input, missing_values_in_feature_mask)\u001b[0m\n\u001b[0;32m 461\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 462\u001b[0m builder \u001b[38;5;241m=\u001b[39m BestFirstTreeBuilder(\n\u001b[0;32m 463\u001b[0m splitter,\n\u001b[0;32m 464\u001b[0m min_samples_split,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 469\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmin_impurity_decrease,\n\u001b[0;32m 470\u001b[0m )\n\u001b[1;32m--> 472\u001b[0m \u001b[43mbuilder\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbuild\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtree_\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mX\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msample_weight\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmissing_values_in_feature_mask\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 474\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mn_outputs_ \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m1\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m is_classifier(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m 475\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mn_classes_ \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mn_classes_[\u001b[38;5;241m0\u001b[39m]\n", "\u001b[1;31mKeyboardInterrupt\u001b[0m: " ] } ], "source": [ "import pandas as pd\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.ensemble import RandomForestClassifier\n", "from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score\n", "from sklearn.model_selection import cross_val_score\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "\n", "# Загрузка данных\n", "df = pd.read_csv(\"..//static//csv//heart_2020_cleaned.csv\")\n", "\n", "# Разделение на обучающую и тестовую выборки (например, 70% обучающая, 30% тестовая)\n", "train_df, test_df = train_test_split(df, test_size=0.3, random_state=42)\n", "\n", "# Разделение обучающей выборки на обучающую и контрольную (например, 70% обучающая, 30% контрольная)\n", "train_df, val_df = train_test_split(train_df, test_size=0.3, random_state=42)\n", "\n", "# Вывод размеров выборок\n", "print(\"Размер обучающей выборки:\", len(train_df))\n", "print(\"Размер контрольной выборки:\", len(val_df))\n", "print(\"Размер тестовой выборки:\", len(test_df))\n", "\n", "# Определение категориальных признаков\n", "categorical_features = [\n", " 'Smoking', 'AlcoholDrinking', 'Stroke', 'DiffWalking', 'Sex', 'AgeCategory', 'Race',\n", " 'Diabetic', 'PhysicalActivity', 'GenHealth', 'Asthma', 'KidneyDisease', 'SkinCancer'\n", "]\n", "\n", "# Применение one-hot encoding к обучающей выборке\n", "train_df_encoded = pd.get_dummies(train_df, columns=categorical_features)\n", "\n", "# Применение one-hot encoding к контрольной выборке\n", "val_df_encoded = pd.get_dummies(val_df, columns=categorical_features)\n", "\n", "# Применение one-hot encoding к тестовой выборке\n", "test_df_encoded = pd.get_dummies(test_df, columns=categorical_features)\n", "\n", "# Определение сущностей\n", "es = ft.EntitySet(id='heart_data')\n", "es = es.add_dataframe(dataframe_name='heart', dataframe=train_df_encoded, index='id')\n", "\n", "# Генерация признаков\n", "feature_matrix, feature_defs = ft.dfs(entityset=es, target_dataframe_name='heart', max_depth=2)\n", "\n", "# Преобразование признаков для контрольной и тестовой выборок\n", "val_feature_matrix = ft.calculate_feature_matrix(features=feature_defs, entityset=es, instance_ids=val_df_encoded.index)\n", "test_feature_matrix = ft.calculate_feature_matrix(features=feature_defs, entityset=es, instance_ids=test_df_encoded.index)\n", "\n", "# Удаление строк с NaN\n", "feature_matrix = feature_matrix.dropna()\n", "val_feature_matrix = val_feature_matrix.dropna()\n", "test_feature_matrix = test_feature_matrix.dropna()\n", "\n", "# Разделение данных на обучающую и тестовую выборки\n", "X_train = feature_matrix.drop('HeartDisease', axis=1)\n", "y_train = feature_matrix['HeartDisease']\n", "X_val = val_feature_matrix.drop('HeartDisease', axis=1)\n", "y_val = val_feature_matrix['HeartDisease']\n", "X_test = test_feature_matrix.drop('HeartDisease', axis=1)\n", "y_test = test_feature_matrix['HeartDisease']\n", "\n", "# Выбор модели\n", "model = RandomForestClassifier(random_state=42)\n", "\n", "# Обучение модели\n", "model.fit(X_train, y_train)\n", "\n", "# Предсказание и оценка\n", "y_pred = model.predict(X_test)\n", "\n", "accuracy = accuracy_score(y_test, y_pred)\n", "precision = precision_score(y_test, y_pred)\n", "recall = recall_score(y_test, y_pred)\n", "f1 = f1_score(y_test, y_pred)\n", "roc_auc = roc_auc_score(y_test, y_pred)\n", "\n", "print(f\"Accuracy: {accuracy}\")\n", "print(f\"Precision: {precision}\")\n", "print(f\"Recall: {recall}\")\n", "print(f\"F1 Score: {f1}\")\n", "print(f\"ROC AUC: {roc_auc}\")\n", "\n", "# Кросс-валидация\n", "scores = cross_val_score(model, X_train, y_train, cv=5, scoring='accuracy')\n", "accuracy_cv = scores.mean()\n", "print(f\"Cross-validated Accuracy: {accuracy_cv}\")\n", "\n", "# Анализ важности признаков\n", "feature_importances = model.feature_importances_\n", "feature_names = X_train.columns\n", "\n", "importance_df = pd.DataFrame({'Feature': feature_names, 'Importance': feature_importances})\n", "importance_df = importance_df.sort_values(by='Importance', ascending=False)\n", "\n", "plt.figure(figsize=(10, 6))\n", "sns.barplot(x='Importance', y='Feature', data=importance_df)\n", "plt.title('Feature Importance')\n", "plt.show()\n", "\n", "# Проверка на переобучение\n", "y_train_pred = model.predict(X_train)\n", "\n", "accuracy_train = accuracy_score(y_train, y_train_pred)\n", "precision_train = precision_score(y_train, y_train_pred)\n", "recall_train = recall_score(y_train, y_train_pred)\n", "f1_train = f1_score(y_train, y_train_pred)\n", "roc_auc_train = roc_auc_score(y_train, y_train_pred)\n", "\n", "print(f\"Train Accuracy: {accuracy_train}\")\n", "print(f\"Train Precision: {precision_train}\")\n", "print(f\"Train Recall: {recall_train}\")\n", "print(f\"Train F1 Score: {f1_train}\")\n", "print(f\"Train ROC AUC: {roc_auc_train}\")\n", "\n", "# Визуализация результатов\n", "plt.figure(figsize=(10, 6))\n", "plt.scatter(y_test, y_pred, alpha=0.5)\n", "plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'k--', lw=2)\n", "plt.xlabel('Actual HeartDisease')\n", "plt.ylabel('Predicted HeartDisease')\n", "plt.title('Actual vs Predicted HeartDisease')\n", "plt.show()" ] } ], "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 }