565 lines
117 KiB
Plaintext
Raw Permalink Normal View History

2024-10-07 12:45:24 +04:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Лабораторная работа 2\n",
"\n",
"1. Цены на телефоны\thttps://www.kaggle.com/datasets/mayankanand2701/starbucks-stock-price-dataset\n",
"2. Цены на машины\thttps://www.kaggle.com/datasets/nancyalaswad90/yamana-gold-inc-stock-price\n",
"3. Цены на дома в Бостоне\thttps://www.kaggle.com/datasets/arunjangir245/boston-housing-dataset"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Датасет 1. Цены мобильных телефонов**\n",
"\n",
"1. **Name**: Название модели мобильного телефона.\n",
"2. **Rating**: Рейтинг мобильного телефона (по отзывам пользователей).\n",
"3. **Spec_score**: Оценка спецификаций телефона (возможно, по различным характеристикам).\n",
"4. **No_of_sim**: Количество SIM-карт, поддерживаемых телефоном.\n",
"5. **Ram**: Объем оперативной памяти (RAM) в гигабайтах.\n",
"6. **Battery**: Емкость батареи в мАч.\n",
"7. **Display**: Размер дисплея в дюймах.\n",
"8. **Camera**: Разрешение камеры (в мегапикселях).\n",
"9. **External_Memory**: Поддержка внешней памяти (да/нет).\n",
"10. **Android_version**: Версия операционной системы Android.\n",
"11. **Price**: Цена мобильного телефона в долларах США.\n",
"12. **Company**: Производитель телефона.\n",
"13. **Inbuilt_memory**: Объем встроенной памяти (в гигабайтах).\n",
"14. **Fast_charging**: Наличие быстрой зарядки (да/нет).\n",
"15. **Screen_resolution**: Разрешение экрана (в пикселях).\n",
"16. **Processor**: Тип процессора.\n",
"17. **Processor_name**: Наименование процессора.\n",
"\n",
"**Объект наблюдения**: Каждый объект представляет собой отдельный мобильный телефон.\n",
"\n",
"**Связи между объектами**: Внутри одного объекта есть взаимосвязь между характеристиками и его ценой. Например, объем оперативной памяти, емкость батареи, качество камеры и поддержка быстрой зарядки могут влиять на цену.\n",
"\n",
"**Бизнес-цель**: Оптимизация продаж мобильных телефонов, оценка цен в зависимости от характеристик.\n",
"\n",
"**Эффект для бизнеса**: Более точная оценка стоимости мобильных телефонов может помочь производителям и ритейлерам предлагать конкурентоспособные цены и максимизировать прибыль.\n",
"\n",
"**Техническая цель**: Построение модели машинного обучения для прогнозирования цены мобильного телефона на основе его характеристик.\n",
"\n",
"* **Вход**: Характеристики мобильного телефона (объем RAM, емкость батареи, качество камеры и т.д.).\n",
"* **Целевой признак**: Цена мобильного телефона.\n",
"\n",
"**Информативность**: Высокая. Набор данных содержит важные характеристики мобильных телефонов, которые влияют на их цену.\n",
"\n",
"**Степень покрытия**: Высокая. Датасет включает разнообразные модели телефонов, что позволяет провести полноценный анализ.\n",
"\n",
"**Соответствие реальным данным**: Высокая. Характеристики мобильных телефонов в наборе данных соответствуют реальным характеристикам, определяемым производителями.\n",
"\n",
"**Согласованность меток**: Высокая. Датасет не содержит проблем с несогласованностью меток, так как все данные соответствуют описанию в заголовках столбцов. \n",
"\n",
"---\n",
"\n",
"**Датасет 2. Прогнозирование цен на автомобили**\n",
"\n",
"1. **make**: Производитель автомобиля.\n",
"2. **model**: Модель автомобиля.\n",
"3. **year**: Год выпуска автомобиля.\n",
"4. **mileage**: Пробег автомобиля в километрах.\n",
"5. **engine_size**: Объем двигателя в литрах.\n",
"6. **horsepower**: Мощность двигателя в лошадиных силах.\n",
"7. **fuel_type**: Тип топлива (бензин, дизель и др.).\n",
"8. **transmission**: Тип трансмиссии (механическая или автоматическая).\n",
"9. **color**: Цвет автомобиля.\n",
"10. **body_type**: Тип кузова (седан, хэтчбек, внедорожник и др.).\n",
"11. **price**: Цена автомобиля в долларах США.\n",
"\n",
"**Объект наблюдения**: Каждый объект представляет собой отдельный автомобиль.\n",
"\n",
"**Связи между объектами**: Внутри одного объекта есть взаимосвязь между характеристиками и его ценой. Например, год выпуска, пробег и мощность двигателя могут влиять на цену автомобиля.\n",
"\n",
"**Бизнес-цель**: Оптимизация продаж автомобилей, оценка цен в зависимости от характеристик.\n",
"\n",
"**Эффект для бизнеса**: Более точная оценка стоимости автомобилей может помочь дилерам и производителям предлагать конкурентоспособные цены и максимизировать прибыль.\n",
"\n",
"**Техническая цель**: Построение модели машинного обучения для прогнозирования цены автомобиля на основе его характеристик.\n",
"\n",
"* **Вход**: Характеристики автомобиля (год выпуска, пробег, объем двигателя и др.).\n",
"* **Целевой признак**: Цена автомобиля.\n",
"\n",
"---\n",
"\n",
"**Датасет 3. Прогнозирование цен на жилье в Бостоне**\n",
"\n",
"1. **crim**: Уровень преступности на душу населения по городам.\n",
"2. **zn**: Доля крупных жилых участков (более 25,000 кв. футов).\n",
"3. **indus**: Доля не розничных бизнес-акров на город.\n",
"4. **Chas**: Двоичный признак, указывающий, находится ли объект рядом с рекой Чарльз (1 — да, 0 — нет).\n",
"5. **nox**: Концентрация оксидов азота в воздухе.\n",
"6. **rm**: Среднее количество комнат в одном жилом доме.\n",
"7. **age**: Доля старых жилых единиц, построенных до 1940 года.\n",
"8. **dis**: Взвешенные расстояния до рабочих центров Бостона.\n",
"9. **rad**: Индекс доступности радиальных шоссе.\n",
"10. **tax**: Налог на недвижимость на сумму $10,000.\n",
"\n",
"**Объект наблюдения**: Каждый объект представляет собой отдельный дом или квартиру.\n",
"\n",
"**Связи между объектами**: Внутри одного объекта есть взаимосвязь между характеристиками, такими как уровень преступности, количество комнат и налоги, которые могут влиять на цену жилья.\n",
"\n",
"**Бизнес-цель**: Оценка стоимости недвижимости для покупателей и продавцов, а также для инвесторов в недвижимость.\n",
"\n",
"**Эффект для бизнеса**: Более точная оценка цен на жилье может помочь улучшить принятие решений при покупке и продаже недвижимости.\n",
"\n",
"**Техническая цель**: Построение модели машинного обучения для прогнозирования цен на жилье в Бостоне на основе его характеристик.\n",
"\n",
"* **Вход**: Характеристики жилья (уровень преступности, количество комнат, налоги и др.).\n",
"* **Целевой признак**: Цена жилья."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Выбросы в столбце 'crim':\n",
"367 13.5222\n",
"371 9.2323\n",
"373 11.1081\n",
"374 18.4982\n",
"375 19.6091\n",
" ... \n",
"468 15.5757\n",
"469 13.0751\n",
"477 15.0234\n",
"478 10.2330\n",
"479 14.3337\n",
"Name: crim, Length: 66, dtype: float64\n",
"\n",
"Выбросы в столбце 'zn':\n",
"39 75.0\n",
"40 75.0\n",
"54 75.0\n",
"55 90.0\n",
"56 85.0\n",
" ... \n",
"351 60.0\n",
"352 60.0\n",
"353 90.0\n",
"354 80.0\n",
"355 80.0\n",
"Name: zn, Length: 68, dtype: float64\n",
"\n",
"Выбросы в столбце 'indus':\n",
"Series([], Name: indus, dtype: float64)\n",
"\n",
"Выбросы в столбце 'chas':\n",
"142 1\n",
"152 1\n",
"154 1\n",
"155 1\n",
"160 1\n",
"162 1\n",
"163 1\n",
"208 1\n",
"209 1\n",
"210 1\n",
"211 1\n",
"212 1\n",
"216 1\n",
"218 1\n",
"219 1\n",
"220 1\n",
"221 1\n",
"222 1\n",
"234 1\n",
"236 1\n",
"269 1\n",
"273 1\n",
"274 1\n",
"276 1\n",
"277 1\n",
"282 1\n",
"283 1\n",
"356 1\n",
"357 1\n",
"358 1\n",
"363 1\n",
"364 1\n",
"369 1\n",
"370 1\n",
"372 1\n",
"Name: chas, dtype: int64\n",
"\n",
"Выбросы в столбце 'nox':\n",
"Series([], Name: nox, dtype: float64)\n",
"\n",
"Выбросы в столбце 'rm':\n",
"97 8.069\n",
"98 7.820\n",
"162 7.802\n",
"163 8.375\n",
"166 7.929\n",
"180 7.765\n",
"186 7.831\n",
"195 7.875\n",
"203 7.853\n",
"204 8.034\n",
"224 8.266\n",
"225 8.725\n",
"226 8.040\n",
"232 8.337\n",
"233 8.247\n",
"253 8.259\n",
"257 8.704\n",
"262 8.398\n",
"267 8.297\n",
"280 7.820\n",
"283 7.923\n",
"364 8.780\n",
"365 3.561\n",
"367 3.863\n",
"374 4.138\n",
"384 4.368\n",
"386 4.652\n",
"406 4.138\n",
"412 4.628\n",
"414 4.519\n",
"Name: rm, dtype: float64\n",
"\n",
"Выбросы в столбце 'age':\n",
"Series([], Name: age, dtype: float64)\n",
"\n",
"Выбросы в столбце 'dis':\n",
"351 10.7103\n",
"352 10.7103\n",
"353 12.1265\n",
"354 10.5857\n",
"355 10.5857\n",
"Name: dis, dtype: float64\n",
"\n",
"Выбросы в столбце 'rad':\n",
"Series([], Name: rad, dtype: int64)\n",
"\n",
"Выбросы в столбце 'tax':\n",
"Series([], Name: tax, dtype: int64)\n",
"\n",
"Выбросы в столбце 'ptratio':\n",
"196 12.6\n",
"197 12.6\n",
"198 12.6\n",
"257 13.0\n",
"258 13.0\n",
"259 13.0\n",
"260 13.0\n",
"261 13.0\n",
"262 13.0\n",
"263 13.0\n",
"264 13.0\n",
"265 13.0\n",
"266 13.0\n",
"267 13.0\n",
"268 13.0\n",
"Name: ptratio, dtype: float64\n",
"\n",
"Выбросы в столбце 'b':\n",
"18 288.99\n",
"25 303.42\n",
"27 306.38\n",
"32 232.60\n",
"34 248.31\n",
" ... \n",
"466 22.01\n",
"467 331.29\n",
"475 302.76\n",
"489 344.05\n",
"490 318.43\n",
"Name: b, Length: 77, dtype: float64\n",
"\n",
"Выбросы в столбце 'lstat':\n",
"141 34.41\n",
"373 34.77\n",
"374 37.97\n",
"387 31.99\n",
"412 34.37\n",
"414 36.98\n",
"438 34.02\n",
"Name: lstat, dtype: float64\n",
"\n",
"Выбросы в столбце 'medv':\n",
"97 38.7\n",
"98 43.8\n",
"157 41.3\n",
"161 50.0\n",
"162 50.0\n",
"163 50.0\n",
"166 50.0\n",
"179 37.2\n",
"180 39.8\n",
"182 37.9\n",
"186 50.0\n",
"190 37.0\n",
"195 50.0\n",
"202 42.3\n",
"203 48.5\n",
"204 50.0\n",
"224 44.8\n",
"225 50.0\n",
"226 37.6\n",
"228 46.7\n",
"232 41.7\n",
"233 48.3\n",
"253 42.8\n",
"256 44.0\n",
"257 50.0\n",
"261 43.1\n",
"262 48.8\n",
"267 50.0\n",
"268 43.5\n",
"280 45.4\n",
"282 46.0\n",
"283 50.0\n",
"291 37.3\n",
"368 50.0\n",
"369 50.0\n",
"370 50.0\n",
"371 50.0\n",
"372 50.0\n",
"398 5.0\n",
"405 5.0\n",
"Name: medv, dtype: float64\n",
"\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAMWCAYAAAAgRDUeAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdd3hUZfr/8c+kJ5BCKCGhB+ldmihSFEWKgq5gQQ2KsgioiA1EDSCIstYVFFAUBcQVlxVFqq7IVw1NYJEiCoQOoabQUp/fH/zmmCEJpM2ZhLxf15UL5pznnHM/z8yce+aeUxzGGCMAAAAAAADARl6eDgAAAAAAAABlD0UpAAAAAAAA2I6iFAAAAAAAAGxHUQoAAAAAAAC2oygFAAAAAAAA21GUAgAAAAAAgO0oSgEAAAAAAMB2FKUAAAAAAABgO4pSAAAAAAAAsB1FKZRKDodDY8eOtWVbS5cuVcuWLRUQECCHw6HExERbtlsYs2bNksPh0J49ezwdCgCUGuQUACibrtT9vzu+E/A9A+5CUQounDub7H9VqlRR165dtWTJEk+HV2Tbtm3T2LFj870zPXHihPr376/AwEBNnTpVs2fPVrly5dwbJABcIcgprsgpAMoK9v+u2P8DefPxdAAomcaPH686derIGKOEhATNmjVLPXv21DfffKPevXt7OrxC27Ztm8aNG6cuXbqodu3al22/bt06paSk6OWXX1a3bt3cH2AR3X///br77rvl7+/v6VAAwEJOuaC05RQAKCr2/xfYvf/nOwFKE4pSyFWPHj3Upk0b6/GgQYMUERGhefPmleoEUlBHjx6VJIWFhRXbOs+cOVPsv4w41+nt7S1vb+9iXTcAFBU55YLSklMAoLiw/7/A7v0/3wlQmnD6HvIlLCxMgYGB8vFxrWOeOXNGTz31lGrUqCF/f381aNBAr7/+uowxkqRz586pYcOGatiwoc6dO2ctd/LkSUVGRuraa69VZmamJGngwIEqX768du/ere7du6tcuXKKiorS+PHjrfVdysaNG9WjRw+FhISofPnyuvHGG7V69Wpr/qxZs9SvXz9JUteuXa1DiVeuXJnr+rp06aKYmBhJUtu2beVwODRw4EBr/vz589W6dWsFBgaqUqVKuu+++3Tw4EGXdTj7tGvXLvXs2VPBwcEaMGDAJftx8OBBDRo0SFFRUfL391edOnX06KOPKi0tzeqHw+HQjz/+qKFDh6pKlSqqXr26y7zshxLXrl1bvXv31sqVK9WmTRsFBgaqWbNmVr8XLFigZs2aKSAgQK1bt9bGjRsvO9YAUBTkFPfnlD179uQ4dSb7X/a4mjZtqm3btqlr164KCgpStWrVNHny5MuOEQAUFPt/e75TXOo7wU8//aR27dopICBA0dHR+vTTT3Msv3XrVt1www0KDAxU9erVNWHCBGVlZeVol9c1uWrXru3Sx/T0dI0bN0716tVTQECAKlasqI4dO2rFihV59gFlB0dKIVdJSUk6fvy4jDE6evSo3n33XZ0+fVr33Xef1cYYo9tuu00//PCDBg0apJYtW2rZsmV65plndPDgQb311lsKDAzUJ598ouuuu05jxozRm2++KUkaNmyYkpKSNGvWLJcqfmZmpm655RZdc801mjx5spYuXarY2FhlZGRo/Pjxeca7detWXX/99QoJCdGzzz4rX19fTZ8+XV26dNGPP/6o9u3bq1OnTnr88cf1z3/+U88//7waNWokSda/FxszZowaNGigGTNmWIce161bV9KFHf2DDz6otm3batKkSUpISNA777yjn3/+WRs3bnT5FSQjI0Pdu3dXx44d9frrrysoKCjPfhw6dEjt2rVTYmKiBg8erIYNG+rgwYP68ssvdfbsWfn5+Vlthw4dqsqVK+ull17SmTNnLvFsSjt37tS9996rv//977rvvvv0+uuv69Zbb9W0adP0/PPPa+jQoZKkSZMmqX///tqxY4e8vKhZAyge5BT7c0rlypU1e/Zsl2np6el68sknXXKJJJ06dUq33HKL7rjjDvXv319ffvmlnnvuOTVr1kw9evTIc5wA4HLY/3vmO0Vedu7cqTvvvFODBg1STEyMPvroIw0cOFCtW7dWkyZNJElHjhxR165dlZGRoVGjRqlcuXKaMWOGAgMDC7w9p7Fjx2rSpEl6+OGH1a5dOyUnJ2v9+vXasGGDbrrppkKvF1cIA2Tz8ccfG0k5/vz9/c2sWbNc2n711VdGkpkwYYLL9DvvvNM4HA6zc+dOa9ro0aONl5eXWbVqlZk/f76RZN5++22X5WJiYowk89hjj1nTsrKyTK9evYyfn585duyYNV2SiY2NtR737dvX+Pn5mV27dlnTDh06ZIKDg02nTp2sac5t//DDDwUaj3Xr1lnT0tLSTJUqVUzTpk3NuXPnrOmLFi0yksxLL72Uo0+jRo3K1/YeeOAB4+Xl5bI9p6ysLJeYOnbsaDIyMnKNNz4+3ppWq1YtI8n88ssv1rRly5YZSSYwMNDs3bvXmj59+vQCjQ8AXAo5JffxsCunXGzo0KHG29vb/Pe//7Wmde7c2Ugyn376qTUtNTXVVK1a1fztb38r1HYAgP1/7uNh1/7/Ut8JVq1aZU07evSo8ff3N0899ZQ1bcSIEUaSWbNmjUu70NDQHOu8ePyybysmJsZ63KJFC9OrV698xY6yh0MhkKupU6dqxYoVWrFihebMmaOuXbvq4Ycf1oIFC6w2ixcvlre3tx5//HGXZZ966ikZY1zurDF27Fg1adJEMTExGjp0qDp37pxjOafhw4db/3c4HBo+fLjS0tL03Xff5do+MzNTy5cvV9++fRUdHW1Nj4yM1L333quffvpJycnJhRqH3Kxfv15Hjx7V0KFDFRAQYE3v1auXGjZsqG+//TbHMo8++uhl15uVlaWvvvpKt956q8u5907ZT7eQpEceeSTf54o3btxYHTp0sB63b99eknTDDTeoZs2aOabv3r07X+sFgPwgp+TNXTnlYp9++qnee+89TZ48WV27dnWZV758eZejFvz8/NSuXTtyAYAiY/+fN7v2/9k1btxY119/vfW4cuXKatCggcv+fvHixbrmmmvUrl07l3aXuwTJpYSFhWnr1q36888/C70OXLkoSiFX7dq1U7du3dStWzcNGDBA3377rRo3bmztzCVp7969ioqKUnBwsMuyzkNX9+7da03z8/PTRx99pPj4eKWkpOjjjz/OUWSRJC8vL5ckIEn169eXpDxvuXrs2DGdPXtWDRo0yDGvUaNGysrK0v79+/Pf+ctw9iu37TVs2NCl35Lk4+NjXfPpUo4dO6bk5GQ1bdo0X3HUqVMnX+0kuRSeJCk0NFSSVKNGjVynnzp1Kt/rBoDLIafkzV05JbtNmzZpyJAhuueeezRy5Mgc86tXr55j/CpUqEAuAFBk7P/zZsf+/2IXfyeQcu7v9+7dq3r16uVol1uc+TV+/HglJiaqfv36atasmZ555hlt3ry50OvDlYWiFPLFy8tLXbt21eHDhwtd4V62bJkk6fz582WqSu7v7++W6zMV5LzuvI6oymu6ycdFIAGgsMgphVfQnHLq1Cn97W9/U/369fXhhx/m2oZcAMAu7P8Lrzi+U9i1v3dedN6pU6dO2rVrlz766CM1bdpUH374oa6++uo88xLKFopSyLeMjAxJ0unTpyVJtWrV0qFDh5SSkuLS7vfff7fmO23evFnjx4/Xgw8+qFatWunhhx9WUlJSjm1kZWXlOF3gjz/+kHThLg65qVy5soKCgrRjx44c837//Xd5eXlZRwTl9ktKQTn7ldv2duzY4dLvgqhcubJCQkK0ZcuWIsUHAKUBOeUCd+UU6UL/BwwYoMTERP3nP/8p1EVxAaC4sf+/wJ37/6KoVatWrsW+3OKsUKGCEhMTXaalpaXp8OHDOdqGh4frwQcf1Lx587R//341b9481zv3oeyhKIV8SU9P1/Lly+Xn52cdStuzZ09lZmZqypQpLm3feustORwO64496enpGjhwoKKiovTOO+9o1qxZSkhI0JNPPpnrtrKvzxijKVOmyNfXVzfeeGOu7b2
"text/plain": [
"<Figure size 1200x800 with 14 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Просачивание данных: Высокая корреляция (0.91) между столбцами 'rad' и 'tax'\n",
"Просачивание данных: Высокая корреляция (0.91) между столбцами 'tax' и 'rad'\n",
"Обучающая выборка: (300, 15)\n",
"Контрольная выборка: (100, 15)\n",
"Тестовая выборка: (101, 15)\n",
"tax_binned\n",
"Low 171\n",
"High 82\n",
"Medium 37\n",
"Very Low 10\n",
"Very High 0\n",
"Name: count, dtype: int64\n",
"Обучающая выборка после undersampling: (40, 15)\n",
"tax_binned\n",
"Very Low 10\n",
"Low 10\n",
"Medium 10\n",
"High 10\n",
"Very High 0\n",
"Name: count, dtype: int64\n"
]
}
],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"from sklearn.model_selection import train_test_split\n",
"from imblearn.under_sampling import RandomUnderSampler\n",
"import matplotlib.pyplot as plt\n",
"import seaborn as sns\n",
"\n",
"df = pd.read_csv(\n",
" \"data/boston_housing.csv\"\n",
") \n",
"\n",
"# Проверка на пропуски и \"зашумленные\" столбцы (если процент пустых значений больше 10%)\n",
"noisy_features = [] # Список для хранения столбцов с большим количеством пропусков\n",
"for col in df.columns: # Проходим по каждому столбцу\n",
" if (\n",
" df[col].isnull().sum() / len(df) > 0.1\n",
" ): # Проверяем, если доля пропусков больше 10%\n",
" noisy_features.append(col) # Добавляем столбец в список\n",
"\n",
"# Проверка на смещение (относительно нормального распределения)\n",
"skewness = df.select_dtypes(\n",
" include=[np.number]\n",
").skew() # Вычисляем коэффициент смещения для числовых столбцов\n",
"\n",
"skewed_features = skewness[\n",
" abs(skewness) > 1\n",
"].index.tolist() # Находим сильно смещенные столбцы\n",
"\n",
"# Поиск выбросов (сильно отличающиеся значения)\n",
"for col in df.select_dtypes(\n",
" include=[\"number\"]\n",
").columns: # Проходим по числовым столбцам\n",
" Q1 = df[col].quantile(0.25) # Находим первый квартиль (значение, ниже которого 25% данных)\n",
" Q3 = df[col].quantile(\n",
" 0.75\n",
" ) # Находим третий квартиль (значение, ниже которого 75% данных)\n",
" IQR = Q3 - Q1 # Вычисляем интерквартильный размах \n",
" lower_bound = Q1 - 1.5 * IQR # Вычисляем нижнюю границу\n",
" upper_bound = Q3 + 1.5 * IQR # Вычисляем верхнюю границу\n",
" outliers = df[col][\n",
" (df[col] < lower_bound) | (df[col] > upper_bound)\n",
" ] # Находим выбросы\n",
" print(f\"Выбросы в столбце '{col}':\\n{outliers}\\n\") # Выводим выбросы\n",
"\n",
"# Визуализация выбросов\n",
"numeric_cols = df.select_dtypes(\n",
" include=[\"number\"]\n",
").columns # Получаем список числовых столбцов\n",
"plt.figure(figsize=(12, 8)) # Устанавливаем размер графика\n",
"\n",
"for i, col in enumerate(\n",
" numeric_cols, 1\n",
"): # Проходим по числовым столбцам для построения графиков\n",
" plt.subplot(\n",
" len(numeric_cols) // 3 + 1, 3, i\n",
" ) # Создаем подграфик для каждого столбца\n",
" sns.boxplot(data=df, x=col) # Строим боксплот для столбца\n",
" plt.title(f\"Boxplot for {col}\") # Устанавливаем заголовок для подграфик\n",
"\n",
"plt.tight_layout() # Упорядочиваем графики\n",
"plt.show() # Отображаем графики\n",
"\n",
"# Проверка на корреляцию (насколько одна переменная изменится (и зависит) от изменения другой) между признаками\n",
"if len(df.columns) >= 2: # Проверяем, что в датасете более одного столбца\n",
" for col1 in df.columns: # Проходим по всем столбцам\n",
" for col2 in df.columns: # Сравниваем с каждым другим столбцом\n",
" if col1 != col2: # Проверяем, что это разные столбцы\n",
" correlation = df[col1].corr(df[col2]) # Вычисляем корреляцию\n",
" if abs(correlation) > 0.9: # Проверяем, превышает ли корреляция 0.9\n",
" print(\n",
" f\"Просачивание данных: Высокая корреляция ({correlation:.2f}) между столбцами '{col1}' и '{col2}'\"\n",
" ) # Выводим информацию о высокой корреляции\n",
"\n",
"\n",
"# Функция для разбиения на train/val/test\n",
"def split_stratified_into_train_val_test(\n",
" df_input,\n",
" stratify_colname=\"y\",\n",
" frac_train=0.6,\n",
" frac_val=0.15,\n",
" frac_test=0.25,\n",
" random_state=None,\n",
"):\n",
" if frac_train + frac_val + frac_test != 1.0: # Проверяем, что доли составляют 1\n",
" raise ValueError(\n",
" \"fractions %f, %f, %f do not add up to 1.0\"\n",
" % (frac_train, frac_val, frac_test)\n",
" ) # Генерируем ошибку, если это не так\n",
"\n",
" if (\n",
" stratify_colname not in df_input.columns\n",
" ): # Проверяем, есть ли колонка для стратификации\n",
" raise ValueError(\n",
" \"%s is not a column in the dataframe\" % (stratify_colname)\n",
" ) # Генерируем ошибку, если колонки нет\n",
"\n",
" X = df_input # Храним все данные\n",
" y = df_input[[stratify_colname]] # Храним целевую переменную\n",
"\n",
" df_train, df_temp, y_train, y_temp = (\n",
" train_test_split( # Разбиваем данные на обучающие и временные\n",
" X, y, stratify=y, test_size=(1.0 - frac_train), random_state=random_state\n",
" )\n",
" )\n",
"\n",
" relative_frac_test = frac_test / (\n",
" frac_val + frac_test\n",
" ) # Вычисляем относительную долю тестового набора\n",
" df_val, df_test, y_val, y_test = (\n",
" train_test_split( # Разбиваем временные данные на валидационные и тестовые\n",
" df_temp,\n",
" y_temp,\n",
" stratify=y_temp,\n",
" test_size=relative_frac_test,\n",
" random_state=random_state,\n",
" )\n",
" )\n",
"\n",
" assert len(df_input) == len(df_train) + len(df_val) + len(\n",
" df_test\n",
" ) # Проверяем, что все данные были распределены\n",
"\n",
" return df_train, df_val, df_test # Возвращаем разбитые данные\n",
"\n",
"\n",
"# целевой признак 'tax'\n",
"df[\"tax_binned\"] = pd.cut( # Разбиваем значения 'tax' на категории\n",
" df[\"tax\"],\n",
" bins=[0, 200, 400, 600, 800, 1000],\n",
" labels=[\"Very Low\", \"Low\", \"Medium\", \"High\", \"Very High\"],\n",
")\n",
"df = df.dropna() # Удаляем строки с пропусками\n",
"\n",
"# Разделение данных\n",
"df_train, df_val, df_test = (\n",
" split_stratified_into_train_val_test( # Разбиваем данные на обучающие, валидационные и тестовые\n",
" df,\n",
" stratify_colname=\"tax_binned\",\n",
" frac_train=0.60,\n",
" frac_val=0.20,\n",
" frac_test=0.20,\n",
" )\n",
")\n",
"\n",
"# Выводим размеры разбитых выборок\n",
"print(\"Обучающая выборка: \", df_train.shape)\n",
"print(\"Контрольная выборка: \", df_val.shape)\n",
"print(\"Тестовая выборка: \", df_test.shape)\n",
"\n",
"# Уравнивание данных для обучения модели\n",
"# Подход с Random Under Sampler\n",
"rus = RandomUnderSampler(\n",
" random_state=42\n",
") # Инициализируем метод уменьшения дисбаланса классов\n",
"X_resampled, y_resampled = rus.fit_resample(\n",
" df_train, df_train[\"tax_binned\"]\n",
") # Применяем undersampling\n",
"\n",
"print(df_train.tax_binned.value_counts())\n",
"\n",
"df_train_rus = pd.DataFrame(X_resampled) # Сохраняем результат в новый DataFrame\n",
"print(\n",
" \"Обучающая выборка после undersampling: \", df_train_rus.shape\n",
") # Выводим размеры новой обучающей выборки\n",
"print(\n",
" df_train_rus.tax_binned.value_counts()\n",
") # Выводим количество классов в новой обучающей выборке"
]
}
],
"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.12.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}