{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Лабораторная 3\n", "\n", "Датасет: Информация об онлайн обучении учеников" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Index(['Education Level', 'Institution Type', 'Gender', 'Age', 'Device',\n", " 'IT Student', 'Location', 'Financial Condition', 'Internet Type',\n", " 'Network Type', 'Flexibility Level'],\n", " dtype='object')\n" ] } ], "source": [ "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import seaborn as sns\n", "import featuretools as ft\n", "import time\n", "import math\n", "from imblearn.over_sampling import RandomOverSampler\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score\n", "from sklearn.ensemble import RandomForestClassifier\n", "from sklearn.model_selection import cross_val_score\n", "from sklearn.metrics import r2_score, mean_absolute_error, mean_squared_error\n", "\n", "df = pd.read_csv(\"..\\\\static\\\\csv\\\\students_adaptability_level_online_education.csv\")\n", "print(df.columns)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Столбцы:\n", "\n", "Education Level - уровень образования\\\n", "Institution Type - тип учреждения\\\n", "Gender - пол\\\n", "Age - возраст\\\n", "Device - устройство\\\n", "IT Student - ученик IT направления или нет\\\n", "Location - локация\\\n", "Financial Condition - финансовое состояние\\\n", "Internet Type - тип доступа к сети\\\n", "Network Type - уровень сети\\\n", "Flexibility Level - уровень приспособления" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "RangeIndex: 1205 entries, 0 to 1204\n", "Data columns (total 11 columns):\n", " # Column Non-Null Count Dtype \n", "--- ------ -------------- ----- \n", " 0 Education Level 1205 non-null object\n", " 1 Institution Type 1205 non-null object\n", " 2 Gender 1205 non-null object\n", " 3 Age 1205 non-null int64 \n", " 4 Device 1205 non-null object\n", " 5 IT Student 1205 non-null object\n", " 6 Location 1205 non-null object\n", " 7 Financial Condition 1205 non-null object\n", " 8 Internet Type 1205 non-null object\n", " 9 Network Type 1205 non-null object\n", " 10 Flexibility Level 1205 non-null object\n", "dtypes: int64(1), object(10)\n", "memory usage: 103.7+ KB\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Education LevelInstitution TypeGenderAgeDeviceIT StudentLocationFinancial ConditionInternet TypeNetwork TypeFlexibility Level
0UniversityPrivateMale23TabNoTownMidWifi4GModerate
1UniversityPrivateFemale23MobileNoTownMidMobile Data4GModerate
2CollegePublicFemale18MobileNoTownMidWifi4GModerate
3SchoolPrivateFemale11MobileNoTownMidMobile Data4GModerate
4SchoolPrivateFemale18MobileNoTownPoorMobile Data3GLow
\n", "
" ], "text/plain": [ " Education Level Institution Type Gender Age Device IT Student Location \\\n", "0 University Private Male 23 Tab No Town \n", "1 University Private Female 23 Mobile No Town \n", "2 College Public Female 18 Mobile No Town \n", "3 School Private Female 11 Mobile No Town \n", "4 School Private Female 18 Mobile No Town \n", "\n", " Financial Condition Internet Type Network Type Flexibility Level \n", "0 Mid Wifi 4G Moderate \n", "1 Mid Mobile Data 4G Moderate \n", "2 Mid Wifi 4G Moderate \n", "3 Mid Mobile Data 4G Moderate \n", "4 Poor Mobile Data 3G Low " ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.info()\n", "df.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Примеры бизнес-целей для датасета:\n", "1. Улучшение доступа к онлайн-образованию для учеников с низким уровнем финансового обеспечения.\n", "2. Повышение удовлетворенности учеников онлайн-обучением на основе их устройств, типу соединения, местоположения." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Цели технического проекта:\n", "\n", "1. Провести анализ зависимости учеников от уровня интернет-соединения и устройств\n", "2. Провести анализ влияния различных факторов (тип устройства, интернет-соединение, финансовое положение) на уровень приспособленности." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Проверяем на выбросы." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Пустые значения по столбцам:\n", "Education Level 0\n", "Institution Type 0\n", "Gender 0\n", "Age 0\n", "Device 0\n", "IT Student 0\n", "Location 0\n", "Financial Condition 0\n", "Internet Type 0\n", "Network Type 0\n", "Flexibility Level 0\n", "dtype: int64\n", "\n", "Количество дубликатов: 980\n", "\n", "Статистический обзор данных:\n", "\n", "Коэффициент асимметрии для столбца 'Age': 0.024342017300169792\n" ] } ], "source": [ "null_values = df.isnull().sum()\n", "print(\"Пустые значения по столбцам:\")\n", "print(null_values)\n", "\n", "duplicates = df.duplicated().sum()\n", "print(f\"\\nКоличество дубликатов: {duplicates}\")\n", "\n", "print(\"\\nСтатистический обзор данных:\")\n", "df.describe()\n", "\n", "for column in df.select_dtypes(include=[np.number]).columns:\n", " skewness = df[column].skew()\n", " print(f\"\\nКоэффициент асимметрии для столбца '{column}': {skewness}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Выбросы незначительны, дубликаты есть. Удаляем дубликаты и очищаем от шумов." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Шумы в датасете:\n", "Empty DataFrame\n", "Columns: [Education Level, Institution Type, Gender, Age, Device, IT Student, Location, Financial Condition, Internet Type, Network Type, Flexibility Level]\n", "Index: []\n" ] } ], "source": [ "cleaned_df = df.drop_duplicates()\n", "\n", "Q1 = df[\"Age\"].quantile(0.25)\n", "Q3 = df[\"Age\"].quantile(0.75)\n", "\n", "IQR = Q3 - Q1\n", "\n", "threshold = 1.5 * IQR\n", "lower_bound = Q1 - threshold\n", "upper_bound = Q3 + threshold\n", "\n", "outliers = (df[\"Age\"] < lower_bound) | (df[\"Age\"] > upper_bound)\n", "\n", "print(\"Шумы в датасете:\")\n", "print(df[outliers])\n", "\n", "median_score = df[\"Age\"].median()\n", "df.loc[outliers, \"Age\"] = median_score" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Преобразуем строковые значение в столбце \"Уровень приспособления\" в числовые значения. Это понадобится для расчёта качества набора признаков." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "map_flexibility_to_int = {'Low': 0, 'Moderate': 1, 'High': 2}\n", "\n", "df['Flexibility Level'] = df['Flexibility Level'].map(map_flexibility_to_int).astype('int32')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Шумов в датасете нет. Разбиваем датасет на три выборки: обучающую, контрольную и тестовую." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Размер обучающей выборки: (723, 10)\n", "Размер контрольной выборки: (241, 10)\n", "Размер тестовой выборки: (241, 10)\n" ] } ], "source": [ "X = df.drop(columns=['Flexibility Level'])\n", "Y = df['Flexibility Level']\n", "\n", "X_train_df, X_test_df, Y_train_df, Y_test_df = train_test_split(X, Y, test_size=0.2, random_state=42)\n", "\n", "X_train_df, X_val_df, Y_train_df, Y_val_df = train_test_split(X_train_df, Y_train_df, test_size=0.25, random_state=42)\n", "\n", "print(\"Размер обучающей выборки:\", X_train_df.shape)\n", "print(\"Размер контрольной выборки:\",X_val_df.shape)\n", "print(\"Размер тестовой выборки:\", X_test_df.shape)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Проверка сбалансированности данных." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Распределение классов в обучающей выборке:\n", "Flexibility Level\n", "1 0.531120\n", "0 0.385892\n", "2 0.082988\n", "Name: proportion, dtype: float64\n", "\n", "Распределение классов в контрольной выборке:\n", "Flexibility Level\n", "1 0.522822\n", "0 0.406639\n", "2 0.070539\n", "Name: proportion, dtype: float64\n", "\n", "Распределение классов в тестовой выборке:\n", "Flexibility Level\n", "1 0.477178\n", "0 0.427386\n", "2 0.095436\n", "Name: proportion, dtype: float64\n" ] }, { "data": { "image/png": "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Nzc3/fDDDw5npma1TUk6cuSIpEtngOa0zRIlSmj27NlZ3n5lAN2gQQO99tprDssmTZqkr7/+Osv1d+zYoY8++kizZs3Kcq5vm82mu+66S2PHjs1y/ZCQkGxrz1SzZk298847kqSjR4/q3XffVbNmzbRx48Ycjz23Zs2apR49eqhDhw4aMmSISpQoIQ8PD8XFxdnnj7/cxIkTlZKSou3btysuLk5PPfWUZs2a5TDmyJEjWQbL2XnxxRcVFRWlFi1aOP3opCRNmTJF7du3V6NGja66rfbt2zv9IOXLL79sf75crnfv3urUqZMyMjK0Y8cOjRgxQh06dNC2bduy3f6xY8e0fv16SdL27dtls9kcPqjKSatWrTRkyBBJl85QHz16tJo3b67169c7nPF8LXVdvp6rrF69Wq+//rrWrVunQYMGqXXr1g7fOFixYoXatWunJk2a6L333lPJkiVVsGBBxcfH69NPP3Xa3vXcxwAAAPkNQTcAALhtzZ8/X82bN3c6K/Wff/5xCI/Kly+vNWvW6MKFCzfkBxUzZZ6xnckYoz///FM1a9a071eSChcurMjIyKtu7/fff9eFCxdyDPczt2uMUbly5exnjuZk+/btcnNzy/IM1cu3uWTJEjVu3DhXgWBAQIDTMeX0g5FDhw5V7dq19eijj2a7/99//1333XdfnqeTueOOOxxqatasmUqVKqX4+Phsf1A00+HDh5WamupwVvcff/whSQoLC5N06fl255136ssvv3SoMfOM4ivVq1dPknT//ferRIkS6t69u1566SVVrVpV0qWpVv7880+1bt06V8e3YMECJSQkZDlNSqb69etr79692rx5s06fPi1Jmjlzpj755BOnsWXKlHF6DMePH59l0F2xYkX72KioKJ09e1YvvfRSjj/02a9fP50+fVpxcXEaOnSoxo8fr8GDB+fqWEuWLOlQW+XKldWoUSMtWLBAXbt2zVNdmWfd79q1y+EMbJvNpt27d6tOnTqS/ndG+65du+xT52TatWuX0wcTNptNe/fudfi/eOVzJ1PPnj01bNgwHT58WNWqVdOgQYMcHpsvvvhC3t7e+vHHHx2mtImPj8/yfrqe+xgAACC/4eN6AABw2/Lw8HCal3fevHk6dOiQw7KHH35YKSkpmjRpktM2cjuvb1ZmzpxpDxOlS0Ho33//rfvvv1+SFB4ervLl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jPz8/PTss8867fPgwYPy8PBQXFycJKlHjx5Zfp3Wzc1NI0aMsF//66+/1LdvX1WuXFk+Pj4qXry4OnXqpH379jmst3z5crm5uWn58uX2ZevWrVPLli1VqFAh+fn5qVmzZlqxYoXDeh999JHc3Ny0fv16+7KUlBSnOiSpbdu2TjWvWLFCnTp1UtmyZeXl5aWQkBANGjRI586dczq2+fPnq27duipUqJDc3Nzsl7fffttpbFY1Zl58fX1111136YMPPnAY16NHD/n7++e4rSuPKzePa6bk5GQ98cQTCgoKkre3t2rVqqWPP/7YYcy+ffvsxzRu3DiFhobKx8dHTZs21datW53qvfL+nDVrltzd3fXmm2/al23evFk9evTQnXfeKW9vbwUHB6tnz546duxYjscKAFa2adMmtW/fXiVLltSPP/6YZcg9b948hYeHy8fHRwEBAfrPf/6jQ4cOOYzJrjfMnz/foW82a9bModdkdcnk5uam/v37a/bs2apcubK8vb0VHh6uX375xWk/v/32m+6//34VLlxY/v7+uu+++7R69eosjzm7Gj766COHMTVq1Ljq/ZdZ45Wy6uVvv/22GjVqpOLFi8vHx0fh4eGaP3++07pnzpzRc889pzvvvFMFCxZ0qDElJSXHeq48toCAALVp08apN2ZXd6bM1wSZr4PWrVsnm82m9PR01a1bV97e3ipevLi6du2q/fv3O63/008/KSIiQn5+fipatKjat2+vHTt2OIwZMWKE3NzctHPnTnXu3FmFCxdW8eLF9eyzz+r8+fNO9V7+uuLixYt64IEHVKxYMW3fvt2+PD4+Xi1atFCJEiXk5eWlatWq6f3338/xPgMAXJKWlqbY2FhVqFDB/p7zhRdeUFpamtPYWbNmqX79+vL19dUdd9yhJk2aaNGiRZKksLCwHPv85f0xNTVVzz33nEJCQuTl5aXKlSvr7bffdgrjL1/fw8NDpUuXVu/evfXPP//Yx6Snp2v48OEKDw9XkSJF5Ofnp4iICC1btsyp/sz3nGXLlpWHh4d921d7n3vl8bm7uys4OFiPPvqoQz+8/P1qdjL7YKbVq1fL29tbe/bsUfXq1eXl5aXg4GD16dNHx48fd1r/Wl6f7d27V1FRUfLz81OpUqU0atQoh/s4s97LXwudPn1a4eHhKleunP7++2/78ty+ngGywtQlsLRvvvlGYWFhioiIyPL2Jk2aKCwsTN9995192bFjxzRt2jT5+/trwIABCgwM1KxZs9SxY0fNnj1bXbt2lb+/vx566CHNnTtXY8eOdfh69WeffSZjjLp163ZNta5bt06//vqrunTpojJlymjfvn16//331axZM23fvl2+vr5Zrvfnn3+qWbNm8vX11ZAhQ+Tr66vp06crMjJSixcvVpMmTa6pjuzMmzdPZ8+e1dNPP63ixYtr7dq1mjhxog4ePKh58+bZxyUkJKhz586qVauW3nzzTRUpUkQpKSkaNGhQrvc1btw4BQQE6NSpU5oxY4Z69eqlsLAwRUZG5rn+3DyuknTu3Dk1a9ZMf/75p/r3769y5cpp3rx56tGjh/755x+nDzdmzpyp06dPq1+/fjp//rwmTJigFi1aaMuWLQoKCsqylkWLFqlnz57q37+/wzQqixcv1t69exUTE6Pg4GBt27ZN06ZN07Zt27R69epcz3EHAFaxZ88etW7dWl5eXvrxxx9VsmRJpzGZZ4DXq1dPcXFxSkpK0oQJE7Rq1Sr99ttvKlq06DXt86WXXtKTTz4pSfb+1Lt372xfK/z888+aO3euBgwYIC8vL7333ntq3bq11q5daw+it23bpoiICBUuXFgvvPCCChYsqKlTp6pZs2b6+eef1aBBA6ftVqlSRS+99JJDHTfbhAkT1K5dO3Xr1k3p6emaM2eOOnXqpG+//VZt2rSxjxsyZIimTJmiJ554Qo0bN1bBggX15Zdf6quvvsrVfjKPzRijPXv2aOzYsXrggQeyDKRzK/ND3/79+ys8PFxvvvmmjh49qnfffVcrV67Ub7/9poCAAEnSkiVLdP/99+vOO+/UiBEjdO7cOU2cOFGNGzfWxo0bnT4A6Ny5s8LCwhQXF6fVq1fr3Xff1YkTJzRz5sxs63nyySe1fPlyLV68WNWqVbMvf//991W9enW1a9dOBQoU0DfffKO+ffvKZrOpX79+eT5+APi3s9lsateunVauXKnevXuratWq2rJli8aNG6c//vjD4QSlkSNHasSIEWrUqJFGjRolT09PrVmzRj/99JNatWql8ePH68yZM5KkHTt26I033tCwYcPsU6RkhsnGGLVr107Lli3TE088odq1a+vHH3/UkCFDdOjQIY0bN86hxoceekgdO3bUxYsXlZCQoGnTpuncuXP2qVhOnTql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Nzc3denSJcuznN5++21VrFgxy7OJbrSMjAy1bNlSx48f14svvqgqVarIz89Phw4dUo8ePRzq69KlizZu3KiJEydq2rRpedrfrFmzFBQUpPPnz+unn35Sv3795O3trR49etjHeHt765tvvpF06cOKGTNmaODAgSpZsqQ6d+7stM1reVxvhpSUFPn5+embb75Rhw4dFBcXp9jYWIcxnTt31q+//qohQ4aodu3a8vf3l81mU+vWrXN9phsAWMWYMWPsHwxPmzZN99xzj4YOHar33nsvz9u8vDdkWrFiRbbzP7rKkSNHFBUVddVxYWFhmj59uqRL82a+++67evzxx3XnnXfav/EjSe3bt3f6YceXX35ZR44csV9fsWKF2rVrpyZNmui9995TyZIlVbBgQcXHxzuF59OmTVPXrl0dPri/FjVr1rS/Sc2cR7tZs2bauHGjgoODneo2xigxMVGjRo1S27Zts3wDfiv7eHZnBK5du1a9evWSn5+fXnvtNXXq1MnhTf6ePXt03333qUqVKho7dqxCQkLk6emp77//XuPGjaOXA0AObDab7rrrLo0dOzbL20NCQm5xRc4ef/xxde/eXTabTXv37tWrr76qtm3basmSJXJzc9OsWbPUo0cPdejQQUOGDFGJEiXk4eGhuLg47dmzx2Fbc+fOVbdu3ZxeD/j5+eWqllatWmnIkCGSpIMHD2r06NFq3ry51q9f79Aze/furU6dOikjI0M7duzQiBEj1KFDB23bts1pm65+zyxd+kHM119/XevWrdOgQYPUunVrh2+EXcvrGSArBN2wtLZt22r69OlauXKl7r33XqfbV6xYoX379qlPnz72ZeXKldOuXbucxu7cuVOSHH7AqEaNGqpTp45mz56tMmXKaP/+/Zo4caLTuh9++KGGDx+uPXv22N/ktGzZ0mHM/PnzFR0dbX9jKF36Su/lv+J8ufDwcDVt2lT+/v65rjevtmzZoj/++EMff/yxunfvbl++ePFip7Hu7u56++23tWXLFiUmJuq9995TUlKSw3QuV9O4cWN73W3bttW2bdsUFxfnEHR7eHg4/DhlmzZtVKxYMS1cuDDLoDu3j2toaKg2b94sm83mcFZ35rjQ0FCH9bN6M/7HH3843e++vr5auHChqlSpokGDBumNN95Q586d7WcLnDhxQkuXLtXIkSM1fPjwHLcPAP8Gl/9Ycr169dSvXz9NnjxZ3bt3t4e4mX9zd+3aZf/qcqZdu3Y5/U2+sjdIyraP5lZ2f+d9fX0VGBgo6dLf+Ox6jLu7u8Ob84MHD+r06dP2v/858fPzczieiIgIlS5dWosWLXIIusuUKeN03OPHj3cIur/44gt5e3vrxx9/dJg2JT4+3mm/YWFhmjVrlu666y717NlTHTp00MyZM+0/tnU1d9xxh0M9zZo1U6lSpRQfH6+hQ4dmW7e/v7+6devmMCVapsxvOGX1XNi5c6dDH88cd6WdO3cqICDAKUTYvXu3ffvSpR/6ttlsTr28ZcuWev/993X+/HktWLBAvXv31vLly+3B+DfffKO0tDT93//9n8qWLWtfL/Pr9gCA7JUvX94+FUhOU5CUL19eNptN27dvd/hxx7wIDQ3VkiVLdPr0aYezurN773fnnXc69K0iRYroscce0+rVq9WwYUPNnz9fd955p7788kuHY7jyBCdJqlOnjqZPn66IiAiNGjVK99xzj8aMGaNVq1blqvaSJUs61FK5cmU1atTIfhJepooVK9rHRUVF6ezZs3rppZey/IHoy3vt5Wdg22w27d69W3Xq1HG4X3L7+izzg4HMs7ilS6+lJOe8omfPnho2bJgOHz6satWqadCgQQ6vP67l9QyQFaYugaUNGTJEPj4+6tOnj44dO+Zw2/Hjx/XUU0/J19fX/kmoJD3wwANau3atfv31V/uy8+fP6/3331dwcLDDPJ3SpU91Fy1apPHjx6t48eK6//77s6wlNDRULVq0UGRkpNObUenSm/Mr58yaOHGiMjIysj0+Nzc3tWrVSj/++KN27NjhcGwff/yx6tatq6CgoGzXz63M+bkur88Yk+1UIRMnTtRPP/2k2bNnKzIyUo0bN76u/Z87d+6qX+PKrO3yucQul9vH9YEHHtCRI0c0d+5c+7iLFy9q4sSJ8vf3d5orfMGCBTp06JD9+tq1a7VmzRqn50FgYKD9K2CjRo1SmTJl1KtXL6e6r3wOjB8/PsfjBoB/i9dff10lS5ZU7969dfHiRUlS3bp1VaJECU2ZMsWhD/zwww/asWOH2rRpc9PrSkhIcJjz8cCBA/r666/VqlUreXh4yMPDQ61atdLXX3/t8PXbpKQkffrpp7r33nvt3xqTLn3VWJLTG8PcyPywPLtelxMPDw+5ubk5vK7Yt2+fFixY4DT24sWL6tatm6pXr65x48YpMjLS6SvH1+LcuXOSdNVentPx1alTR8HBwU7PhRUrVmj9+vVq27atpEtv/GvXrq2PP/7Y4UOOrVu3atGiRXrggQectj158mSH65knLVzZyxs1aiQPDw/5+flpypQp+uWXX+xn3F9e9+W9/OTJk7z5BoBc6Ny5sw4dOuTwdzXTuXPn7NNOdejQQe7u7ho1apTTN2VyOwd1pgceeEAZGRmaNGmSw/Jx48bJzc0t2/f2l9cl/a+/ZdUH1qxZo4SEBKd1T506pccff1zt2rXTyy+/rMjISJUsWfKa6s+pluzk1Gvvu+8+eXl56d1333W4b2fPnq2kpCR7r83L67PL72NjjCZNmqSCBQs6zSseEREhSSpVqpRGjx6tWbNmOUzHdi2vZ4CscEY3LK1ixYr6+OOP1a1bN91111164oknVK5cOe3bt08ffvihUlJS9Nlnn6l8+fL2dV544QXNnj1b999/vwYMGKCAgADNmjVL27dv1+zZs1WggON/i8cee0wvvPCCvvrqKz399NMqWLBgnmpt27atPvnkExUpUkTVqlVTQkKClixZctUfqHj11Vf1448/qmnTpnrmmWfk6+ur6dOn659//tH8+fOdxickJNjnCM/8caw///xTCxcutI85evSozp07p4ULF6p169aqUqWKypcvr+eff16HDh1S4cKF9cUXX2Q5Z9a2bdv0wgsvaMSIEapXr16e7osFCxYoICDAPnXJihUrNHDgQIcxGRkZ9ppPnz6t+Ph4paamqkOHDlluM7ePa+/evTV16lT7j3mGhYVp/vz5WrVqlcaPH+80f1uFChV077336umnn1ZaWpr9A48XXngh2+Pz8fHRtGnTFBkZqffff199+/ZV4cKF1aRJE7311lu6cOGC/Yy9xMTEPN2HAGA1hQoV0sSJE9WxY0e98847evHFF1WwYEGNHj1aMTExatq0qbp27aqkpCRNmDBBYWFhGjRo0E2vq0aNGoqKitKAAQPk5eVln1pl5MiR9jGvvfaaFi9erHvvvVd9+/ZVgQIFNHXqVKWlpemtt96SdCn4jo2N1QcffKAuXbpkOdf0lc6cOWPvdcePH9e7776rggUL5ingb9OmjcaOHavWrVvrscceU3JysiZPnqwKFSo4TfM2cuRIbdmyRb/99lueXtckJSVp1qxZki5N3TV16lQVKFDA/gY50/79+7Vw4UL71CWvv/66QkNDVadOHacz6QsUKKC33npL3bt3V0REhLp162afFqVMmTJ68cUX7WPHjBmj+++/Xw0bNtQTTzyhc+fOaeLEiSpSpIhGjBjhVG9iYqLatWun1q1bKyEhQbNmzdJjjz2mWrVqZXuMUVFR+s9//qMXXnhBDz74oEqWLKlWrVrJ09NTDz74oPr06aMzZ85o+vTpKlGihP7+++9rvh8B4Hby+OOP6/PPP9dTTz2lZcuWqXHjxsrIyNDOnTv1+eef68cff1TdunVVoUIFvfTSS3r11VcVERGhjh07ysvLS+vWrVOpUqUUFxeX630++OCDat68uV566SXt27dPtWrV0qJFi/T1119r4MCBDjmBdGna01mzZskYoz179th7UN26dSVdek//5Zdf6qGHHlKbNm2UmJioKVOmqFq1ajpz5ozDtvr166dz585lOa92buzdu9feaw8dOqRJkyapcOHCTsHxrl27tHDhQvtZ8GPGjFG9evVUunRpp20WK1ZML7/8sl555RVFRUWpffv22rt3ryZNmqRatWrpySeflKRrfn3m7e2thQsXKjo6Wg0aNNAPP/yg7777TsOGDbN/Oy4rvXv31qeffqqnnnpKW7dutc8xntvXM0CWDPAvsHnzZtO1a1dTsmRJU7BgQRMcHGy6du1qtmzZkuX4PXv2mEceecQUKVLEeHt7m3r16pkFCxZku/0HHnjASDK//vprrmuSZGJjY+3XT5w4YWJiYkxAQIDx9/c3UVFRZufOnSY0NNRER0fbxy1btsxIMsuWLbMv27Bhg2nVqpXx9/c3vr6+pkmTJubnn3922F98fLyRdM2XTNu3bzeRkZHG39/fBAQEmF69epnff//dSDLx8fHGGGPOnz9vatasae69915z8eJF+7qJiYlGkhkzZkyO98mVNXp6epoKFSqY4cOHm/Pnz9vHRUdHO4zz9/c3d999t/nkk0+yvX+Nyf3jmpSUZH8sPD09zV133WU/xqyO6Z133jEhISHGy8vLREREmN9//91hbHR0tAkNDXXaT0xMjClcuLA5ePCgMcaYgwcPmoceesgULVrUFClSxHTq1MkcPnw4y2MBAKvK/Fu/bt26LG9v37698fX1NXv37rUvmzt3rqlTp47x8vIyxYoVM926dbP/7cwUHR1t/Pz8nLY3b948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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "\n", "def analyze_balance(y_train, y_val, y_test, y_name):\n", " print(\"Распределение классов в обучающей выборке:\")\n", " print(y_train.value_counts(normalize=True))\n", " \n", " print(\"\\nРаспределение классов в контрольной выборке:\")\n", " print(y_val.value_counts(normalize=True))\n", " \n", " print(\"\\nРаспределение классов в тестовой выборке:\")\n", " print(y_test.value_counts(normalize=True))\n", "\n", " fig, axes = plt.subplots(1, 3, figsize=(18, 5), sharey=True)\n", " fig.suptitle('Распределение в различных выборках')\n", "\n", " sns.barplot(x=y_train.value_counts().index, y=y_train.value_counts(normalize=True), ax=axes[0])\n", " axes[0].set_title('Обучающая выборка')\n", " axes[0].set_xlabel(y_name)\n", " axes[0].set_ylabel('Доля')\n", "\n", " sns.barplot(x=y_val.value_counts().index, y=y_val.value_counts(normalize=True), ax=axes[1])\n", " axes[1].set_title('Контрольная выборка')\n", " axes[1].set_xlabel(y_name)\n", "\n", " sns.barplot(x=y_test.value_counts().index, y=y_test.value_counts(normalize=True), ax=axes[2])\n", " axes[2].set_title('Тестовая выборка')\n", " axes[2].set_xlabel(y_name)\n", "\n", " plt.show()\n", "\n", "analyze_balance(Y_train_df, Y_val_df, Y_test_df, 'Flexibility Level')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Выполним оверсемплинг для балансировки." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Распределение классов в обучающей выборке:\n", "Flexibility Level\n", "2 0.333333\n", "0 0.333333\n", "1 0.333333\n", "Name: proportion, dtype: float64\n", "\n", "Распределение классов в контрольной выборке:\n", "Flexibility Level\n", "1 0.333333\n", "0 0.333333\n", "2 0.333333\n", "Name: proportion, dtype: float64\n", "\n", "Распределение классов в тестовой выборке:\n", "Flexibility Level\n", "1 0.477178\n", "0 0.427386\n", "2 0.095436\n", "Name: proportion, dtype: float64\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABboAAAHyCAYAAAAtJXgGAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABt6klEQVR4nO3deXhMZ//H8U8SsltKSCyRqH2ppbEUjTVEG0W1lHoqokWLKlrtQ1tBl1S1StFaWulCS2mrv25qKS0ae9WuaqeViF2QkLl/f7gyjzFJRITJqffruua6zJn7nPM9MyPfmc+cucfNGGMEAAAAAAAAAIBFubu6AAAAAAAAAAAAbgRBNwAAAAAAAADA0gi6AQAAAAAAAACWRtANAAAAAAAAALA0gm4AAAAAAAAAgKURdAMAAAAAAAAALI2gGwAAAAAAAABgaQTdAAAAAAAAAABLI+gGAAAAgFyw2WxKTk7Wnj17XF0KAADAbY+gGwAAAABy6MiRIxo0aJBCQkLk6empEiVKqHr16jp9+rSrSwMAALitFXB1AQAAAHnto48+UkxMjP26l5eXypUrpzZt2ujll19WYGCgC6sDYFV//fWXWrRooYsXL2rgwIG6++67VaBAAfn4+MjPz8/V5QEAANzWCLoBAMC/1ujRo1W+fHlduHBBK1as0Pvvv68ffvhBW7Zska+vr6vLA2Axffv2laenp1atWqUyZcq4uhwAAABcgaAbAAD8a913332qV6+eJOmJJ55Q8eLFNW7cOH3zzTfq1q2bi6sDYCXr16/Xzz//rIULFxJyAwAA5EPM0Q0AAG4bLVu2lCTt3btXknT8+HE999xzuuuuu+Tv76/ChQvrvvvu0x9//OG07oULFzRy5EhVrlxZ3t7eKlWqlDp16qTdu3dLkvbt2yc3N7csL82bN7dva9myZXJzc9OcOXM0fPhwBQUFyc/PT+3bt9fBgwed9r169Wq1bdtWRYoUka+vr5o1a6aVK1dmeozNmzfPdP8jR450Gjtz5kyFhYXJx8dHxYoVU9euXTPdf3bHdiWbzabx48erRo0a8vb2VmBgoPr27asTJ044jAsNDVW7du2c9jNgwACnbWZW+9ixY53uU0lKTU1VbGysKlasKC8vLwUHB+v5559XampqpvfVla6+3wICAhQVFaUtW7bkaN2aNWtq/fr1aty4sXx8fFS+fHlNmTLFYVxaWppGjBihsLAwFSlSRH5+fgoPD9fSpUsdxu3cuVMtW7ZUUFCQ/TiefPJJHT9+3GnfPXv2vObj3bNnT4WGhjqsd/DgQfn4+MjNzU379u2T9L/H+aOPPnIYO3LkyEwflwEDBjjV065dO4d9ZWzzrbfeyuLec95+fHy83NzcNGPGDIdxr7/+utzc3PTDDz9kuS3p8vMr435wd3dXUFCQHnnkER04cOCG6lq1apW8vb21e/du1ahRQ15eXgoKClLfvn0zfWzmzp1r//8VEBCg//znPzp8+LDDmJ49e8rf31979uxRZGSk/Pz8VLp0aY0ePVrGGKd6r3xszpw5o7CwMJUvX17//POPfflbb72lxo0bq3jx4vLx8VFYWJjmzZvnsN8bvY8BAADyI87oBgAAt42MULp48eKSpD179mj+/Pnq3Lmzypcvr8TERE2dOlXNmjXTtm3bVLp0aUlSenq62rVrpyVLlqhr16565plndObMGS1atEhbtmxRhQoV7Pvo1q2b7r//fof9Dhs2LNN6XnvtNbm5uemFF15QUlKSxo8fr4iICG3cuFE+Pj6SpJ9//ln33XefwsLCFBsbK3d3d8XHx6tly5Zavny5GjRo4LTdsmXLKi4uTpJ09uxZPfXUU5nu++WXX1aXLl30xBNP6OjRo5o4caKaNm2q33//XUWLFnVap0+fPgoPD5ckffXVV/r6668dbu/bt699fvSBAwdq7969mjRpkn7//XetXLlSBQsWzPR+uB4nT560H9uVbDab2rdvrxUrVqhPnz6qVq2aNm/erHfeeUd//vmn5s+ff81tV61aVS+++KKMMdq9e7fGjRun+++/3yEgzcqJEyd0//33q0uXLurWrZu++OILPfXUU/L09FSvXr0kSadPn9YHH3ygbt26qXfv3jpz5ow+/PBDRUZGas2aNapTp44kKSUlRWXLltUDDzygwoULa8uWLZo8ebIOHz6sb7/91mnfAQEBeuedd+zXH3vssWvWO2LECF24cOGa41whJiZGX331lYYMGaLWrVsrODhYmzdv1qhRo/T44487/f/KTHh4uPr06SObzaYtW7Zo/Pjx+vvvv7V8+fJc13Xs2DFduHBBTz31lFq2bKknn3xSu3fv1uTJk7V69WqtXr1aXl5ekv73OwH169dXXFycEhMTNWHCBK1cudLp/1d6erratm2r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xx8dzkzNbJuSdOTIEUmXzwDNbpslS5bUrFmzMr396gC6YcOGevXVVx2WTZo0Sd98802m62/fvl0fffSRZs6cmelc3zabTXfddZfGjRuX6frBwcFZ1p6hVq1aevvttyVJR48e1bvvvqvmzZtrw4YN2R57Ts2cOVM9e/ZUx44dNXToUJUsWVIeHh6Ki4uzzx9/pYkTJyo5OVnbtm1TXFycnnzySc2cOdNhzJEjRzINlrPywgsvKDIyUi1btnT60UlJmjJlijp06KDGjRtfc1sdOnRw+kHKl156yf58uVKfPn3UuXNnpaena/v27Ro5cqQ6duyorVu3Zrn9Y8eOad26dZKkbdu2yWazOXxQlZ02bdpo6NChki6foT5mzBi1aNFC69atczjj+XrqunI9V1m1apVee+01rV27VoMHD1bbtm0dvnGwfPlytW/fXk2bNtV7772nUqVKqWDBgoqPj9dnn33mtL0buY8BAADyG4JuAABw25o3b55atGjhdFbqyZMnHcKjChUqaPXq1bp48WKe/KBihowztjMYY/TXX3+pVq1a9v1KUuHChRUREXHN7f3xxx+6ePFituF+xnaNMSpfvrz9zNHsbNu2TW5ubpmeoXrlNhcvXqwmTZrkKBAMCAhwOqbsfjBy2LBhqlOnjh555JEs9//HH3+oVatWuZ5O5o477nCoqXnz5ipdurTi4+Oz/EHRDH///bdSUlIczur+888/JUmhoaGSLj/f7rzzTn311VcONWacUXy1+vXrS5Luu+8+lSxZUj169NCLL76oatWqSbo81cpff/2ltm3b5uj45s+fr4SEhEynScnQoEED7dmzR5s2bdKZM2ckSZ988ok+/fRTp7Fly5Z1egzHjx+fadBdqVIl+9jIyEidO3dOL774YrY/9Nm/f3+dOXNGcXFxGjZsmMaPH68hQ4bk6FhLlSrlUFuVKlXUuHFjzZ8/X926dctVXRln3e/cudPhDGybzaZdu3apbt26kv53RvvOnTvtU+dk2Llzp9MHEzabTXv27HH4v3j1cydDr169NHz4cP3999+qXr26Bg8e7PDYfPnll/L29tZPP/3kMKVNfHx8pvfTjdzHAAAA+Q0f1wMAgNuWh4eH07y8c+fO1eHDhx2WPfTQQ0pOTtakSZOctpHTeX0z88knn9jDROlyEPrPP//ovvvukySFhYWpQoUKeuut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FR4enuntTZs2VWhoqL7//nv7smPHjmnatGny9/fXwIEDVaJECc2cOVOdOnXSrFmz1K1bN/n7++vBBx/UnDlzNG7cOIevV3/++ecyxqh79+7XVevatWv122+/qWvXripbtqz27dun999/X82bN9e2bdvk6+ub6Xp//fWXmjdvLl9fXw0dOlS+vr6aPn26IiIitGjRIjVt2vS66sjK3Llzde7cOT311FMqXry41qxZo4kTJ+rQoUOaO3eufVxCQoK6dOmi2rVr64033lCRIkWUnJyswYMH53hf77zzjgICAnT69GnNmDFDvXv3VmhoqCIiInJdf04eV0k6f/68mjdvrr/++ksDBgxQ+fLlNXfuXPXs2VMnT550+nDjk08+0ZkzZ9S/f39duHBBEyZMUMuWLbV582YFBgZmWsvChQvVq1cvDRgwwGEalUWLFmnPnj2KiYlRUFCQtm7dqmnTpmnr1q1atWpVjue4AwCr2L17t9q2bSsvLy/99NNPKlWqlNOYjDPA69evr7i4OCUmJmrChAlauXKlfv/9dxUtWvS69vniiy/qiSeekCR7f+rTp0+WrxV++eUXzZkzRwMHDpSXl5fee+89tW3bVmvWrLEH0Vu3blV4eLgKFy6s559/XgULFtTUqVPVvHlz/fLLL2rYsKHTdqtWraoXX3zRoY6bbcKECWrfvr26d++utLQ0zZ49W507d9Z3332nqKgo+7ihQ4dqypQpevzxx9WkSRMVLFhQX331lb7++usc7Sfj2Iwx2r17t8aNG6f7778/00A6pzI+9B0wYIDCwsL0xhtv6OjRo3r33Xe1YsUK/f777woICJAkLV68WPfdd5/uvPNOjRw5UufPn9fEiRPVpEkTbdiwwekDgC5duig0NFRxcXFatWqV3n33XZ04cUKffPJJlvU88cQTWrZsmRYtWqTq1avbl7///vuqUaOG2rdvrwIFCujbb79Vv379ZLPZ1L9//1wfPwD829lsNrVv314rVqxQnz59VK1aNW3evFnvvPOO/vzzT4cTlEaNGqWRI0eqcePGGj16tDw9PbV69Wr9/PPPatOmjcaPH6+zZ89KkrZv367XX39dw4cPt0+RkhEmG2PUvn17LV26VI8//rjq1Kmjn376SUOHDtXhw4f1zjvvONT44IMPqlOnTrp06ZISEhI0bdo0nT9/3j4Vy+nTp/XBBx+oW7du6t27t86cOaMPP/xQkZGRWrNmjerUqWPfVnR0tBYvXqynn35atWvXloeHh6ZNm6YNGzbk6P4KDw9Xnz59ZLPZtGXLFo0fP15///230wlv1+PYsWO6cOGCnnrqKbVs2VJPPvmkdu/ercmTJ2v16tVavXq1vLy8JF3f67P09HS1bdtW99xzj958800tWLBAsbGxunTpkkaPHp1pLRcvXtRDDz2kAwcOaOXKlQ6vEXP6egbIlAEs6uTJk0aS6dChQ7bj2rdvbySZ06dPG2OMkWQkmWXLltnHnDt3zlSrVs0EBQWZtLQ0Y4wxP/30k5FkfvzxR4ft1apVyzRr1sx+PSYmxpQrV85pv5JMbGyswz6ulpCQYCSZTz75xL5s6dKlRpJZunSpMcaYhx56yHh4eJgtW7bYxyQnJ5vixYubsLAw+7L4+Hgjyaxdu9a+7OjRo051GGNMVFSUCQkJcViWWX1xcXHGzc3N7N+/375s2LBhRpL5559/7Mv27t1rJJmxY8c6beNKGTXu3bvXvuzPP/80ksybb75pXxYdHW38/Pyy3dbVx5XTx3X8+PFGkpk5c6Z9XFpammnUqJHx9/e3P08yjsnHx8ccOnTIPnb16tVGkhk8eLBDvRn357p164y/v7/p3LmzSU9Pd6g5s/v4888/N5LMr7/+mu3xAoBVZPyt/+6770yFChWMJNOmTZtMx6alpZmSJUuamjVrmvPnz9uXf/fdd0aSGTFihH1ZVr1h7ty5Dn3zShl/y+Pj4zPdf0bvWLdunX3Z/v37jbe3t3nwwQftyzp27Gg8PT3N7t277cv+/vtvU6hQIdO0aVOn7TZp0sS0aNEi2zqaNWtmatSokWldV9fYv39/p+U56eVpaWmmZs2apmXLlg7LS5UqZSIjIx2WxcbGGknm6NGj2dbTrFkzh9dBxhgzfPhwI8kkJSVds+4MV78myLhevXp1h+PIeF307LPP2pfVqVPHlCxZ0hw7dsy+7I8//jDu7u6mR48eTsfUvn17h33369fPSDJ//PGHQ70ZryuGDRtmPDw8zPz5853qzqyXR0ZGmjvvvDPLYwWA20X//v1NVjHTp59+atzd3c3y5csdlk+ZMsVIMitXrjTGGLNr1y7j7u5uHnzwQaf3UzabzWm7V79/vtL8+fONJPPqq686LH/44YeNm5ub+euvv+zLMnvf3LhxY1O9enX79UuXLpnU1FSHMSdOnDCBgYGmV69e9mXnz5837u7upm/fvg5jc/I+1xhjQkJCTHR0tMOyRx991Pj6+tqv5+Q9eEYfvPp6q1atzKVLl+zLM3rwxIkTjTHX//pMknn66afty2w2m4mKijKenp721xVXvhay2Wyme/fuxtfX16xevdqp7py+ngEyw9QlsKwzZ85IkgoVKpTtuIzbT58+bV9Wv359NWvWzH7dx8dH/fr105EjR+yfsEZERKh06dKaNWuWfdyWLVu0adMm/ec//7EvK1mypJKSkpSWlpZtHT4+PvZ/X7x4UceOHVPFihVVtGjRTD/VPXXqlJKSkrRo0SJFRkY6/ChT8eLF1bNnT61fv16JiYnZ7jenrqwvJSVFycnJaty4sYwx+v333+23nTlzRu7u7td9ht2VTpw4oeTkZO3Zs0fvvPOOPDw8HB6PDMnJyUpOTnb6enFWcvK4/vDDDwoKCrKf4S1JBQsW1MCBA3X27Fn98ssvDtvs2LGjw490NGjQQA0bNtQPP/zgtP89e/YoKipKderU0aeffip3d8c/sVfexxcuXFBycrLuueceScrxJ/sAYBU9e/bUwYMH9eijj2rhwoUO3w7KsG7dOiUlJalfv37y9va2L4+KilLVqlUdvpGVIaM3ZFwyXg/kVqNGjRQWFma/Xq5cOXXo0EE//fST0tPTlZ6eroULF6pjx4723/uQpFKlSunRRx/VihUrHF5jSJe/2pxxRlR20tPT7ceR3euIjJ5x5eXixYtO467sMydOnNCpU6cUHh7u1GPOnDmj4sWLX7O+rFy8eFHJyck6evSoEhIS9PXXX6tWrVr2M66vrvvYsWOy2Ww52nb//v0djqN58+YKCwuzPxf++ecfbdy4UT179lSxYsXs42rVqqXWrVtn2p+vPtP66aeflqRMx06aNElxcXF699131aFDB6fbr6zt1KlTSk5OVrNmzbRnzx6dOnUqR8cIALejuXPnqlq1aqpatapDP2vZsqUk2af/mD9/vmw2m0aMGOH0fup6vwH7ww8/yMPDQwMHDnRY/uyzz8oYox9//NFh+blz55ScnKwjR47oyy+/1B9//KFWrVrZb/fw8JCnp6eky2eoHz9+XJcuXVK9evUcem1KSopsNtsN9drU1FQlJyfbM4Gff/7ZoZaraz5x4kSO50YfMmSIw7fWH3vsMQUGBtp7bW5en105XVnG9GVpaWlavHix09ihQ4dq1qxZ+uKLL9SgQQOn23P6egbIDEE3LCsjwL7WG9zMAvGqVas6jcv4mlPGXJHu7u7q3r275s+fr3PnzkmSZs2aJW9vb3Xu3Nm+XuPGjXXhwgW99NJLOnTokL1hX+38+fMaMWKEfW6wgIAAlShRQidPnsz0jVHHjh0VGBio06dPq0qVKtes90YdOHDA/qbR399fJUqUsIfGV9bXqFEj2Ww2PfPMM9q9e7e9qV6Pu+++WyVKlFCFChU0Y8YMTZo0yanBpaSkqESJEipRooR8fHxUrlw5TZgwIdvt5uRx3b9/vypVquT0oilj3P79+x2WV6pUyWmblStXdrrfU1JSFBkZqcTERB0/fjzTF2HHjx/XM888o8DAQPn4+KhEiRIqX768JPHmGMC/zvHjxzVz5kx9/PHHqlOnjp555hmnv3UZf3Mz63NVq1Z1+pt8ZW/IuPTq1euG6szq7/y5c+d09OhRHT16VOfOncuyF9tsNh08eNBh+cmTJ3M0B+eOHTscel2VKlX02WefOY378MMPnY47Y57SK3333Xe655575O3trWLFiqlEiRJ6//33ne73Ro0a6euvv9a8efP0zz//KDk52f5aJyd+++03lShRQiVLllTjxo116dIlzZ0716n3ZdQdEBAgHx8fNW3a1OG3RK6UsW5WvfzKPi5l/pypVq2akpOTlZKS4rD86se4QoUKcnd3d+rlP/74o30Ks8zmKpWklStXKiIiwj43eIkSJTR8+HBJ9HIAyM6uXbu0detWp35WuXJlSZfntJYuT3vm7u7uMG1Ubu3fv1+lS5d2Ojkuq/d+Y8eOVYkSJVSqVCk9/PDDCg8P15gxYxzGfPzxx6pVq5b9tyRKlCih77//3qEHFC9eXJUqVdIHH3yghQsXKikpScnJyZnORZ6V2bNnq0SJEgoMDFSbNm0UHBzs9NtWkhQbG6sSJUqoWLFi8vX1VVRUlHbt2pXpNrPqtR4eHqpUqVKOem1mr8/c3d0dTgaQZH9cr+61U6dO1dtvvy1JWeYIOX09A2SGObphWUWKFFGpUqW0adOmbMdt2rRJZcqUUeHChSU5fjp4LT169NDYsWM1f/58devWTZ999pnatWvn8ENa7du3V69evTR27FiNHTs2y209/fTTio+P16BBg9SoUSMVKVJEbm5u6tq1a6ZnOb311luqVKlSpmcT5bX09HS1bt1ax48f1wsvvKCqVavKz89Phw8fVs+ePR3q69q1qzZs2KCJEydq2rRpudrfzJkzFRgYqAsXLujnn39W//795e3trZ49e9rHeHt769tvv5V0+cOKGTNmaNCgQSpVqpS6dOnitM3reVxvhuTkZPn5+enbb79Vx44dFRcXp9jYWIcxXbp00W+//aahQ4eqTp068vf3l81mU9u2bXN8phsAWMXYsWPtHwxPmzZN99xzj4YNG6b33nsv19u8sjdkWL58eZbzP7rKkSNHFBkZec1xoaGhmj59uqTL82a+++67euyxx3TnnXfav/EjSR06dHD6YceXXnpJR44csV9fvny52rdvr6ZNm+q9995TqVKlVLBgQcXHxzuF59OmTVO3bt0cPri/HrVq1bK/Sc2YR7t58+basGGDgoKCnOo2xmjv3r0aPXq02rVrl+kb8FvZx7M6I3DNmjXq3bu3/Pz89Oqrr6pz584Ob/J3796tVq1aqWrVqho3bpyCg4Pl6empH374Qe+88w69HACyYbPZdNddd2ncuHGZ3h4cHHyLK3L22GOPqUePHrLZbNqzZ49eeeUVtWvXTosXL5abm5tmzpypnj17qmPHjho6dKhKliwpDw8PxcXFaffu3Q7bmjNnjrp37+70esDPzy9HtbRp00ZDhw6VJB06dEhjxoxRixYttG7dOoee2adPH3Xu3Fnp6enavn27Ro4cqY4dO2rr1q1O23T1e2bp8g9ivvbaa1q7dq0GDx6stm3bOnwj7HpezwCZIeiGpbVr107Tp0/XihUrdO+99zrdvnz5cu3bt099+/a1Lytfvrx27tzpNHbHjh2S5PADRjVr1lTdunU1a9YslS1bVgcOHNDEiROd1v3www81YsQI7d692/4mp3Xr1g5j5s2bp+joaPsbQ+nyV3qv/BXnK4WFhalZs2by9/fPcb25tXnzZv3555/6+OOP1aNHD/vyRYsWOY11d3fXW2+9pc2bN2vv3r167733lJiY6DCdy7U0adLEXne7du20detWxcXFOQTdHh4eDj9OGRUVpWLFimnBggWZBt05fVxDQkK0adMm2Ww2h7O6M8aFhIQ4rJ/Zm/E///zT6X739fXVggULVLVqVQ0ePFivv/66unTpYj9b4MSJE1qyZIlGjRqlESNGZLt9APg3uPLHkuvXr6/+/ftr8uTJ6tGjhz3Ezfibu3PnTvtXlzPs3LnT6W/y1b1BUpZ9NKey+jvv6+urEiVKSLr8Nz6rHuPu7u7w5vzQoUM6c+aM/e9/dvz8/ByOJzw8XGXKlNHChQsdgu6yZcs6Hff48eMdgu4vv/xS3t7e+umnnxymTYmPj3fab2hoqGbOnKm77rpLvXr1UseOHfXJJ5/Yf2zrWu644w6Hepo3b67SpUsrPj5ew4YNy7Juf39/de/e3WFKtAwZ33DK7LmwY8cOhz6eMe5qO3bsUEBAgFOIsGvXLvv2pcs/9G2z2Zx6eevWrfX+++/rwoULmj9/vvr06aNly5bZg/Fvv/1Wqamp+r//+z+VK1fOvl7G1+0BAFmrUKGCfSqQ7KYgqVChgmw2m7Zt2+bw4465ERISosWLF+vMmTMOZ3Vn9d7vzjvvdOhbRYoU0aOPPqpVq1apUaNGmjdvnu6880599dVXDsdw9QlOklS3bl1Nnz5d4eHhGj16tO655x6NHTtWK1euzFHtpUqVcqilSpUqaty4sf0kvAyVKlWyj4uMjNS5c+f04osvZvoD0Vf22ivPwLbZbNq1a5fq1q3rcL/k9PVZxgcDGWdxS5dfS0nOeUWvXr00fPhw/f3336pevboGDx7s8Prjel7PAJlh6hJY2tChQ+Xj46O+ffvq2LFjDrcdP35cTz75pHx9fe2fhErS/fffrzVr1ui3336zL7tw4YLef/99BQUFOczTKV3+VHfhwoUaP368ihcvrvvuuy/TWkJCQtSyZUtFREQ4vRmVLr85v3rOrIkTJyo9PT3L43Nzc1ObNm30008/afv27Q7H9vHHH6tevXoKDAzMcv2cypif68r6jDFZThUyceJE/fzzz5o1a5YiIiLUpEmTG9r/+fPnr/k1rozarpxL7Eo5fVzvv/9+HTlyRHPmzLGPu3TpkiZOnCh/f3+nucLnz5+vw4cP26+vWbNGq1evdnoelChRwv4VsNGjR6ts2bLq3bu3U91XPwfGjx+f7XEDwL/Fa6+9plKlSqlPnz66dOmSJKlevXoqWbKkpkyZ4tAHfvzxR23fvl1RUVE3va6EhASHOR8PHjyob775Rm3atJGHh4c8PDzUpk0bffPNNw5fv01MTNRnn32me++91/6tMenyV40lOb0xzImMD8uz6nXZ8fDwkJubm8Prin379mn+/PlOYy9duqTu3burRo0aeueddxQREeH0lePrcf78eUm6Zi/P7vjq1q2roKAgp+fC8uXLtW7dOrVr107S5Tf+derU0ccff+zwIceWLVu0cOFC3X///U7bnjx5ssP1jJMWru7ljRs3loeHh/z8/DRlyhT9+uuv9jPur6z7yl5+6tQp3nwDQA506dJFhw8fdvi7muH8+fP2aac6duwod3d3jR492umbMjmdgzrD/fffr/T0dE2aNMlh+TvvvCM3N7cs39tfWZf0v/6WWR9YvXq1EhISnNY9ffq0HnvsMbVv314vvfSSIiIiVKpUqeuqP7taspJdr23VqpW8vLz07rvvOty3s2bNUmJior3X5ub12ZX3sTFGkyZNUsGCBZ3mFQ8PD5cklS5dWmPGjNHMmTMdpmO7ntczQGY4oxuWVqlSJX388cfq3r277rrrLj3++OMqX7689u3bpw8//FDJycn6/PPPVaFCBfs6zz//vGbNmqX77rtPAwcOVEBAgGbOnKlt27Zp1qxZKlDA8b/Fo48+queff15ff/21nnrqKRUsWDBXtbZr106ffvqpihQpourVqyshIUGLFy++5g9UvPLKK/rpp5/UrFkzPf300/L19dX06dN18uRJzZs3z2l8QkKCfY7wjB/H+uuvv7RgwQL7mKNHj+r8+fNasGCB2rZtq6pVq6pChQp67rnndPjwYRUuXFhffvllpnNmbd26Vc8//7xGjhyp+vXr5+q+mD9/vgICAuxTlyxfvlyDBg1yGJOenm6v+cyZM4qPj1dKSoo6duyY6TZz+rj26dNHU6dOtf+YZ2hoqObNm6eVK1dq/PjxTvO3VaxYUffee6+eeuoppaam2j/weP7557M8Ph8fH02bNk0RERF6//331a9fPxUuXFhNmzbVm2++qYsXL9rP2Nu7d2+u7kMAsJpChQpp4sSJ6tSpk95++2298MILKliwoMaMGaOYmBg1a9ZM3bp1U2JioiZMmKDQ0FANHjz4ptdVs2ZNRUZGauDAgfLy8rJPrTJq1Cj7mFdffVWLFi3Svffeq379+qlAgQKaOnWqUlNT9eabb0q6HHzHxsbqgw8+UNeuXTOda/pqZ8+etfe648eP691331XBggVzFfBHRUVp3Lhxatu2rR599FElJSVp8uTJqlixotM0b6NGjdLmzZv1+++/5+p1TWJiombOnCnp8tRdU6dOVYECBexvkDMcOHBACxYssE9d8tprrykkJER169Z1OpO+QIECevPNN9WjRw+Fh4ere/fu9mlRypYtqxdeeME+duzYsbrvvvvUqFEjPf744zp//rwmTpyoIkWKaOTIkU717t27V+3bt1fbtm2VkJCgmTNn6tFHH1Xt2rWzPMbIyEj95z//0fPPP68HHnhApUqVUps2beTp6akHHnhAffv21dmzZzV9+nSVLFlS//zzz3XfjwBwO3nsscf0xRdf6Mknn9TSpUvVpEkTpaena8eOHfriiy/0008/qV69eqpYsaJefPFFvfLKKwoPD1enTp3k5eWltWvXqnTp0oqLi8vxPh944AG1aNFCL774ovbt26fatWtr4cKF+uabbzRo0CCHnEC6PO3pzJkzZYzR7t277T2oXr16ki6/p//qq6/04IMPKioqSnv37tWUKVNUvXp1nT171mFb/fv31/nz5zOdVzsn9uzZY++1hw8f1qRJk1S4cGGn4Hjnzp1asGCB/Sz4sWPHqn79+ipTpozTNosVK6aXXnpJL7/8siIjI9WhQwft2bNHkyZNUu3atfXEE09I0nW/PvP29taCBQsUHR2thg0b6scff9T333+v4cOH278dl5k+ffros88+05NPPqktW7bY5xjP6esZIFMG+BfYtGmT6datmylVqpQpWLCgCQoKMt26dTObN2/OdPzu3bvNww8/bIoUKWK8vb1N/fr1zfz587Pc/v33328kmd9++y3HNUkysbGx9usnTpwwMTExJiAgwPj7+5vIyEizY8cOExISYqKjo+3jli5daiSZpUuX2petX7/etGnTxvj7+xtfX1/TtGlT88svvzjsLz4+3ki67kuGbdu2mYiICOPv728CAgJM7969zR9//GEkmfj4eGOMMRcuXDC1atUy9957r7l06ZJ93b179xpJZuzYsdneJ1fX6OnpaSpWrGhGjBhhLly4YB8XHR3tMM7f39/cfffd5tNPP83y/jUm549rYmKi/bHw9PQ0d911l/0YMzumt99+2wQHBxsvLy8THh5u/vjjD4ex0dHRJiQkxGk/MTExpnDhwubQoUPGGGMOHTpkHnzwQVO0aFFTpEgR07lzZ/P3339neiwAYFUZf+vXrl2b6e0dOnQwvr6+Zs+ePfZlc+bMMXXr1jVeXl6mWLFipnv37va/nRmio6ONn5+f0/bmzp3r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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "ros = RandomOverSampler(random_state=42)\n", "\n", "X_train_resampled, Y_train_resampled = ros.fit_resample(X_train_df, Y_train_df)\n", "X_val_resampled, Y_val_resampled = ros.fit_resample(X_val_df, Y_val_df)\n", "\n", "analyze_balance(Y_train_resampled, Y_val_resampled, Y_test_df, 'Flexibility Level')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Конструирование признаков. Для начала применим унитарное кодирование категориальных признаков (one-hot encoding), переведя их в бинарные вектора." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AgeEducation Level_SchoolEducation Level_UniversityInstitution Type_PublicGender_MaleDevice_MobileDevice_TabIT Student_YesLocation_TownFinancial Condition_PoorFinancial Condition_RichInternet Type_WifiNetwork Type_3GNetwork Type_4G
010TrueFalseFalseTrueTrueFalseFalseTrueFalseTrueTrueFalseTrue
118FalseFalseFalseFalseTrueFalseFalseTrueFalseFalseTrueFalseTrue
223FalseTrueFalseTrueTrueFalseFalseTrueFalseFalseTrueFalseTrue
318TrueFalseTrueTrueTrueFalseFalseTrueFalseTrueFalseFalseTrue
423FalseTrueFalseFalseTrueFalseFalseFalseFalseFalseTrueFalseTrue
\n", "
" ], "text/plain": [ " Age Education Level_School Education Level_University \\\n", "0 10 True False \n", "1 18 False False \n", "2 23 False True \n", "3 18 True False \n", "4 23 False True \n", "\n", " Institution Type_Public Gender_Male Device_Mobile Device_Tab \\\n", "0 False True True False \n", "1 False False True False \n", "2 False True True False \n", "3 True True True False \n", "4 False False True False \n", "\n", " IT Student_Yes Location_Town Financial Condition_Poor \\\n", "0 False True False \n", "1 False True False \n", "2 False True False \n", "3 False True False \n", "4 False False False \n", "\n", " Financial Condition_Rich Internet Type_Wifi Network Type_3G \\\n", "0 True True False \n", "1 False True False \n", "2 False True False \n", "3 True False False \n", "4 False True False \n", "\n", " Network Type_4G \n", "0 True \n", "1 True \n", "2 True \n", "3 True \n", "4 True " ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cat_features = ['Education Level', 'Institution Type', 'Gender', 'Device', 'IT Student', 'Location', 'Financial Condition', 'Internet Type', 'Network Type']\n", "\n", "train_encoded = pd.get_dummies(X_train_resampled, columns=cat_features, drop_first=True)\n", "val_encoded = pd.get_dummies(X_val_resampled, columns=cat_features, drop_first=True)\n", "test_encoded = pd.get_dummies(X_test_df, columns=cat_features, drop_first=True)\n", "\n", "train_encoded.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Применим дискретизацию к числовым признакам." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Education Level_SchoolEducation Level_UniversityInstitution Type_PublicGender_MaleDevice_MobileDevice_TabIT Student_YesLocation_TownFinancial Condition_PoorFinancial Condition_RichInternet Type_WifiNetwork Type_3GNetwork Type_4GAge_Bin
0TrueFalseFalseTrueTrueFalseFalseTrueFalseTrueTrueFalseTrueyoung
1FalseFalseFalseFalseTrueFalseFalseTrueFalseFalseTrueFalseTrueyoung
2FalseTrueFalseTrueTrueFalseFalseTrueFalseFalseTrueFalseTrueyoung
3TrueFalseTrueTrueTrueFalseFalseTrueFalseTrueFalseFalseTrueyoung
4FalseTrueFalseFalseTrueFalseFalseFalseFalseFalseTrueFalseTrueyoung
\n", "
" ], "text/plain": [ " Education Level_School Education Level_University \\\n", "0 True False \n", "1 False False \n", "2 False True \n", "3 True False \n", "4 False True \n", "\n", " Institution Type_Public Gender_Male Device_Mobile Device_Tab \\\n", "0 False True True False \n", "1 False False True False \n", "2 False True True False \n", "3 True True True False \n", "4 False False True False \n", "\n", " IT Student_Yes Location_Town Financial Condition_Poor \\\n", "0 False True False \n", "1 False True False \n", "2 False True False \n", "3 False True False \n", "4 False False False \n", "\n", " Financial Condition_Rich Internet Type_Wifi Network Type_3G \\\n", "0 True True False \n", "1 False True False \n", "2 False True False \n", "3 True False False \n", "4 False True False \n", "\n", " Network Type_4G Age_Bin \n", "0 True young \n", "1 True young \n", "2 True young \n", "3 True young \n", "4 True young " ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "num_features = ['Age']\n", "\n", "def discretize_features(df, features, bins, labels):\n", " for feature in features:\n", " df[f'{feature}_Bin'] = pd.cut(df[feature], bins=bins, labels=labels)\n", " df.drop(columns=[feature], inplace=True)\n", " return df\n", "\n", "age_bins = [0, 25, 55, 100]\n", "age_labels = [\"young\", \"middle-aged\", \"old\"]\n", "\n", "train_encoded = discretize_features(train_encoded, num_features, bins=age_bins, labels=age_labels)\n", "val_encoded = discretize_features(val_encoded, num_features, bins=age_bins, labels=age_labels)\n", "test_encoded = discretize_features(test_encoded, num_features, bins=age_bins, labels=age_labels)\n", "\n", "train_encoded.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Применим ручной синтез признаков. К примеру, для этого датасета, сделаем признак \"соотвествие устройства для обучения\". Мобильные устройства часто менее удобны для учебы по сравнению с планшетами." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Education Level_SchoolEducation Level_UniversityInstitution Type_PublicGender_MaleDevice_MobileDevice_TabIT Student_YesLocation_TownFinancial Condition_PoorFinancial Condition_RichInternet Type_WifiNetwork Type_3GNetwork Type_4GAge_BinDevice Suitability
0TrueFalseFalseTrueTrueFalseFalseTrueFalseTrueTrueFalseTrueyoungLow
1FalseFalseFalseFalseTrueFalseFalseTrueFalseFalseTrueFalseTrueyoungLow
2FalseTrueFalseTrueTrueFalseFalseTrueFalseFalseTrueFalseTrueyoungLow
3TrueFalseTrueTrueTrueFalseFalseTrueFalseTrueFalseFalseTrueyoungLow
4FalseTrueFalseFalseTrueFalseFalseFalseFalseFalseTrueFalseTrueyoungLow
\n", "
" ], "text/plain": [ " Education Level_School Education Level_University \\\n", "0 True False \n", "1 False False \n", "2 False True \n", "3 True False \n", "4 False True \n", "\n", " Institution Type_Public Gender_Male Device_Mobile Device_Tab \\\n", "0 False True True False \n", "1 False False True False \n", "2 False True True False \n", "3 True True True False \n", "4 False False True False \n", "\n", " IT Student_Yes Location_Town Financial Condition_Poor \\\n", "0 False True False \n", "1 False True False \n", "2 False True False \n", "3 False True False \n", "4 False False False \n", "\n", " Financial Condition_Rich Internet Type_Wifi Network Type_3G \\\n", "0 True True False \n", "1 False True False \n", "2 False True False \n", "3 True False False \n", "4 False True False \n", "\n", " Network Type_4G Age_Bin Device Suitability \n", "0 True young Low \n", "1 True young Low \n", "2 True young Low \n", "3 True young Low \n", "4 True young Low " ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "train_encoded['Device Suitability'] = train_encoded['Device_Tab'].apply(lambda x: \"High\" if x == True else \"Low\")\n", "val_encoded['Device Suitability'] = val_encoded['Device_Tab'].apply(lambda x: \"High\" if x == True else \"Low\")\n", "test_encoded['Device Suitability'] = test_encoded['Device_Tab'].apply(lambda x: \"High\" if x == True else \"Low\")\n", "\n", "train_encoded.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Конструирование признаков с помощью фреймворка Featuretools." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "d:\\ulstu\\cr3\\sem1\\MAI\\AIM-PIbd-31-Makarov-DV\\.venv\\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", "d:\\ulstu\\cr3\\sem1\\MAI\\AIM-PIbd-31-Makarov-DV\\.venv\\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", "d:\\ulstu\\cr3\\sem1\\MAI\\AIM-PIbd-31-Makarov-DV\\.venv\\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" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Education Level_SchoolEducation Level_UniversityInstitution Type_PublicGender_MaleDevice_MobileDevice_TabIT Student_YesLocation_TownFinancial Condition_PoorFinancial Condition_RichInternet Type_WifiNetwork Type_3GNetwork Type_4GAge_BinDevice Suitability
id
0TrueFalseFalseTrueTrueFalseFalseTrueFalseTrueTrueFalseTrueyoungLow
1FalseFalseFalseFalseTrueFalseFalseTrueFalseFalseTrueFalseTrueyoungLow
2FalseTrueFalseTrueTrueFalseFalseTrueFalseFalseTrueFalseTrueyoungLow
3TrueFalseTrueTrueTrueFalseFalseTrueFalseTrueFalseFalseTrueyoungLow
4FalseTrueFalseFalseTrueFalseFalseFalseFalseFalseTrueFalseTrueyoungLow
\n", "
" ], "text/plain": [ " Education Level_School Education Level_University \\\n", "id \n", "0 True False \n", "1 False False \n", "2 False True \n", "3 True False \n", "4 False True \n", "\n", " Institution Type_Public Gender_Male Device_Mobile Device_Tab \\\n", "id \n", "0 False True True False \n", "1 False False True False \n", "2 False True True False \n", "3 True True True False \n", "4 False False True False \n", "\n", " IT Student_Yes Location_Town Financial Condition_Poor \\\n", "id \n", "0 False True False \n", "1 False True False \n", "2 False True False \n", "3 False True False \n", "4 False False False \n", "\n", " Financial Condition_Rich Internet Type_Wifi Network Type_3G \\\n", "id \n", "0 True True False \n", "1 False True False \n", "2 False True False \n", "3 True False False \n", "4 False True False \n", "\n", " Network Type_4G Age_Bin Device Suitability \n", "id \n", "0 True young Low \n", "1 True young Low \n", "2 True young Low \n", "3 True young Low \n", "4 True young Low " ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ft_data = train_encoded.copy()\n", "\n", "es = ft.EntitySet(id=\"students\")\n", "es = es.add_dataframe(dataframe_name=\"students_data\", dataframe=ft_data, index=\"id\", make_index=True)\n", "\n", "feature_matrix, feature_defs = ft.dfs(\n", " entityset=es, \n", " target_dataframe_name=\"students_data\",\n", " max_depth=1\n", ")\n", "\n", "feature_matrix.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Featuretools не смог сделать новые признаки.\n", "\n", "Оценка качества набора признаков." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Время обучения модели: 0.11 секунд\n" ] } ], "source": [ "train_encoded = pd.get_dummies(train_encoded, drop_first=True)\n", "val_encoded = pd.get_dummies(val_encoded, drop_first=True)\n", "test_encoded = pd.get_dummies(test_encoded, drop_first=True)\n", "\n", "cols = train_encoded.columns\n", "\n", "train_encoded = train_encoded.reindex(columns=cols, fill_value=0)\n", "val_encoded = val_encoded.reindex(columns=cols, fill_value=0)\n", "test_encoded = test_encoded.reindex(columns=cols, fill_value=0)\n", "\n", "model = RandomForestClassifier(n_estimators=100, random_state=42)\n", "\n", "start = time.time()\n", "model.fit(train_encoded, Y_train_resampled)\n", "train_time = time.time() - start\n", "\n", "print(f'Время обучения модели: {train_time:.2f} секунд')" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Feature Importance:\n", " feature importance\n", "9 Financial Condition_Rich 0.184028\n", "3 Gender_Male 0.108992\n", "8 Financial Condition_Poor 0.107030\n", "2 Institution Type_Public 0.095663\n", "10 Internet Type_Wifi 0.089925\n", "7 Location_Town 0.078658\n", "0 Education Level_School 0.061961\n", "6 IT Student_Yes 0.055048\n", "1 Education Level_University 0.049695\n", "12 Network Type_4G 0.044837\n", "4 Device_Mobile 0.042086\n", "11 Network Type_3G 0.038541\n", "13 Age_Bin_middle-aged 0.034876\n", "15 Device Suitability_Low 0.004611\n", "5 Device_Tab 0.004049\n", "14 Age_Bin_old 0.000000\n" ] } ], "source": [ "# Получение важности признаков\n", "importances = model.feature_importances_\n", "feature_names = train_encoded.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": 15, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "d:\\ulstu\\cr3\\sem1\\MAI\\AIM-PIbd-31-Makarov-DV\\.venv\\Lib\\site-packages\\sklearn\\metrics\\_regression.py:492: FutureWarning: 'squared' is deprecated in version 1.4 and will be removed in 1.6. To calculate the root mean squared error, use the function'root_mean_squared_error'.\n", " warnings.warn(\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "RMSE: 0.5652451456569942\n", "R²: 0.22569473420679287\n", "MAE: 0.2697095435684647 \n", "\n", "Кросс-валидация RMSE: 0.5705060311373475 \n", "\n", "Train RMSE: 0.5237418787490223\n", "Train R²: 0.5885416666666667\n", "Train MAE: 0.19791666666666666\n", "\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "d:\\ulstu\\cr3\\sem1\\MAI\\AIM-PIbd-31-Makarov-DV\\.venv\\Lib\\site-packages\\sklearn\\metrics\\_regression.py:492: FutureWarning: 'squared' is deprecated in version 1.4 and will be removed in 1.6. To calculate the root mean squared error, use the function'root_mean_squared_error'.\n", " warnings.warn(\n" ] } ], "source": [ "y_pred = model.predict(test_encoded)\n", "\n", "# Анализ важности признаков\n", "feature_importances = model.feature_importances_\n", "feature_names = train_encoded.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", "rmse = mean_squared_error(Y_test_df, y_pred, squared=False)\n", "r2 = r2_score(Y_test_df, y_pred)\n", "mae = mean_absolute_error(Y_test_df, y_pred)\n", "\n", "print()\n", "print(f\"RMSE: {rmse}\")\n", "print(f\"R²: {r2}\")\n", "print(f\"MAE: {mae} \\n\")\n", "\n", "# Кросс-валидация\n", "scores = cross_val_score(model, train_encoded, Y_train_resampled, cv=5, scoring='neg_mean_squared_error')\n", "rmse_cv = math.sqrt((-scores.mean()))\n", "print(f\"Кросс-валидация RMSE: {rmse_cv} \\n\")\n", "\n", "# Проверка на переобучение\n", "y_train_pred = model.predict(train_encoded)\n", "\n", "rmse_train = mean_squared_error(Y_train_resampled, y_train_pred, squared=False)\n", "r2_train = r2_score(Y_train_resampled, y_train_pred)\n", "mae_train = mean_absolute_error(Y_train_resampled, y_train_pred)\n", "\n", "print(f\"Train RMSE: {rmse_train}\")\n", "print(f\"Train R²: {r2_train}\")\n", "print(f\"Train MAE: {mae_train}\")\n", "print()" ] } ], "metadata": { "kernelspec": { "display_name": ".venv", "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.13.0" } }, "nbformat": 4, "nbformat_minor": 2 }