AIM-PIbd-32-Kozlova-A-A/lab_3/laba3.ipynb
2024-10-25 21:38:40 +04:00

758 lines
90 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **Diamonds Prices**"
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Unnamed: 0\n",
"carat\n",
"cut\n",
"color\n",
"clarity\n",
"depth\n",
"table\n",
"price\n",
"x\n",
"y\n",
"z\n"
]
}
],
"source": [
"import pandas as pd\n",
"df = pd.read_csv(\".//static//csv//Diamonds Prices2022.csv\")\n",
"\n",
"attributes = df.columns\n",
"for attribute in attributes:\n",
" print(attribute)\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### **Бизнес-цели**"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**1. Определение цены алмаза на основе его характеристик**\n",
"\n",
"**Бизнес-цель:** Разработать модель, которая позволяет прогнозировать цену алмаза на основе его характеристик (таких как карат, чистота, цвет и огранка).\n",
"\n",
"**Техническая цель:** Создать и обучить модель машинного обучения, которая принимает на вход параметры алмаза и выдает предсказанную цену. Цель — минимизация ошибки предсказания.\n",
"\n",
"**2. Классификация качества алмаза на основе характеристик**\n",
"\n",
"**Бизнес-цель:** Определить качество алмаза (например, высокая, средняя, низкая) на основе его характеристик для автоматической сортировки.\n",
"\n",
"**Техническая цель:** Создать модель классификации, которая принимает на вход характеристики алмаза и присваивает ему категорию качества. Цель — максимизация точности классификации."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### **Подготовка данных**"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Пропущенные данные по каждому столбцу:\n",
"Unnamed: 0 0\n",
"carat 0\n",
"cut 0\n",
"color 0\n",
"clarity 0\n",
"depth 0\n",
"table 0\n",
"price 0\n",
"x 0\n",
"y 0\n",
"z 0\n",
"dtype: int64\n"
]
}
],
"source": [
"import numpy as np\n",
"\n",
"# Проверка на пропущенные значения\n",
"missing_data = df.isnull().sum()\n",
"print(\"Пропущенные данные по каждому столбцу:\")\n",
"print(missing_data)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Пропущенных значений не найдено"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### **Разбиение каждого набора данных на обучающую, контрольную и тестовую выборки**"
]
},
{
"cell_type": "code",
"execution_count": 82,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Размеры выборок:\n",
"Обучающая выборка: 32365 записей\n",
"Валидационная выборка: 10789 записей\n",
"Тестовая выборка: 10789 записей\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 1200x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import pandas as pd\n",
"from sklearn.model_selection import train_test_split\n",
"import matplotlib.pyplot as plt\n",
"\n",
"# Разделение признаков (features) и целевой переменной (target)\n",
"X = df.drop(columns=['price']) # Признаки (все столбцы, кроме 'price')\n",
"y = df['price'] # Целевая переменная (цена)\n",
"\n",
"# Разбиение на обучающую (60%), валидационную (20%) и тестовую (20%) выборки\n",
"X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.4, random_state=42)\n",
"X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)\n",
"\n",
"# Проверка размеров выборок\n",
"print(f\"Размеры выборок:\")\n",
"print(f\"Обучающая выборка: {X_train.shape[0]} записей\")\n",
"print(f\"Валидационная выборка: {X_val.shape[0]} записей\")\n",
"print(f\"Тестовая выборка: {X_test.shape[0]} записей\")\n",
"\n",
"# Визуализация распределения цен в каждой выборке\n",
"plt.figure(figsize=(12, 6))\n",
"plt.subplot(1, 3, 1)\n",
"plt.hist(y_train, bins=30, color='blue', alpha=0.7)\n",
"plt.title('Обучающая выборка')\n",
"plt.xlabel('Цена')\n",
"plt.ylabel('Количество')\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Данные не сбалансированы, так как существует большая разница в количестве наблюдений для разных диапазонов цен. Это может привести к тому, что модель будет хуже предсказывать цены для более дорогих алмазов, так как таких данных меньше. Применим методы приращения."
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Размеры выборок:\n",
"Обучающая выборка: 32365 записей\n",
"Валидационная выборка: 10789 записей\n",
"Тестовая выборка: 10789 записей\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA1YAAAImCAYAAABQCRseAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABkBUlEQVR4nO3dd3hUddrG8XtShiSE3hILUrIBBGJAEsClGRVZsSG+FppSFKUpSFNRREFROigl0gRhEQWxoKuLim2lqohSQoSgoiGE0MKkzpz3DzazDEnIZM4kk5Dv57q4YE555neeqTfnzDkWwzAMAQAAAAA85ufrAQAAAABAeUewAgAAAACTCFYAAAAAYBLBCgAAAABMIlgBAAAAgEkEKwAAAAAwiWAFAAAAACYRrAAAAADAJIIVAAAAAJgU4OsBAIAndu/erRUrVmj79u1KS0tT3bp11b59ez388MO68sorXZb97rvvtGTJEu3evVunT5+Ww+GQJA0bNkzDhw/3xfBxiUhKStKCBQu0ZcsWpaamKjc3V5IUGxurlStX+nh0kKRjx45p/vz5+vrrr5WcnKycnBxJUv369fXxxx8rIICvQgC8w2IYhuHrQQBAcaxatUovvvii2rZtqx49eqhu3bo6fPiwlixZopMnT+qNN95Q06ZNJUn//ve/NWbMGA0aNEhRUVEKDQ1VQECAatasqSuuuMLHW4Ly7I8//lCPHj1044036oYbblCNGjUUGBio4OBgNW7cWH5+HBTia2fOnNEdd9yhJk2a6Pbbb1edOnVktVpltVrVuHFjBQYG+nqIAC4hBCsA5crOnTvVt29f9e7dW08//bTLvLS0NN15552qXbu21q9fL0m6/fbbdf/99+v+++/3xXBxCZs8ebKOHz+uWbNm+XooKMTy5cv18ccf66233vL1UABUAPx3GoByZcmSJapSpYpGjRqVb17NmjU1fvx43XDDDbLZbDp16pT279+vVq1aafTo0br22mt17bXXasSIEfrjjz+c69ntdsXHx+vWW29VVFSUoqOjdd9992nLli0u9ePi4tSkSZN8f+Li4pzLZGZmasaMGeratatatGih1q1bq3///tq7d69zmfHjx7usI53b+9GkSRNnIJSkgwcPatiwYYqNjVVMTIwGDx6sX3/9tdDls7KydMMNN6hJkybOaX379tX48eO1cOFCXXfddbr22ms1ZMgQHTlyxOX+d+/erYEDB6pt27Zq3bq1HnnkER04cMA5f+vWrS7b3KJFC8XFxWnp0qUudTZt2qRevXqpVatWatGihbp166ZVq1blq7N161aX9fr27au+ffs6bzdp0kTz5s1zWWbevHku2+bO43b69Gk99dRT6tChQ77H7cIxnM9ut2vVqlW67bbbFBUVpS5dumj69OnKyspyLrNt2zZ17txZc+fOVceOHRUVFaX77rvPWffAgQNq0qRJvi/1f/31l5o1a6b3338/33YX1iNP+vr555/rtttuU4sWLdSlSxfNmzfPeRisdO75PH78eOftgp5TBdXdt2+fhg0bpnbt2ql58+bq2LGjJk+erMzMTOcyn332mXr06KFrrrnGpecXbuv51q9fn+85dvPNN+v99993LnPhc6CwGnmv761bt+r666/XihUrdMMNN6hly5a644479Mknn7isl5WVpddee03dunVTy5Yt1bVrV8XHx7v0y53X0oXj27hxo2JiYjRjxgxJ7r/XACifOLAYQLlhGIa++eYbxcXFKTg4uMBlbrnlFue/9+zZI0l64oknVKdOHb388svKzs7Wq6++qvvuu0/vvfeeatWqpenTp+uf//ynnnjiCTVp0kRHjx7Va6+9pscee0ybN292ua/OnTtryJAhztvz589XYmKi8/bYsWO1Y8cOjRo1SvXr19fhw4c1Z84cPfHEE9q4caMsFotb23r06FHde++9qlevnp577jmFhIRo3rx5euCBB/Thhx8WuM7ixYtdAmOezz77TDVq1NCECRPkcDg0Y8YM9e3bVxs3blRwcLC2bNmiQYMGqW3btnrxxReVlZWlRYsW6b777tPatWvVuHFjZ61nn31WzZs319mzZ7Vx40a9/PLLatq0qa677jpt3rxZQ4cOVb9+/TR8+HBlZmZq9erVev7559WiRQtdc801bm27u9x53KZOnap//etfGjdunBo3bqyAgAD98ssvev755y9a+9lnn9V7772nhx56SG3atNGePXv02muvae/evVq8eLEsFouOHDmi119/XRkZGXriiSdUvXp1rV27VgMGDNCSJUvUrl07XXPNNXrvvfd07733Omtv2LBBISEh6tq1q95+++0it9OTvu7evVtDhw7VnXfeqbFjxyohIUGzZs2SzWbTuHHjit/s/0pJSVHv3r0VHR2tqVOnymq16quvvtKyZctUt25dPfzww/rtt9/02GOPqWPHjho5cqSqVq0qSZo0aZJb9/Hqq6+qTp06OnXqlNasWaNx48apZcuWatiwYbHHe+TIEf32229KTU3V448/riuuuEIff/yxRowYoZdffll33nmnDMPQI488oh9//FHDhg1T06ZNtXXrVs2ePVu///67XnjhBWe9ol5L58vMzNTzzz+vQYMG6bbbbpPk3nMWQPlFsAJQbpw4cUJZWVlu/zbKZrNJkrKzs/X66687f09x7bXX6sYbb9TSpUs1ZswYpaSkaOTIkS7/m16pUiUNHz5c+/fvV3R0tHN6zZo1893Ok52drbNnz2rChAnOgBcbG6v09HRNnTpVqampqlOnjltjX758ubKzs7Vs2TLnOk2bNtX999+vXbt2uYQd6dxekNdff13NmzfXL7/84jIvIyND69evd57Uo1GjRurRo4c2bNig+++/XzNmzNBVV12l+Ph4+fv7S5I6dOigm266SXPnztWcOXOctSIiIpzbHx0drXXr1unnn3/Wddddp8TERPXo0cPlEM1WrVqpbdu22rp1q9eDlTuP208//aQOHTq4BJvz9zoVJDExUe+8846eeOIJPfzww5Kkv//976pbt67Gjh2rr776Sp07d1ZGRoYOHTqkjz76SA0aNJB0LnjfcccdmjFjht5++2317NlTEydO1O+//+7s/4YNG9S9e3cFBQXJz89P2dnZRY6nuH199dVX1apVK7300kuSpI4dO+rMmTNavHixBg8erOrVq1/0PguTkJCgZs2aac6cOQoNDZUkXXfddfr222+1detWPfzww9qzZ49ycnI0cuRIRUZGOtfNW74ozZo1c77Gw8PD9fnnn2vv3r0eBauMjAz99ttveuONN9SuXTtJ53qRlpam6dOn6/bbb9fXX3+t//znP5o5c6a6d+8u6dzjHRQUpDlz5qhfv37629/+5qx3sdfS+T788EMFBgZq0KBBztdVcd5rAJQ/BCsA5UbelxO73e7W8nl7h7p37+7yI/V69erp2muvdR7elHeYTlpamg4ePKjDhw/riy++kKQiv/Sez2q1asmSJZLO7XE6dOiQkpKSCq2VdwY5SS6HHEnnfksWHR3tEsTCwsKctS7cM/Xyyy+rTZs2uuaaa/IFq9atW7ucKfHqq6/WlVdeqe3bt+uOO+7Q7t27NWzYMGd/Jalq1aq6/vrr9eWXX7rUcjgcys3NVVZWllavXi1JatmypSRp0KBBkqSzZ8/q0KFD+u2337R79+4Ctz2vTh7DMPLtzbtwmQt75M7j1rJlS33xxRf67rvv1KJFCwUHB+erc6Ft27ZJkvNLdp7u3bvrySef1NatW9W5c2dZLBZdc801zlAlnXvOdevWTXPnztXZs2fVvXt3vfTSS3rvvfc0bNgwff/990pKStLUqVMlSbVq1dKPP/540fEUt685OTn6/vvv9dBDD7nM69SpkxYsWKBdu3apc+fOF73PwnTo0EEdOnRQTk6OEhMTdfjwYSUkJCgtLc0Z1po3b66AgAC9+eabGjx4sOrUqSM/P78CH+OC5D3uGRkZWrt2rQICApwno8mTm5sri8Xi8pwtiMViUVhYmDNU5fnHP/6hL774QgcPHtS2bdsUEBCgbt26uSxz++23a86cOdq2bZszWF3stXR+sDp69Khef/119erVy2WM3nqvAVA2EawAlBvVqlVT5cqV9eeffxa6jM1mU05OjnNZ6VyQulCNGjX0119/STp32NSkSZO0e/duBQcHKyIiQpdddpmkc1/4i+Prr7/Wiy++qIMHD6py5cpq2rSpQkJC8tU6cuSImjdvXmidkydPur1nbtu2bdq0aZPef/99bdy4Md/8gra/Vq1aOnXqlM6cOSPDMFS7du18y9SuXVtnzpxxmfbggw+63G7Xrp3zS2taWpomTpyoTZs2yWKx6KqrrlKbNm0k5e/jhXWkc3v3zjd//nzNnz8//wb/lzuP27hx45SRkaHBgwcXuacqz6lTpyQp397FgIAA1ahRw9mTypUrF/rcMgxDZ8+eVd26ddWtWze9//77GjZsmDZs2KCGDRuqVatWkqQuXbpo48aNWrRokXr37q3jx49r8+bNLvU87Wu1atXyjev87fOEw+HQzJkztWrVKtlsNoWHhysqKkqVKlVyLnPllVdq2rRpmjlzZr7fl134GBfkpptucrl91113qVGjRi7T8l47lStXVsOGDdWvXz/dcccd+WpVrly5wL1zeb04c+aMTp06pRo1auQLaXmP//mvgYu9ls7XqVMnNW/ePF+49eZ7DYCyh2AFoFzp0KGDtm7dqqysLJcvc3nWrl2rl19+We+8847q168vSTp+/Hi+5f7880/Vrl1b6enpGjRokJo0aaKNGzeqUaNG8vPz05dffpnvB+6SLvo/7r/99puGDh2qG2+8UYsWLdKVV14pi8WiVatW6euvv3ZZtk6dOlqwYIHz9rFjx/Too486b1epUkVpaWn57uO7777TFVdc4RyH3W7X5MmT1a9fv3xfPvOcOHEi37TU1FTVr19fVapUkcViUWpqar5ljh07lu9L6aRJk9S8eXPl5ubq559/1ksvvaRly5ZpwIABGj16tA4ePKjly5erVatWslqtzr0OF8qrk2fixIn5lrnnnnt0zz33OG+vXbvWWcvdx6169eoaMGCAduzYoebNm2vgwIE6ePBggfeXJy+QHDt2TJdffrlzek5Ojk6cOOH8Un7ZZZcV+tzy8/NzLtezZ0+9++67+umnn/TJJ59o4MCBzmVvu+02/fzzz5ozZ45mzpwpKX+g86Sv/fr1yze2vOfThYGrOOLj47V8+XJNmjRJXbt2VZUqVSRJd999t8ty//jHP/Ttt9/q+PHjevrppxUZGannnnvOrftYsGCB6tSpo+zsbH377bd67bXX1KVLF918883OZd555x1J5w7N+/zzzzV27Fjnf2Cc77LLLtO+ffvyTc/7z5natWurWrVqOnHihOx2u0u4SklJkfS/ECZd/LV0vnnz5mnixImaOHGiXnzxRUnuP2cBlF+cFRBAuTJgwACdPHlSs2fPzjfv2LFjWrp0qSIiItS8eXNVqVJF0dHR+vjjj10OH0xMTNSuXbvUqVMnHTx4UCdPnlS/fv0UERHhvPbQV199Jcn18DOHw3HRaxP9/PPPysrK0sMPP6z69es7w09eqDr/f6StVqtatmzp/HP+b1EkqU2bNtq1a5dLuDp+/LgGDRrkcnje2rVrlZaW5nJCjQvt3LnT5Qvhzz//rD/++EPt27dXSEiIWrRoka9HZ86c0ebNm3Xttde61GrYsKFatmypVq1aqW/fvmratKnzjGY7d+5U165d1bZtW1mt1kL7eH6dvD95exfPV7duXZdl6tat65zn7uOWkZGhxx9/XFarVbNmzVJsbGyRv9XJ26ty4d6/jRs3ym63O3vSsWNH/fDDDy6HZWZnZ+vDDz/Udddd5zz8NCYmRg0aNNC0adOc11XKY7FY9NRTT+mbb77RBx98oK1btzoPF8vjSV8bN26c7zDOr776SgEBAc5DNz2xc+dORUREqGfPns5QdfToUSUkJLiMZfXq1XrnnXc0evRo3X333YqKiirwMS5IZGSkWrZs6TyDZ/Xq1fOdNS/vOREbG6vx48eratWqBZ7lsWPHjvrjjz/0ww8/OKcZhqF3331XDRo00JVXXqnY2Fjl5ubqX//6l8u6eWcjPP81cLHX0vm6du2ql156SevWrdNHH30kyf3nLIDyiz1WAMqV6OhoPfbYY5o9e7Z+/fVX3XnnnapRo4YOHDigJUuWKCsryyV0jR07Vg888IAGDRqkvn376syZM5o9e7auvPJK9e7dW4ZhKDQ0VAsXLlRAQIACAgL0ySefuPyP+NGjR7V//36lpaU5z3BWkLzflkybNk0DBgxQdna21q9f7zy0K+9kGu548MEHtWHDBg0aNEiDBw9WYGCgFixYoLCwMN12223Ow5N++uknvfzyyxc9MUBGRoYGDRqkRx99VGfPntWsWbMUGRmpW2+9VdK5syYOHDhQDz/8sHr16qWcnBzFx8crOztbQ4cOdamVmJioSpUqKScnR/v371dCQoLzUMCoqCh98MEHat68ucLCwvT9998rPj5eFotFGRkZbm+7Oxo2bFjk4yad2/tx5MgRLVq0qMA9GgWJiIhQjx49NHfuXGVkZCgmJkZ79+7Vq6++qrZt26pjx46SpIEDB+r999/Xgw8+qOHDh6tKlSpavny5UlNT8x3C2LNnT82YMUOdOnUq8HCymjVrupwI5Xye9PWhhx7SiBEj9NRTT+mWW27Rzz//rCVLluj+++93uZ+0tDTnb7yOHTsm6dye17xpeWe8TExMVKtWrRQVFaX58+crPj5e0dHROnz4sBYtWqTs7GznWI4fP67Zs2crKipKvXr1cqvn59u7d69SU1OVlZWlHTt26OTJk4qIiHBZ5scff5RhGDp9+rS++OILnT59WjExMTp79qzLcj179tQ///lPDRkyRI899pjCw8O1bt067dq1SwsXLpR07rC9tm3basKECTp69KiaNm2qbdu26fXXX1ePHj1c7ruo19L58vayvfTSS+rUqZPbz1kA5RfBCkC58+ijj+rqq6/WqlWr9OKLL+rUqVMKDw9Xly5d9Mgjjyg8PNy57LXXXqvXX3/decrzgIAA55eovDAyf/58vfLKK3rsscdUuXJlNWvWTG+++aYeeugh7dixQwkJCZozZ44aNmyo//u//yt0XFdddZVmzJihV199VY8++qiqVaum6OhorVy5Un379tWOHTsueg2e84WHh2v16tWaNm2axo8fL6vVqrZt22rWrFmqVq2aM1i1atWqwN+WnK9NmzZq166d86xycXFxGjt2rHPvR/v27bVs2TLNnTtXo0aNktVqVZs2bfTyyy87f7SfJ+805RaLRbVr19btt9/uDF9Tp07VCy+84Dw9dYMGDTRp0iS9//772rFjh1vb7a4qVaoU+bg1atRIS5cuVVxcnLp06VKs+lOmTNFVV12ldevW6fXXX1fdunXVr18/DRkyxLmnoXr16lq5cqVeeeUV52nqmzZtqmXLlqlZs2Yu9Tp37qwZM2borrvuKva2etLXm2++WZMnT9aSJUv0/vvvq1atWho8eHC+PZtffvllvj1bCxYscDlMVTr3uHfu3FmDBw/WiRMntGLFCr322msKDw/XHXfcIYvFokWLFun06dOaPn260tPTNXHiRLcvL3C+YcOGSTp3spo6depowIABuu+++1yWyTvLY1BQkK688kpNmjRJN998s8s1uCQpMDBQS5cu1bRp0zRv3jydOXNGDRs21Kuvvup8TuSNfe7cuVq+fLnS0tJ0xRVXaNSoUerfv79LvaJeSxd66qmn9I9//EPz5s3Tk08+WeRz9sLr2wEoXywGv5YEgEtW3mmdV65c6eORVGx5v03avHlzoV/Cy6o//vhDN9xwgz777DO3T6hyKeK1BKAo7LECAKCEvPvuu0pISNDq1as1ZMiQcheqAADuI1gBAFBC9u3bpzVr1uimm27SgAEDfD0cj1itVl1zzTWEQgAoAocCAgAAAIBJnG4dAAAAAEwiWAEAAACASQQrAAAAADCJk1dc4IcffpBhGAoMDPT1UAAAAAD4UE5OjiwWi1q1alXksuyxuoBhGCqp83kYhqHs7OwSq4/C0Xvfov++Q+99h977Fv33HXrvO/Te+4qTDdhjdYG8PVUtW7b0em2bzaa9e/cqIiJCISEhXq+PwtF736L/vkPvfYfe+xb99x167zv03vt2797t9rLssQIAAAAAkwhWAAAAAGASwQoAAAAATCJYAQAAAIBJBCsAAAAAMIlgBQAAAAAmEawAAAAAwKQyEaw2bNigW265RS1btlT37t318ccfO+f98ccfGjx4sFq3bq0OHTpo9uzZstvtLuuvWrVKN9xwg6KiotSrVy/t2bOntDcBAAAAQAXm82D1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XFyc5syZo59++sll+q5duzRv3jzFxcV5ZXAAAAAAUB549Bur4cOH6z//+Y/uvfdeXX755apdu7ZSU1N15MgRNW7cWE888YS3xwkAAAAAZZZHwSo0NFTvvPOO1q1bp+3bt+vUqVNq2bKlBgwYoLvuuktBQUHeHicAAAAAlFkeX8eqUqVK6tWrl3r16uWcduLECUIVAAAAgArHo99YnTp1SmPHjlX37t01fvx4HTx4UHfccYeuu+46dejQQbt27fL2OAEAAACgzPIoWD3zzDP67LPP1LhxY33zzTfq2bOn7Ha7JkyYoLp162ratGneHicAAAAAlFkeHQq4ZcsWjRs3Tvfcc49++ukn3XPPPRozZow6d+6sevXqafz48d4eJwAAAACUWR7tsTpz5owaNWokSWrWrJkkqVatWs6/z54966XhAQAAAEDZ51GwMgxDVqv1XAE/vwL/BgAAAICKwuOzAs6fP181atRw3p43b56qV6+uEydOeGVgAAAAAFBeeBSsLrvsMiUkJLjc3r9/v/N2eHi4+ZEBAAAAQDnhUbD6/PPPvT0OAAAAACi3PPpBVL9+/fTrr796eywAAAAAUC55FKy2bdvGmf8AAAAA4L84hR8AAAAAmOTxWQHvvffeQudZLBbt2bPH09IAAAAAUK54HKx69uypsLAwb44FAAAAAMolj4PVPffco6ioKG+OBQAAAADKJX5jBQAAAAAmeRSsVqxYocaNGystLc057fTp00pMTPTawAAAAACgvPAoWDVr1kyPPfaYevfu7Zz2448/6tZbb9WIESOUmZnptQECAAAAQFnnUbCaPn269u7dq+HDhzuntWvXTvPmzdP333+vefPmeW2AAAAAAFDWeRSsPv/8c40bN0633HKLc5rVatVNN92kUaNG6aOPPvLaAAEAAACgrPMoWKWnp6tatWoFzqtTp47Lb68AAAAA4FLnUbBq2rSp1q1bV+C8DRs2qEmTJqYGBQAoTZwgFgAAszy6jtUjjzyiRx55RHfddZduuukm1apVS2lpafriiy+0e/duLViwwNvjBACUhIBQyeIn2Y6U7H1YCz7KAQCAS4VHwapz586aP3++5s2bp7lz58owDFksFjVr1kzz589X586dvT1OAEBJ8A+W7DYpMV7KTPV+/aDaUuQwghUA4JLnUbCSpOuvv17XX3+9srKydPLkSVWpUkUhISHeHBsAoLRkpkqZyb4eBQAA5ZapA+t//fVXvfXWW3rzzTd15swZ7dixQ+np6d4aGwAAAACUCx7tsXI4HHr22We1bt0652GA3bp10/z58/Xbb7/pzTffVFhYmLfHCgAAAABlkkd7rObPn68PPvhAkydP1rfffivDMCRJY8aMkcPh0KxZs7w6SAAAAAAoyzwKVuvWrdOIESPUs2dPVa9e3Tm9WbNmGjFihL799ltvjQ8AAAAAyjyPglVqaqqaNWtW4Lx69erp9OnTpgYFAAAAAOWJR8Hqqquu0pdfflngvG3btumqq64yNSgAAAAAKE88OnnFAw88oGeffVY5OTm6/vrrZbFYdPjwYW3dulVLly7V+PHjvT1OAAAAACizPApW//d//6e0tDQtWLBA//znP2UYhkaNGqXAwEANGjRI999/v7fHCQAAAABllscXCB48eLB69+6t77//XqdOnVLVqlV1zTXXuJzMAgAAAAAqAlMXCA4NDVWnTp102223qXPnzh6FquPHj2vMmDFq166dWrVqpYcffli//vqrc/7evXvVp08fRUdHKy4uTitWrHBZ3+FwaO7cuerYsaOio6P10EMP6ffffzezWQAAAABQLB7tsYqLi5PFYil0vsVi0aZNm9yqNXToUDkcDsXHx6ty5cqaM2eOHnzwQX366afKzMxU//79FRcXp0mTJunHH3/UpEmTVLlyZfXs2VPSuWtqrV69WlOnTlVYWJimTZumQYMG6YMPPpDVavVk8wAAXmXq//AAACgXPApWsbGxLsHqwIED+v333xUXF1esOqdOndLll1+uwYMHKzIyUpI0ZMgQ3XHHHTpw4IC+++47BQYG6vnnn1dAQIAaN26sw4cPKz4+Xj179lR2draWLl2q0aNHq0uXLpKkWbNmqWPHjvr000916623erJ5AABvCQiVLH6S7UjJ1bdWK5naAAAUg0fBaurUqS63d+zYoUGDBun5559XYGCg23WqVaumGTNmOG+npaVp+fLlCgsLU0REhObNm6fY2FgFBPxvmO3atdOiRYuUmpqqP//8U2fPnlX79u2d86tWraqrr75a27dvJ1gBgK/5B0t2m5QYL2Wmerd2UG0pchjBCgBQJnh88orzNW3aVJmZmfrzzz89vobVM888o7Vr18pqtWrBggUKCQlRcnKyc09Wnrp160qS/vrrLyUnJ0uS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qVJmsq9HAQBlhs8Pkh41apR++OEHzZw5U+vWrVOzZs00cOBAHTx4UL/++qsGDx6sjh07av369fq///s/jR07Vt99951z/eeee07ffPON5s2bpzfeeEMHDx7UiBEjfLhFAAAAACoan+6xOnz4sL799lutXr1a1157rSTpmWee0ddff60PPvhAx48fV5MmTTRy5EhJUuPGjbVnzx4tXrxY7du319GjR7VhwwYtXLjQuYdr5syZ6tatm3744Qe1atXKZ9sGAAAAoOLw6R6rGjVqKD4+Xi1btnROs1gsslgsOn36tHbs2KH27du7rNOuXTvt3LlThmFo586dzml5GjZsqHr16mn79u2lsxEAAAAAKjyfBquqVauqc+fOslqtzmmffPKJDh8+rI4dOyo5OVlhYWEu69StW1cZGRk6ceKEjh49qho1aqhSpUr5lklO5rhvAAAAAKXD5yevON/333+vJ598Ul27dlWXLl2UmZnpErokOW9nZ2crIyMj33xJqlSpkrKysjweh2EYstlsHq9fmIyMDJe/3WGxWGR12CWHXbLbvTsgh11+khxGCdQu6frFrG132F3+9nb9YqlAfc/jVv8rYF9Ko36RvS/DY/dpbS/Uv2jvy/jYfVb7v/XlsCs7I0OGYXhcxpPPXHgHvfcdeu99hmHIYrG4tWyZCVabNm3S6NGj1bp1a02fPl3SuYCUnZ3tslze7eDgYAUFBeWbL507U2BwcLDHY8nJydHevXs9Xr8oSUlJbi9rtVrVKDxI9rM2OWzpXh2Hf6VMhTgcstkyZE/3bu2Sru9pbZvNvTeasjj2slDfbO2L9b8i96U06hfW+/Iwdl/U9mb9gnpfXsZe2rUlyc9hk39mlg7+lVjgZ3xxFeczF95F732H3ntXQTtyClImgtWbb76pKVOmqFu3bnr55Zedgw8PD1dKSorLsikpKQoJCVGVKlUUFhamkydPKjs722WDU1JSVK9ePY/HExgYqIiICI/XL0xGRoaSkpLUoEEDt4OfxWKR1X5Mqhwi+YV6d0DBQfLz81NISLAkL9cu6frFrG132GWzZSgkJFj+fv5er18sFajvedzqfwXsS2nUL7L3ZXjsPq3thfoX7X0ZH7vPaktScIgUVEkREVeY3mNV3M9ceAe99x16732JiYluL+vzYLV69Wq98MIL6tu3r55++mmXXW1t2rTRtm3b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",
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import pandas as pd\n",
"from sklearn.model_selection import train_test_split\n",
"import matplotlib.pyplot as plt\n",
"from imblearn.under_sampling import RandomUnderSampler\n",
"from imblearn.over_sampling import SMOTE\n",
"\n",
"# Разделение признаков (features) и целевой переменной (target)\n",
"X = df.drop(columns=['price']) # Признаки (все столбцы, кроме 'price')\n",
"y = df['price'] # Целевая переменная (цена)\n",
"\n",
"# Применение one-hot encoding для категориальных признаков\n",
"X = pd.get_dummies(X, drop_first=True)\n",
"\n",
"# Разбиение на обучающую (60%), валидационную (20%) и тестовую (20%) выборки\n",
"X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.4, random_state=42)\n",
"X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)\n",
"\n",
"# Проверка размеров выборок\n",
"print(f\"Размеры выборок:\")\n",
"print(f\"Обучающая выборка: {X_train.shape[0]} записей\")\n",
"print(f\"Валидационная выборка: {X_val.shape[0]} записей\")\n",
"print(f\"Тестовая выборка: {X_test.shape[0]} записей\")\n",
"\n",
"# Применение RandomUnderSampler для уменьшения размеров больших классов\n",
"undersampler = RandomUnderSampler(random_state=42)\n",
"X_undersampled, y_undersampled = undersampler.fit_resample(X_train, y_train)\n",
"\n",
"# Применение SMOTE для увеличения сбалансированности\n",
"smote = SMOTE(random_state=42)\n",
"X_resampled, y_resampled = smote.fit_resample(X_undersampled, y_undersampled)\n",
"\n",
"# Визуализация распределения цен в сбалансированной выборке\n",
"plt.figure(figsize=(10, 6))\n",
"plt.hist(y_resampled, bins=30, color='orange', alpha=0.7)\n",
"plt.title('Сбалансированная обучающая выборка')\n",
"plt.xlabel('Цена')\n",
"plt.ylabel('Количество')\n",
"plt.show()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Теперь данные намного более сбаланчированные."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### **Конструировании признаков**"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"1. Унитарное кодирование категориальных признаков (One-Hot Encoding)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Унитарное кодирование уже было пременено. Выведем имеющиеся столбцы"
]
},
{
"cell_type": "code",
"execution_count": 84,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Данные до унитарного кодирования:\n",
" Unnamed: 0 carat cut color clarity depth table price x y \\\n",
"0 1 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 \n",
"1 2 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 \n",
"2 3 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 \n",
"3 4 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 \n",
"4 5 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 \n",
"\n",
" z \n",
"0 2.43 \n",
"1 2.31 \n",
"2 2.31 \n",
"3 2.63 \n",
"4 2.75 \n",
"\n",
"Данные после унитарного кодирования:\n",
" Unnamed: 0 carat depth table price x y z cut_Good \\\n",
"0 1 0.23 61.5 55.0 326 3.95 3.98 2.43 False \n",
"1 2 0.21 59.8 61.0 326 3.89 3.84 2.31 False \n",
"2 3 0.23 56.9 65.0 327 4.05 4.07 2.31 True \n",
"3 4 0.29 62.4 58.0 334 4.20 4.23 2.63 False \n",
"4 5 0.31 63.3 58.0 335 4.34 4.35 2.75 True \n",
"\n",
" cut_Ideal ... color_H color_I color_J clarity_IF clarity_SI1 \\\n",
"0 True ... False False False False False \n",
"1 False ... False False False False True \n",
"2 False ... False False False False False \n",
"3 False ... False True False False False \n",
"4 False ... False False True False False \n",
"\n",
" clarity_SI2 clarity_VS1 clarity_VS2 clarity_VVS1 clarity_VVS2 \n",
"0 True False False False False \n",
"1 False False False False False \n",
"2 False True False False False \n",
"3 False False True False False \n",
"4 True False False False False \n",
"\n",
"[5 rows x 25 columns]\n"
]
}
],
"source": [
"import pandas as pd\n",
"df1 = pd.read_csv(\".//static//csv//Diamonds Prices2022.csv\")\n",
"\n",
"print(\"Данные до унитарного кодирования:\")\n",
"print(df1.head())\n",
"\n",
"# Применение унитарного кодирования для категориальных признаков\n",
"df_encoded = pd.get_dummies(df1, drop_first=True)\n",
"\n",
"print(\"\\nДанные после унитарного кодирования:\")\n",
"print(df_encoded.head())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Видим что данные изменились."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2. Дискретизация числовых признаков\n"
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Данные до дискретизации:\n",
" Unnamed: 0 carat cut color clarity depth table price x y \\\n",
"0 1 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 \n",
"1 2 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 \n",
"2 3 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 \n",
"3 4 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 \n",
"4 5 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 \n",
"\n",
" z \n",
"0 2.43 \n",
"1 2.31 \n",
"2 2.31 \n",
"3 2.63 \n",
"4 2.75 \n",
"\n",
"Данные после дискретизации:\n",
" price price_bins\n",
"0 326 0-5k\n",
"1 326 0-5k\n",
"2 327 0-5k\n",
"3 334 0-5k\n",
"4 335 0-5k\n"
]
}
],
"source": [
"import pandas as pd\n",
"df1 = pd.read_csv(\".//static//csv//Diamonds Prices2022.csv\")\n",
"\n",
"print(\"Данные до дискретизации:\")\n",
"print(df1.head())\n",
"\n",
"bins = [0, 5000, 10000, 15000, 20000]\n",
"labels = ['0-5k', '5k-10k', '10k-15k', '15k-20k']\n",
"df1['price_bins'] = pd.cut(df1['price'], bins=bins, labels=labels, right=False)\n",
"\n",
"print(\"\\nДанные после дискретизации:\")\n",
"print(df1[['price', 'price_bins']].head())\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Видим, что данные изменились."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 3. «Ручной» синтез признаков"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Данные до синтеза признака:\n",
" Unnamed: 0 carat cut color clarity depth table price x y \\\n",
"0 1 0.23 Ideal E SI2 61.5 55.0 326 3.95 3.98 \n",
"1 2 0.21 Premium E SI1 59.8 61.0 326 3.89 3.84 \n",
"2 3 0.23 Good E VS1 56.9 65.0 327 4.05 4.07 \n",
"3 4 0.29 Premium I VS2 62.4 58.0 334 4.20 4.23 \n",
"4 5 0.31 Good J SI2 63.3 58.0 335 4.34 4.35 \n",
"\n",
" z \n",
"0 2.43 \n",
"1 2.31 \n",
"2 2.31 \n",
"3 2.63 \n",
"4 2.75 \n",
"\n",
"Данные после синтеза признака 'price_per_carat':\n",
" price carat price_per_carat\n",
"0 326 0.23 1417.391304\n",
"1 326 0.21 1552.380952\n",
"2 327 0.23 1421.739130\n",
"3 334 0.29 1151.724138\n",
"4 335 0.31 1080.645161\n"
]
}
],
"source": [
"import pandas as pd\n",
"\n",
"# Загрузка данных\n",
"df1 = pd.read_csv(\".//static//csv//Diamonds Prices2022.csv\")\n",
"\n",
"# Проверка первых строк данных\n",
"print(\"Данные до синтеза признака:\")\n",
"print(df1.head())\n",
"\n",
"# Создание нового признака 'price_per_carat' (цена за караты)\n",
"df1['price_per_carat'] = df1['price'] / df1['carat']\n",
"\n",
"# Проверка первых строк данных после синтеза признака\n",
"print(\"\\nДанные после синтеза признака 'price_per_carat':\")\n",
"print(df1[['price', 'carat', 'price_per_carat']].head())\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 4. масштабирование признаков на основе нормировки и стандартизации.\n"
]
},
{
"cell_type": "code",
"execution_count": 91,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Данные до масштабирования:\n",
" price carat price_per_carat\n",
"0 326 0.23 1417.391304\n",
"1 326 0.21 1552.380952\n",
"2 327 0.23 1421.739130\n",
"3 334 0.29 1151.724138\n",
"4 335 0.31 1080.645161\n",
"\n",
"Данные после нормировки:\n",
" price carat price_per_carat\n",
"0 0.000000 0.006237 0.021828\n",
"1 0.000000 0.002079 0.029874\n",
"2 0.000054 0.006237 0.022087\n",
"3 0.000433 0.018711 0.005994\n",
"4 0.000487 0.022869 0.001757\n",
"\n",
"Данные после стандартизации:\n",
" price carat price_per_carat\n",
"0 -0.904102 -1.198189 -1.287394\n",
"1 -0.904102 -1.240384 -1.220321\n",
"2 -0.903851 -1.198189 -1.285233\n",
"3 -0.902096 -1.071605 -1.419396\n",
"4 -0.901846 -1.029411 -1.454713\n"
]
}
],
"source": [
"import pandas as pd\n",
"from sklearn.preprocessing import MinMaxScaler, StandardScaler\n",
"df1 = pd.read_csv(\".//static//csv//Diamonds Prices2022.csv\")\n",
"\n",
"# Создание нового признака 'price_per_carat' (цена за караты)\n",
"df1['price_per_carat'] = df1['price'] / df1['carat']\n",
"\n",
"# Проверка первых строк данных до масштабирования\n",
"print(\"Данные до масштабирования:\")\n",
"print(df1[['price', 'carat', 'price_per_carat']].head())\n",
"\n",
"# Масштабирование признаков на основе нормировки\n",
"min_max_scaler = MinMaxScaler()\n",
"df1[['price', 'carat', 'price_per_carat']] = min_max_scaler.fit_transform(df1[['price', 'carat', 'price_per_carat']])\n",
"\n",
"# Проверка первых строк данных после нормировки\n",
"print(\"\\nДанные после нормировки:\")\n",
"print(df1[['price', 'carat', 'price_per_carat']].head())\n",
"\n",
"# Стандартизация признаков\n",
"standard_scaler = StandardScaler()\n",
"df1[['price', 'carat', 'price_per_carat']] = standard_scaler.fit_transform(df1[['price', 'carat', 'price_per_carat']])\n",
"\n",
"# Проверка первых строк данных после стандартизации\n",
"print(\"\\nДанные после стандартизации:\")\n",
"print(df1[['price', 'carat', 'price_per_carat']].head())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"конструирование признаков с применением фреймворка Featuretools."
]
},
{
"cell_type": "code",
"execution_count": 94,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"c:\\D\\semester5\\mii\\aimenv\\Lib\\site-packages\\featuretools\\entityset\\entityset.py:1733: UserWarning: index index not found in dataframe, creating new integer column\n",
" warnings.warn(\n",
"c:\\D\\semester5\\mii\\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:\\D\\semester5\\mii\\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:\\D\\semester5\\mii\\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:\\D\\semester5\\mii\\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:\\D\\semester5\\mii\\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:\\D\\semester5\\mii\\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:\\D\\semester5\\mii\\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"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Built 12 features\n",
"Elapsed: 00:00 | Progress: 100%|██████████\n",
"Новые признаки, созданные с помощью Featuretools:\n",
" Unnamed: 0 carat cut color clarity depth table price x \\\n",
"index \n",
"0 1 0.23 Ideal E SI2 61.5 55.0 326 3.95 \n",
"1 2 0.21 Premium E SI1 59.8 61.0 326 3.89 \n",
"2 3 0.23 Good E VS1 56.9 65.0 327 4.05 \n",
"3 4 0.29 Premium I VS2 62.4 58.0 334 4.20 \n",
"4 5 0.31 Good J SI2 63.3 58.0 335 4.34 \n",
"\n",
" y z price_per_carat \n",
"index \n",
"0 3.98 2.43 1417.391304 \n",
"1 3.84 2.31 1552.380952 \n",
"2 4.07 2.31 1421.739130 \n",
"3 4.23 2.63 1151.724138 \n",
"4 4.35 2.75 1080.645161 \n"
]
}
],
"source": [
"import pandas as pd\n",
"import featuretools as ft\n",
"df1 = pd.read_csv(\".//static//csv//Diamonds Prices2022.csv\")\n",
"\n",
"# Создание нового признака 'price_per_carat'\n",
"df1['price_per_carat'] = df1['price'] / df1['carat']\n",
"\n",
"# Создание EntitySet\n",
"es = ft.EntitySet(id='diamonds')\n",
"\n",
"# Добавление данных\n",
"es = es.add_dataframe(dataframe_name='diamonds_data', dataframe=df1, index='index')\n",
"\n",
"# Конструирование признаков\n",
"features, feature_defs = ft.dfs(entityset=es, target_dataframe_name='diamonds_data', verbose=True)\n",
"\n",
"# Проверка первых строк новых признаков\n",
"print(\"Новые признаки, созданные с помощью Featuretools:\")\n",
"print(features.head())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### **Оценка качества**"
]
},
{
"cell_type": "code",
"execution_count": 95,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Время обучения: 0.0694 секунд\n",
"MAE: 352.05\n",
"MSE: 363100.29\n",
"R^2: 0.98\n",
"Корреляция: 0.99\n",
"Среднее MSE (кросс-валидация): 885042.98\n"
]
}
],
"source": [
"import pandas as pd\n",
"import time\n",
"from sklearn.model_selection import train_test_split\n",
"from sklearn.linear_model import LinearRegression\n",
"from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score\n",
"import numpy as np\n",
"\n",
"# Загрузка данных\n",
"df1 = pd.read_csv(\".//static//csv//Diamonds Prices2022.csv\")\n",
"\n",
"# Создание нового признака 'price_per_carat'\n",
"df1['price_per_carat'] = df1['price'] / df1['carat']\n",
"\n",
"# Унитарное кодирование\n",
"X = pd.get_dummies(df1.drop(columns=['price']), drop_first=True)\n",
"y = df1['price']\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",
"def evaluate_model(X_train, X_test, y_train, y_test):\n",
" model = LinearRegression()\n",
" \n",
" # Измерение времени обучения\n",
" start_time = time.time()\n",
" model.fit(X_train, y_train)\n",
" training_time = time.time() - start_time\n",
" \n",
" # Прогнозирование\n",
" y_pred = model.predict(X_test)\n",
" \n",
" # Оценка метрик\n",
" mae = mean_absolute_error(y_test, y_pred)\n",
" mse = mean_squared_error(y_test, y_pred)\n",
" r2 = r2_score(y_test, y_pred)\n",
" \n",
" # Корреляция\n",
" correlation = np.corrcoef(y_test, y_pred)[0, 1]\n",
" \n",
" print(f\"Время обучения: {training_time:.4f} секунд\")\n",
" print(f\"MAE: {mae:.2f}\")\n",
" print(f\"MSE: {mse:.2f}\")\n",
" print(f\"R^2: {r2:.2f}\")\n",
" print(f\"Корреляция: {correlation:.2f}\")\n",
"\n",
"# Оценка качества набора признаков\n",
"evaluate_model(X_train, X_test, y_train, y_test)\n",
"\n",
"# Дополнительно: оценка надежности с помощью кросс-валидации\n",
"from sklearn.model_selection import cross_val_score\n",
"\n",
"cv_scores = cross_val_score(LinearRegression(), X, y, cv=5, scoring='neg_mean_squared_error')\n",
"print(f\"Среднее MSE (кросс-валидация): {-np.mean(cv_scores):.2f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Вывод:**\n",
"\n",
"Время обучения: \n",
"\n",
"Время обучения модели составляет 0.0694 секунды, что является очень коротким. Это указывает на то, что модель обучается быстро и может эффективно обрабатывать данные.\n",
"\n",
"Предсказательная способность: \n",
"\n",
"MAE (Mean Absolute Error): 352.05 — это средняя абсолютная ошибка предсказаний модели. Значение MAE относительно невелико, что означает, что предсказанные значения в среднем отклоняются от реальных на 352.05. Это может быть приемлемым уровнем ошибки.\n",
"\n",
"MSE (Mean Squared Error): 363100.29 — это среднее значение квадратов ошибок. Хотя MSE высокое, оно также может быть связано с большими значениями целевой переменной (цен).\n",
"\n",
"R² (коэффициент детерминации): 0.98 — это очень высокий уровень, указывающий на то, что модель объясняет 98% вариации целевой переменной. Это свидетельствует о высокой предсказательной способности модели.\n",
"\n",
"Корреляция:\n",
"\n",
"Корреляция (0.99) между предсказанными и реальными значениями говорит о том, что предсказания модели имеют очень сильную линейную зависимость с реальными значениями. Это подтверждает, что модель хорошо обучена и делает точные прогнозы.\n",
"\n",
"Надежность (кросс-валидация):\n",
"\n",
"Среднее MSE (кросс-валидация): 885042.98 — это значительно выше, чем обычное MSE, что может указывать на потенциальные проблемы с переобучением. Модель может хорошо работать на обучающих данных, но ее производительность на новых данных (или в реальных условиях) может быть менее стабильной.\n",
" \n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.6"
}
},
"nbformat": 4,
"nbformat_minor": 2
}