diff --git a/lab_3/laba3.ipynb b/lab_3/laba3.ipynb new file mode 100644 index 0000000..08746f3 --- /dev/null +++ b/lab_3/laba3.ipynb @@ -0,0 +1,757 @@ +{ + "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": "iVBORw0KGgoAAAANSUhEUgAAAWkAAAImCAYAAACRnXtqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABLmklEQVR4nO3de1hU1f4G8HcYGBhEUQHB8g4B3hAvkJZX9Hj6qV0U05OipaKUGh5TUdM0r5kSWhgqibeSvGd5yjTtXopiaZaQjop3BMRAnIGBYf/+IHaODMw4orN03s/z8Ch7rf2dNYvxZbtm79kKSZIkEBGRkBxsPQAiIqocQ5qISGAMaSIigTGkiYgExpAmIhIYQ5qISGAMaSIigTGkiYgExpAmIhKYo60HQGI7cuQI1q1bh19++QX5+fmoV68eOnXqhBEjRsDX17dC/927dyM5ORlpaWkoKCiAJElQKBSYP38+Bg4caINnQLc7cOAAkpKScPz4ceTn56O0tBQAMH78eLz66qs2Hh3dTsHLwqkyiYmJiIuLQ+fOndG/f394eXnh3Llz+Pjjj6HRaPDWW2+hb9++cv9169ZhxYoViIqKQkBAAFxdXeHo6Ih69erB29vbhs+Eyn311VeYMmUKIiMjERQUBDc3Nzg6OqJu3bpo0KCBrYdHpkhEJnz99deSv7+/FB8fX6FNr9dLr776qtSqVSvp5MmT8rbQ0FDpu+++u99DpTvw9NNPS8nJybYeBt0BrkmTScuXL0ezZs0wbty4Cm1OTk6YO3culEolPvjgAwDAqVOnUFhYiIYNGyIqKgpt27bF448/junTpyM3NxcA8PbbbyMoKAg3btwwqpeQkID27dtDo9EgICAAO3bsMGqfNm0awsLC5O8LCwvxzjvvoHfv3mjVqhXatWuHESNGIC0trdJ99Ho93n77bTz55JNo06YNnn/+eRw4cEBuT0lJQUBAAFJSUuRt8fHxCAgIqHIsALB161YMGDAAwcHBCAoKwrPPPovdu3dXeOxu3bqhefPmCAgIkL9uf663GjZsmFHfdu3aYeTIkbhw4YLcJywsDNOmTauyxrBhwwAAeXl5+PPPP9G2bVtMnjwZ7du3R/v27REdHY2LFy8a7ZeRkYHo6Gg8+eSTCA4OxrBhw3DkyBG5/eLFiwgICMDnn3+Ol19+GW3atEH37t3x/vvvy8snt4+vtLQUEyZMQKtWrXD69Gm5TkxMDDp37oyWLVuiU6dOiImJwfXr1yt9TvaGIU0V5Obm4vfff0ePHj2gUChM9qlduzaeeOIJ7N+/HwBw6dIlODk54cUXX4RarcbSpUsxdepU/Pjjj3jxxRdRWFiIgQMHoqioCF9++aVRrU8//RR9+vSBi4uLReOLiYnB9u3bMWbMGKxZswbTp0/HqVOnMGnSJEiVrN4tXrwYmzdvxtixYxEfH4/69etj9OjR+OOPP+5gZirauHEjZs2ahV69emHVqlWIjY2FSqXC5MmTkZmZCQD44IMPsH79erz44otYv349Nm/ejOXLl1tUv0WLFti8ebP8OKdOnUJMTIxVY7106RIAYNKkScjJycHbb7+NefPmQaPR4D//+Q+uXbsGANBoNBgwYAAuXryImTNnIjY2FgqFAi+++CIOHTpkVPPNN9+Em5sb4uPj8eyzz2L58uV45513TD7+l19+iZSUFHzwwQdo0KABdDodhg8fjtOnT2P27NlISkrC8OHD8fnnn2Pp0qVWPceHEd84pArK/zE/+uijVfZr3Lgx9u/fj7y8PGi1Wty4cQOBgYFYtmyZ3Mff3x/h4eHYsWMHhgwZgrZt2+LTTz/F888/DwD45ZdfkJGRgUWLFkGpVAIADAZDpY+p1+tx8+ZNzJw5E3369AEAhIaGoqCgAIsWLUJOTg68vLyM9snJyUFycjLmzJkjP27nzp3Rq1cvrFy5EvHx8Xc2Qbe4cOECRo0ahbFjx8rbHn30UQwYMABHjhxB37598dtvvyEwMBAjR46U+9x+5FoZNzc3BAcHAwA6dOiAP//8Exs3brRqrFqtFkDZHH7wwQdwcnICALRv3x69evXCmjVrMGXKFCxfvhwqlQobNmyAm5sbAKB79+7o168fFi9ejG3btsk1W7ZsidjYWABA165dodVqsX79erzyyivyvuU2btyIAQMGoFOnTgCAtLQ0+Pj44O2330bDhg0BAB07dsSxY8cq/DKwZzySpgrKj0bL/xFXpjxUpb/P4ACAZ5991qhPq1at0KhRI3kZITw8HKmpqfIvgk8++QRNmzZF27ZtUbt2bSiVSvkI1BSVSoWkpCT06dMHV69excGDB7Fp0yZ88803AMoC6FYlJSU4cuQIDAYDunfvLm93cHDAk08+afRfeGtMmzYNkydPRn5+Po4ePYpPP/1UDtHysbRu3RoajQZ79uxBXl4eSkpKjJYEqiJJEkpKSqDX63HmzBl8++23aNWqlck+5mqW/4z69u1r9LP19vZG+/bt5Z/RoUOH0KNHD6OQdXR0RN++ffH777/j5s2b8vbnnnvO6DH+/e9/o7i4GL/++qu8zWAwYO/evTh27BheeOEFeXvz5s2RnJyMRx99FBkZGfjuu++QlJSEM2fOVPg52jMeSVMF5UfQ5UFamQsXLqBGjRqoXbs2atSoAQAmz+KoU6cOCgoKAAB9+vTBwoUL8emnn2LUqFHYvXs3xowZAwBQq9V4/PHHsWnTJnTp0gV+fn5IT0/HqVOnjOr98MMPWLhwIc6cOYMaNWogMDAQrq6uAGC03HHp0iW0bNlS/t7d3b3CuPLy8iyak8qcP38es2bNwoEDB+Dk5IRmzZohMDDQaCyjR49GdnY2pk+fbhRwljh8+LDRc3BwcMDs2bON+uzcuRM7d+6EQqGAh4cH2rdvjwkTJlQ4RdLcz+jKlSsAytauPT09K/Tx9PSEJEnyz9JUrbp168o1yn322Wf47LPPMHXqVPmIudzatWuxcuVK/PXXX/D09ESrVq2gVqsrvG9hz3gkTRV4eHggODgYe/bsqfTorKCgAD/99JP8Jlp5sJe/SXiry5cvw8PDA0BZUDz11FPYvXs3fvjhB2i1WqOj7wULFsDLywuDBw9G+/btMXLkSJw/f15uP3/+PMaNG4fmzZvjq6++wpEjR5CcnIwePXpUeFwvLy9s27ZNXsO9fWy5ubmoVavWnUyNkdLSUowZMwbXrl3Dtm3bcPToUXz22WfyL51yzs7OiIyMhJeXF9q0aYO1a9dixYoVFj1Gy5YtsW3bNmzduhVJSUlo164dJk2aJC9dAECPHj2wbds2bNmyBXPnzsWVK1fk9wFuVf4zKl97vtXly5flYHZ3d0dOTk6FPtnZ2QDKAr3c7W/wldcu/3kDQLdu3TBmzBjExcXh559/lrfv2rULixYtwujRo3HgwAH89NNPWLVqFZo0aWLR3NgLhjSZNH78eJw9exZxcXEV2gwGA2bPno3CwkJERkYCAB577DF4e3tj165dRn2///57ZGdno2vXrvK2gQMH4uTJk1i/fj2eeOIJo6OxRx55BJ988gn27NmDL7/8EqmpqejZs6fc/vvvv6OoqAhjxoxBo0aN5P/C//DDDwCMj6RVKhVat26Nbt26AQC+/fZbua2kpAQ///wz2rZta+0U4fr16zh79iwGDhyI1q1bw9HRUX7OAORfcKWlpZg0aRKuXbuG+Ph4PPHEE/D397foMWrUqIHWrVsjKCgInTt3RmRkJHJycqDRaOQ+tWvXlvv07NkTUVFRyM7OxpkzZ4xq1axZE8HBwdi9e7fRur9Go8GxY8fkn1FISAi++eYboyNmg8GAzz//HK1bt4ZKpZK379u3z+gx9uzZA7VajTZt2sjb6tati0mTJiEsLAwxMTHyUfKRI0dQq1YtREZGykfgN2/exJEjRyxeDrIHXO4gk7p06YJp06Zh8eLFSEtLQ3h4OOrVq4eLFy/i448/RlpaGhYsWCD/116pVGLatGmYOHEiXnvtNTz77LO4cuUK4uLi0LZtW/zf//2fXLt9+/Zo2rQpDh06ZPJdfIVCUenRVMuWLeHo6IglS5Zg5MiR0Ov12LFjhxzAtx5hlvPz80OPHj2wZMkSSJKERx55BB9//DGuXr1a4fE1Gg2cnZ0BQF4bP3r0qNyem5sLvV4PjUYDPz8/PProo9i4cSN8fHxQq1Yt/PDDD9iwYQMAQKfTASg7Re/YsWOYNWvWHV/UU1BQgKNHj0KSJOTl5WHDhg1wdnZGo0aNjMZ09OhRlJSU4MqVK1i7di08PT1NzmFMTAxefPFFREZGYtiwYbhx4waWLVuGhg0bYujQoQDKfkF///33GD58OMaMGQMnJyd89NFHuHDhAlavXm1Ub/fu3fDw8EC3bt1w6NAhbNy4ERMnTpSXn241Y8YM/N///R+WLVuGN954A0FBQfj444+xaNEi9OjRA1lZWUhKSkJOTk6FpSl7xpCmSo0YMQJt27bF+vXr8fbbbyM3NxdeXl548sknsWDBAvj5+Rn1Lz/bIjExEdHR0VCr1ejZsydef/11+U3Gct27d0dubi569ep1R2Nq3Lgx3nnnHSxfvhyvvPIK3N3dERwcjA8//BDDhg1DampqhXObgbJT8N5++20sW7YMWq0WgYGBWL16tdERHwDMnTu3wr6DBw+usG3OnDn48MMPkZCQgAULFmDatGlQqVTw8/PDihUrsHDhQqSmpuLpp59GXFwcWrRoYfSmmaVOnDghP75arUazZs3w3nvvoXbt2nKf7777Dt999x2AsqWIVq1aYeHChSaDsn379vjggw/w7rvvYtKkSXB0dMTjjz+OmTNnym8UPvbYY0hOTkZcXBymT58OhUKBoKAgbNiwAR06dDCqN2HCBBw6dAibN29G/fr1MWvWrEqfp7e3NyZMmIC3334b4eHh6N+/Py5evIjt27cjOTkZ3t7e6NatG4YMGYI33ngDp0+fNvnRA/aGl4XTfSdJEvr27YvOnTvj9ddft/Vw7lh8fDwOHTqEDz/80NZDsZmLFy+iZ8+eeOuttzBgwABbD+ehxiNpum8KCgqwbt06HD9+HBcuXJCvhCOiyjGk6b5xcXHBpk2bUFpaioULF1Y4HetB4ePjw/+G033D5Q4iIoHxFDwiIoExpImIBMaQJiISGN84tMKvv/4KSZLMfgAREZEpxcXFUCgUFl3xyiNpK0iSVOnnFpe36/X6KvvYC87FPzgXxux5PsxlyK14JG2F8iPo1q1bm2zXarVIS0uDn5+fyau+7Ann4h+cC2P2PB/Hjx+3uC+PpImIBMaQJiISGEOaiEhgDGkiIoExpImIBMaQJiISGEOaiEhgDGkiIoExpImIBMaQJiISGEOaiEhgDGkiIoExpImIBGbzkC4pKcG7776LHj16oG3bthg6dCiOHj0qt6elpSEiIgLBwcEICwvDhg0bjPYvLS3Fe++9hy5duiA4OBijR4/GhQsXjPqYq0FEJCqbh/SKFSuwdetWzJs3Dzt37kTTpk0RGRmJrKwsXL9+HSNGjECjRo2wfft2jBs3DrGxsdi+fbu8f0JCApKTkzFv3jz5TtSRkZHQ6/UAYFENIiJR2fzzpPft24d+/fqhc+fOAIBp06Zh69atOHr0KM6ePQsnJyfMnTsXjo6O8PX1xblz55CYmIjw8HDo9XqsWbMGkydPRvfu3QEAS5cuRZcuXbB3717069cPW7ZsqbIGEZHIbH4k7eHhgW+++QYXL16EwWDA5s2boVKpEBgYiNTUVISGhsLR8Z/fJR07dkRGRgZycnKQnp6OmzdvolOnTnJ7rVq10KJFCxw+fBgAzNYgIhKZzY+kZ8yYgQkTJqBnz55QKpVwcHBAfHw8GjVqhMzMTPj7+xv1r1evHgDgypUryMzMBADUr1+/Qp/yNnM1PD09rRq3JEnQarUm23Q6ndGf9oxz8Q/OhTF7ng9JkqBQKCzqa/OQ1mg0qFmzJt5//314e3tj69atmDx5Mj766CMUFhZCpVIZ9Xd2dgYAFBUVyT9cU33y8vIAwGwNaxUXFyMtLa3KPhkZGVbXf9hwLv7BuTBmr/Nxey5VxqYhfeXKFUyaNAnr1q1Dhw4dAJTdN1Cj0SA+Ph4uLi7yG4DlyoPV1dUVLi4uAAC9Xi//vbyPWq0GALM1rOXk5AQ/Pz+TbTqdDhkZGWjSpIk8DgBmf3M+jDfkrGwu7BHnwpg9z4dGo7G4r01D+tixYyguLq5wQ9c2bdrg+++/xyOPPIKsrCyjtvLvvb29UVJSIm9r1KiRUZ+AgAAAgI+PT5U1rKVQKMyGvFqtlvvk5QEFBVXXdHMD3N2tHpLQbp0Le8e5MGaP82HpUgdg45D28fEBAPz5558ICgqSt588eRJNmjRBmzZtsGnTJhgMBiiVSgDAwYMH0bRpU3h4eKBmzZpwc3NDSkqKHNL5+fk4ceIEIiIiAAAhISFV1rhfCgqA5cuByt6r9PQExo9/eEOaiKxj07M7goKC0L59e0ydOhUHDx5ERkYGli1bhgMHDmDMmDEIDw9HQUEBZsyYAY1Ggx07dmDdunWIiooCULamExERgdjYWOzfvx/p6emYOHEifHx80Lt3bwAwW+N+yskBMjNNf/FEEyIyxaZH0g4ODlixYgWWLVuG6dOnIy8vD/7+/li3bh3atGkDAFi9ejUWLFiA/v37w8vLCzExMejfv79cIzo6GiUlJZg5cyYKCwsREhKCpKQkODk5ASg7xc9cDSIiUdn87A53d3fMnj0bs2fPNtkeFBSEzZs3V7q/UqnElClTMGXKlEr7mKtBRCQqm1/MQkRElWNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwm4Z0SkoKAgICTH717NkTAHDx4kVERUWhXbt26Ny5M5YtWwaDwWBUZ+PGjejZsyeCgoIwZMgQnDhxwqjdkhpERCJytOWDt23bFj/++KPRtqNHj+LVV1/F2LFjUVxcjFGjRqFJkybYtGkTzp8/jxkzZsDBwQHR0dEAgE8++QSLFy/GvHnz0KJFCyQmJmLEiBHYvXs36tata1ENIiJR2TSkVSoVvLy85O+1Wi3eeust9O/fH+Hh4fjf//6Hy5cvY8uWLXB3d4e/vz+uXbuGxYsX4+WXX4ZKpcLKlSsRERGBZ555BgCwcOFC9OrVC1u3bkVUVBT27NljtgYRkaiEWpNeuXIldDodpk6dCgBITU1Fy5Yt4e7uLvfp2LEjCgoKkJaWhmvXriEjIwOdOnWS2x0dHdGhQwccPnzYohpERCKz6ZH0rXJzc7Fu3TpMmjQJtWvXBgBkZmbCx8fHqF+9evUAAFeuXIGjY9nw69evX6FPenq6RTXatGlj1XglSYJWqzXZptPpjP5UKBQwGFQwGIDKlsLL23Q6PSRJsmpMIrp9LuwZ58KYPc+HJElQKBQW9RUmpJOTk1GzZk0MHjxY3lZYWIhatWoZ9XN2dgYAFBUVyT/c25csnJ2dUVRUZFENaxUXF5s9Es/IyJDH5+LSDFqtAQUFpSb7arUOKCpSQqM5A71eb/W4RFU+F8S5uJ29zoelS63ChPTOnTvx3HPPwcXFRd7m4uJSIbDKg9XV1VXua6qPWq22qIa1nJyc4OfnZ7JNp9MhIyMDTZo0gVqthkKhQHa2Cq6ugJub6XquroCzM9Cggd9DdyR961zYM86FMXueD41GY3FfIUI6PT0dFy5cwNNPP2203cfHBydPnjTalpWVBQDw9vaWlzmysrLg6+tr1Mfb29uiGtZSKBRmQ16tVst9lMp/vkwpb3tYX6y3zoW941wYs8f5sHSpAxDkjcPU1FR4eHggMDDQaHtISAhOnDiBgoICedvBgwdRo0YNBAYGwsPDA02bNkVKSorcXlJSgtTUVISEhFhUg4hIZEKE9IkTJxAQEFBhe69eveDl5YX//ve/SE9Px759+xAXF4eRI0fK6zkjR47E2rVr8cknn0Cj0eD1119HYWEhBg4caHENIiJRCbHckZ2dLZ/RcStnZ2esXr0ac+bMwaBBg+Du7o4hQ4Zg7Nixcp9Bgwbhxo0bWLZsGf766y+0atUKa9euRd26dS2uQUQkKiFC+oMPPqi0rXHjxlizZk2V+48aNQqjRo26qxpERCISYrmDiIhMY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDAhQnrnzp3o06cPWrdujb59+2L37t1y28WLFxEVFYV27dqhc+fOWLZsGQwGg9H+GzduRM+ePREUFIQhQ4bgxIkTRu2W1CAiEpHNQ/rTTz/FjBkzMHToUHz++efo168fXnvtNfz6668oLi7GqFGjAACbNm3Cm2++iY8//hjvv/++vP8nn3yCxYsXY8KECdixYwcaNGiAESNGIDc3FwAsqkFEJCpHWz64JEl49913MXz4cAwdOhQA8MorryA1NRWHDh3CpUuXcPnyZWzZsgXu7u7w9/fHtWvXsHjxYrz88stQqVRYuXIlIiIi8MwzzwAAFi5ciF69emHr1q2IiorCnj17zNYgIhKVTY+kz549i0uXLuHpp5822p6UlISoqCikpqaiZcuWcHd3l9s6duyIgoICpKWl4dq1a8jIyECnTp3kdkdHR3To0AGHDx8GALM1iIhEZvOQBgCtVotRo0ahU6dOeP755/H1118DADIzM+Hj42O0T7169QAAV65cQWZmJgCgfv36FfqUt5mrQUQkMpsudxQUFAAApk6divHjx2Py5MnYs2cPxo4di7Vr16KwsBC1atUy2sfZ2RkAUFRUBJ1OBwAVliycnZ1RVFQEAGZrWEuSJGi1WpNt5eMq/1OhUMBgUMFgACp7v7K8TafTQ5Ikq8clmtvnwp5xLozZ83xIkgSFQmFRX5uGtJOTEwBg1KhR6N+/PwCgefPmOHHiBNauXQsXFxfo9XqjfcqD1dXVFS4uLgBgso9arQYAszWsVVxcbHa5JCMjA0DZLxEXl2bQag0oKCg12VerdUBRkRIazZkK430YlM8FcS5uZ6/zYen7YTYNaW9vbwCAv7+/0XY/Pz98++23CA0NxcmTJ43asrKy5H3LlzmysrLg6+tr1Ke8to+PT5U1rOXk5AQ/Pz+TbTqdDhkZGWjSpAnUajUUCgWys1VwdQXc3EzXc3UFnJ2BBg38Hroj6Vvnwp5xLozZ83xoNBqL+9o0pFu2bIkaNWrg2LFj6NChg7z95MmTaNSoEUJCQrBz504UFBTA7e90O3jwIGrUqIHAwECoVCo0bdoUKSkp8puHJSUlSE1NxZAhQwDAbA1rKRQKs0fiarVa7qNU/vNlSnnbw/pivXUu7B3nwpg9zoelSx2Ajd84dHFxQWRkJN5//33873//w/nz57FixQr89NNPGDFiBHr16gUvLy/897//RXp6Ovbt24e4uDiMHDlS/q/CyJEjsXbtWnzyySfQaDR4/fXXUVhYiIEDBwKARTWIiERl0yNpABg7dizUajWWLl2Kq1evwtfXF/Hx8Xj88ccBAKtXr8acOXMwaNAguLu7Y8iQIRg7dqy8/6BBg3Djxg0sW7YMf/31F1q1aoW1a9eibt26AMreJDRXg4hIVDYPaQAYMWIERowYYbKtcePGWLNmTZX7jxo1Sr6q0NoaREQisvll4UREVDmGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQnM5iF99epVBAQEVPjasWMHACAtLQ0REREIDg5GWFgYNmzYYLR/aWkp3nvvPXTp0gXBwcEYPXo0Lly4YNTHXA0iIlE52noA6enpcHZ2xr59+6BQKOTtNWvWxPXr1zFixAiEhYVhzpw5OHr0KObMmYMaNWogPDwcAJCQkIDk5GQsWrQIPj4+WLJkCSIjI7Fr1y6oVCqLahARicrmIX3y5Ek0adIE9erVq9C2fv16ODk5Ye7cuXB0dISvry/OnTuHxMREhIeHQ6/XY82aNZg8eTK6d+8OAFi6dCm6dOmCvXv3ol+/ftiyZUuVNYiIRGbz5Y4///wTvr6+JttSU1MRGhoKR8d/fpd07NgRGRkZyMnJQXp6Om7evIlOnTrJ7bVq1UKLFi1w+PBhi2oQEYlMiCPpOnXqYOjQoTh79iwaN26MV155BV27dkVmZib8/f2N+pcfcV+5cgWZmZkAgPr161foU95mroanp6dV45YkCVqt1mSbTqcz+lOhUMBgUMFgAAwG0/XK23Q6PSRJsmpMIrp9LuwZ58KYPc+HJElGy7tVsWlIl5SU4MyZM/Dz88O0adPg5uaGzz//HGPGjMHatWtRWFgIlUpltI+zszMAoKioSP7hmuqTl5cHAGZrWKu4uBhpaWlV9snIyJDH5+LSDFqtAQUFpSb7arUOKCpSQqM5A71eb/W4RFU+F8S5uJ29zsftuVQZm4a0o6MjUlJSoFQq4eLiAgBo1aoVTp06haSkJLi4uFQIrPJgdXV1lffR6/Xy38v7qNVqADBbw1pOTk7w8/Mz2abT6ZCRkYEmTZpArVZDoVAgO1sFV1fAzc10PVdXwNkZaNDA76E7kr51LuwZ58KYPc+HRqOxuK/Nlztq1KhRYdtjjz2GH3/8ET4+PsjKyjJqK//e29sbJSUl8rZGjRoZ9QkICAAAszWspVAozIa8Wq2W+yiV/3yZUt72sL5Yb50Le8e5MGaP82HpUgdg4zcOT506hXbt2iElJcVo+++//w4/Pz+EhITgyJEjMNyykHvw4EE0bdoUHh4eCAwMhJubm9H++fn5OHHiBEJCQgDAbA0iIpHdVUjn5+fj+++/x+eff46ff/4ZBQUFd7S/r68vmjVrhrlz5yI1NRWnT5/GW2+9haNHj+KVV15BeHg4CgoKMGPGDGg0GuzYsQPr1q1DVFQUgLI1nYiICMTGxmL//v1IT0/HxIkT4ePjg969ewOA2RpERCKzerkjMTERCQkJKCoqktdQVSoVoqKiMG7cOItqODg4YOXKlXjnnXfw3//+F/n5+WjRogXWrl0rn5GxevVqLFiwAP3794eXlxdiYmLQv39/uUZ0dDRKSkowc+ZMFBYWIiQkBElJSXBycgIAeHh4mK1BRCQqq0J6+/btiIuLw8CBA/HMM8/A09MT2dnZ+PTTT7F8+XI88sgjFoegp6cn3nrrrUrbg4KCsHnz5krblUolpkyZgilTplhdg4hIVFaF9Lp16/DCCy9g9uzZ8rZmzZrh8ccfh4uLCzZs2MAjVSKiamDVmvS5c+fQq1cvk209e/bEmTNn7mpQRERUxqqQ9vb2xuXLl022Xbx4EW6VnQxMRER3xKqQDgsLw7vvvovffvvNaPuxY8cQHx+PsLCwahkcEZG9s2pN+tVXX8XPP/+MwYMH49FHH4WnpydycnJw6dIl+Pr6YtKkSdU9TiIiu2RVSLu5uWHbtm3Yvn07Dh8+jLy8PLRu3RojR47EgAEDjC7RJiIi61l9nrSzszOGDBmCIUOGyNuuX7/OgCYiqkZWrUnn5eUhJiYGffv2xbRp03DmzBk8++yzeOKJJ9C5c2ccO3asusdJRGSXrArpN954A/v374evry9+/PFHhIeHw2AwYObMmahXrx6WLFlS3eMkIrJLVi13HDx4EFOnTsWgQYPw22+/YdCgQZgyZQq6desGb29vTJs2rbrHSURkl6w6kr5x4waaNWsGAGjevDkAyJ8o5+HhgZs3b1bT8IiI7JtVIS1JknxXAQcHB5N/EhHR3bP67I6EhATUqVNH/j4+Ph61a9fG9evXq2VgRERkZUg/8sgjOHnypNH3f/75p/z97TeGJSIi61gV0l9//XV1j4OIiEywagF5+PDhOH36dHWPhYiIbmNVSB86dIhncBAR3Qc8FYOISGBWn90xePDgStsUCgVOnDhhbWkiIvqb1SEdHh4OHx+f6hwLERHdxuqQHjRoEIKCgqpzLEREdBuuSRMRCcyqkN6wYQN8fX2Rm5srb8vPz4dGo6m2gRERkZUh3bx5c0yYMAFDhw6Vtx09ehT9+vVDdHQ0CgsLq22ARET2zKqQjo2NRVpaGl599VV5W8eOHREfH49ffvkF8fHx1TZAIiJ7ZlVIf/3115g6dSr69Okjb1OpVPjXv/6F1157DV988UW1DZCIyJ5ZFdIFBQVwd3c32ebl5WW0Vk1ERNazKqQDAwOxfft2k207d+5EQEDAXQ2KiIjKWHWe9Msvv4yXX34ZAwYMwL/+9S94eHggNzcX33zzDY4fP44VK1ZU9ziJiOySVSHdrVs3JCQkID4+Hu+99x4kSYJCoUDz5s2RkJCAbt26Vfc4iYjsktVXHPbo0QM9evRAUVER/vrrL9SsWROurq7VOTYiIrt3V1ccnj59Gps3b8ZHH32EGzduIDU1FQUFBdU1NiIiu2fVkXRpaSlmzZqF7du3y0sdTz31FBISEnD+/Hl89NFH/PAlIqJqYNWRdEJCAnbt2oX58+fjp59+giRJAIApU6agtLQUS5curdZBEhHZK6tCevv27YiOjkZ4eDhq164tb2/evDmio6Px008/Vdf4iIjsmlUhnZOTg+bNm5ts8/b2Rn5+/l0NioiIylgV0o0bN8Z3331nsu3QoUNo3LjxXQ2KiIjKWPXG4YsvvohZs2ahuLgYPXr0gEKhwLlz55CSkoI1a9Zg2rRp1T1OIiK7ZFVIP//888jNzcWKFSvw8ccfQ5IkvPbaa3ByckJkZCReeOGF6h4nEZFdsvpilqioKAwdOhS//PIL8vLyUKtWLbRp08bojUQiIro7Voc0ALi5uaFr167VNRYiIrqNVSEdFhYGhUJRabtCocC+ffusHhQREZWxKqRDQ0ONQvrUqVO4cOECwsLCqm1g9siBtwUmottYFdKLFi0y+j41NRWRkZGYO3cunJycrB7M2bNnMWDAALzxxhsYMGAAACAtLQ0LFizA77//jrp16+Kll17C8OHD5X1KS0uxfPlybN26FTdu3EBISAhmzZqFhg0byn3M1RCBm1tZSF+6VHWfSu61QEQPqbtaky4XGBiIwsJCXL582epzpIuLizF58mRotVp52/Xr1zFixAiEhYVhzpw5OHr0KObMmYMaNWogPDwcQNkl6snJyVi0aBF8fHywZMkSREZGYteuXVCpVBbVEIFaDWi1QGIikJNTsd3TExg/niFNZG+qJaRPnz4NhUJR5Tq1OfHx8XBzczPatmXLFjg5OWHu3LlwdHSEr68vzp07h8TERISHh0Ov12PNmjWYPHkyunfvDgBYunQpunTpgr1796Jfv35ma4gmJwfIzLT1KIhIFFaF9M6dOwEAJSUlyMzMxKZNm9C8eXM0atTIqkEcPnwYmzdvxs6dO+WwBcqWUUJDQ+Ho+M8wO3bsiFWrViEnJweXL1/GzZs30alTJ7m9Vq1aaNGiBQ4fPox+/fqZreHp6WnVmImI7gerQvrWKwqVSiUef/xxLFiwwKoB5OfnIyYmBjNnzkT9+vWN2jIzM+Hv72+0rV69egCAK1euIPPvQ87b96tXr57cZq6GtSEtSZLR0sytdDqd0Z8KhQIGgwoGA2AwmK5Xtt0BBkOpyT7l++p0evlTBx8Et8+FPeNcGLPn+Sj/iGdLWBXS+/fvB1AW0LVr14aLi4s1ZQAAb775Jtq2bYunn366QlthYSFUKpXRNmdnZwBAUVGR/MM11ScvL8+iGtYqLi5GWlpalX0yMjLk8bm4NINWa0BBQanJvoWFSpSWukKn06KgoGJKa7UOKCpSQqM5A71eb/W4baV8LohzcTt7nY/bc6kyVoX05cuX5b9fuHDBZJ+QkBCzdXbu3InU1FTs2rXLZLuLi0uFQCoPVldXV/mXg16vN/pFUVRUBLVabVENazk5OcHPz89km06nQ0ZGBpo0aQK1Wg2FQoHsbBVcXcvO0DDFxQVwcHCAWu1qso+rK+DsDDRo4PfAHUnfOhf2jHNhzJ7nQ6PRWNzXqpAeNmyYfKheHhi3fq9QKMweZQJln0t97do1o3VoAJg9eza++OIL+Pj4ICsry6it/Htvb2+UlJTI225dD8/KykJAQAAAmK1hLYVCYTbk1Wq13Eep/OfLlPLtSqXSZJ/yfR/UF/Otc2HvOBfG7HE+7uQkC6tCuk+fPvjiiy/QqlUrjBs3DjVq1LCmDGJjY1FYWGi0rXfv3oiOjsYzzzyDTz/9FJs2bYLBYIDy7+Q6ePAgmjZtCg8PD9SsWRNubm5ISUmRQzo/Px8nTpxAREQEgLIj+qpqEBGJzKpr3OLi4vDRRx/BYDDgjTfewOXLlxEaGmr0ZQlvb280btzY6AsAPDw84O3tjfDwcBQUFGDGjBnQaDTYsWMH1q1bh6ioKABlazoRERGIjY3F/v37kZ6ejokTJ8LHxwe9e/cGALM1iIhEZvWFyB06dMCOHTswduxYLFq0CIMHD8Yff/xRnWODh4cHVq9ejbNnz6J///5Yvnw5YmJi0L9/f7lPdHQ0Bg4ciJkzZ+KFF16AUqlEUlKSfOWjJTWIiER1VxezKBQKDBkyBH379sW7776L//znP3juuecwceJE1K1b16qaf/75p9H3QUFB2Lx5c6X9lUolpkyZgilTplTax1wNIiJRWRXS06dPN7nd398fW7duxd69e5GSknJXAyMiIitDuqoAfuSRR6weDBERGbMqpL/++uvqHgcREZnATzAmIhKYVUfSPXv2rLKdd2YhIqoeVoX0pUuX0K1bN6vP4CAiIstYfQreuHHjEBQUVJ1jISKi23BNmohIYAxpIiKBWb3ckZCQgDp16sjfKxQKKJVK1KxZE4MGDUKTJk2qY3xERHbNqpB+5JFHcPLkyQrbJUlCbm4ufvjhh0o/I5qIiCxX7RezfP/993j55ZetHhAREf3jrtekdTodsrOzUVxcDAAICAjAhAkT7npgRER0F2vSqampWLx4MX7//Xf57ixBQUGYOHEiP6uZiKiaWBXSv/zyC1566SU0bNgQY8eOhaenJ7KysvD5558jMjISH374Idq2bVvdYyUisjtWhfSyZcvQoUMHJCUlybekAoDx48dj1KhRiI+Px5o1a6ptkERE9sqqNenjx49j+PDhRgENlN3tOiIiAr/99lu1DI6IyN5ZFdI1atSQ79R9u5KSEnmNmoiI7o5VId2uXTskJiZCp9MZbddqtUhMTESHDh2qZXBERPbOqjXpSZMmYcCAAejZsye6d+8OLy8vZGdn49tvv4VOp8OCBQuqe5xERHbJ4iPp7du34/r16wCAxo0bY8uWLQgNDcV3332HpKQkfPfddwgNDcXWrVsrXQohIqI7Y/GR9OzZs9GwYUOEhoYCAHx9fbFs2TKjPtevX0dcXBy2b9+OEydOVOtAiYjskcVH0s2aNcPKlSuRk5NToU2SJGzcuBFPPfUUtm7divbt21frIImI7JXFIT1r1iwcP34cYWFhmDFjBs6fPw8AuHz5MgYPHoz58+fDxcUF77zzDj788MN7NmAiInticUh36NABe/bswfDhw/Hll1/imWeeQUpKCoYOHYo//vgDI0aMwO7du9G3b997OV4iIrtyR6fg1a1bF5MnT8a+ffvw5JNPYvTo0SguLsbHH3+MmJgYuLq63qtxEhHZJavOk65Tpw7eeOMN6PV6TJ48mfc6JCK6Ryw+u2P48OFG35dfVbhhwwbs2LHDqE2hUGD9+vXVMDwiIvtmcUibutQ7JCTEZBsvCyciqh4WhzTP2CAiuv94t3AiIoExpImIBMaQJiISGEOaiEhgDGkiIoExpImIBMaQJiISGEOaiEhgDOkHiAN/WkR2x6p7HNL95+ZWFtKXLlXdx939/o2JiO49hvQDQq0GtFogMREwcXMceHoC48czpIkeNgzpB0xODpCZaetRENH9wlVOIiKB2Tykr127hilTpqBjx45o27YtxowZg9OnT8vtaWlpiIiIQHBwMMLCwrBhwwaj/UtLS/Hee++hS5cuCA4OxujRo3HhwgWjPuZqEBGJyuYhPW7cOJw7dw6JiYnYtm0bXFxc8NJLL0Gn0+H69esYMWIEGjVqhO3bt2PcuHGIjY3F9u3b5f0TEhKQnJyMefPmYdOmTSgtLUVkZCT0ej0AWFSDiEhUNl2TzsvLw6OPPoqoqCj4+/sDAMaOHYtnn30Wp06dwoEDB+Dk5IS5c+fC0dERvr6+cqCHh4dDr9djzZo1mDx5Mrp37w4AWLp0Kbp06YK9e/eiX79+2LJlS5U1iIhEZtMjaXd3d7zzzjtyQOfm5mLdunXw8fGBn58fUlNTERoaCkfHf36XdOzYERkZGcjJyUF6ejpu3ryJTp06ye21atVCixYtcPjwYQAwW4OISGTCnN3xxhtvYMuWLVCpVFixYgVcXV2RmZkpB3i5evXqAQCuXLmCzL9Pc6hfv36FPuVt5mp4enpaNV5JkqDVak226XQ6oz8VCgUMBhUMBsBgMF2vbLsDDIZSk30saTcYAJ1OL9Tty26fC3vGuTBmz/MhSRIUCoVFfYUJ6RdffBGDBw/Gxo0bMW7cOCQnJ6OwsBAqlcqon7OzMwCgqKhI/uGa6pOXlwcAZmtYq7i4GGlpaVX2ycjIkMfn4tIMWq0BBQWlJvsWFipRWuoKnU6LgoKKKWyuXat1QFGREhrNGXk9XiTlc0Gci9vZ63zcnkuVESak/fz8AAALFizAsWPH8NFHH8HFxaVC4JQHq6urK1xcXAAAer1e/nt5H7VaDQBma1jLyclJHvPtdDodMjIy0KRJE6jVaigUCmRnq+DqWnZVoCkuLoCDgwPUaleTfcy1u7oCzs5AgwZ+wh1J3zoX9oxzYcye50Oj0Vjc16YhnZubiwMHDuDf//63vGbs4OAAPz8/ZGVlwcfHB1lZWUb7lH/v7e2NkpISeVujRo2M+gQEBACA2RrWUigUZkNerVbLfZTKf75MKd+uVCpN9rGkXamEsC/2W+fC3nEujNnjfFi61AHY+I3DnJwcvPbaazhw4IC8rbi4GCdOnICvry9CQkJw5MgRGG5ZhD148CCaNm0KDw8PBAYGws3NDSkpKXJ7fn4+Tpw4gZCQEAAwW4OISGQ2DWl/f3907doV8+fPx+HDh3Hy5ElMmzYN+fn5eOmllxAeHo6CggLMmDEDGo0GO3bswLp16xAVFQWgbE0nIiICsbGx2L9/P9LT0zFx4kT4+Pigd+/eAGC2BhGRyGy+Jh0XF4d33nkHEydOxI0bN9ChQwds3LgRjzzyCABg9erVWLBgAfr37w8vLy/ExMSgf//+8v7R0dEoKSnBzJkzUVhYiJCQECQlJcHJyQkA4OHhYbYGEZGobB7SNWvWxJtvvok333zTZHtQUBA2b95c6f5KpRJTpkzBlClTKu1jrgYRkahsflk4ERFVjiFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhvRDxIE/TaKHjqOtB0DVw82tLKQvXaq6j7v7/RsTEd09hvRDQq0GtFogMRHIyanY7ukJjB/PkCZ60DCkHzI5OUBmpq1HQUTVhauYREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCs3lI//XXX5g1axa6du2Kdu3a4YUXXkBqaqrcfuDAAQwYMABt2rTBU089hc8//9xo/6KiIsyZMwedOnVC27ZtMWnSJOTm5hr1MVeDiEhUNg/p1157Db/++ivi4uKwfft2NG/eHKNGjcKZM2dw+vRpREVFoUuXLtixYweef/55xMTE4MCBA/L+b775Jn788UfEx8dj/fr1OHPmDKKjo+V2S2oQEYnKpp/dce7cOfz0009ITk5G+/btAQBvvPEGfvjhB+zatQvXrl1DQEAAJk6cCADw9fXFiRMnsHr1anTq1AlXr17Fzp07sXLlSnTo0AEAEBcXh6eeegq//vor2rZti/Xr11dZg4hIZDY9kq5Tpw4SExPRunVreZtCoYBCoUB+fj5SU1MrBGnHjh1x5MgRSJKEI0eOyNvKNW3aFN7e3jh8+DAAmK1BRCQym4Z0rVq10K1bN6hUKnnbnj17cO7cOXTp0gWZmZnw8fEx2qdevXrQ6XS4fv06rl69ijp16sDZ2blCn8y/PwrOXA0iIpEJ9VGlv/zyC6ZPn47evXuje/fuKCwsNApwAPL3er0eOp2uQjsAODs7o6ioCADM1rCWJEnQarUm23Q6ndGfCoUCBoMKBgNgMJiuV7bdAQZDqck+1dFuMAA6nf6+/g/i9rmwZ5wLY/Y8H5IkQaFQWNRXmJDet28fJk+ejHbt2iE2NhZAWdjeHqTl36vVari4uJgM2qKiIqjVaotqWKu4uBhpaWlV9snIyABQ9kvBxaUZtFoDCgpKTfYtLFSitNQVOp0WBQUVU/Zu27VaBxQVKaHRnLmrX07WKp8L4lzczl7nw9QBpilChPRHH32EBQsW4KmnnsLbb78tD75+/frIysoy6puVlQVXV1fUrFkTPj4++Ouvv6DX642ecFZWFry9vS2qYS0nJyf4+fmZbNPpdMjIyECTJk2gVquhUCiQna2Cq2vZLaxMcXEBHBwcoFa7muxzt+2uroCzM9Cggd99P5K+dS7sGefCmD3Ph0ajsbivzUM6OTkZ8+bNw7BhwzBjxgyj/wJ06NABhw4dMup/8OBBtGvXDg4ODmjfvj1KS0tx5MgR+c3Bs2fP4urVqwgJCbGohrUUCgVcXV2r7KNWq+U+SuU/X6aUb1cqlSb7VEe7Unl3/3u4G7fOhb3jXBizx/mwdKkDsPEbh2fPnsXChQvxr3/9C1FRUcjJyUF2djays7Nx48YNDBs2DL/99htiY2Nx+vRprFmzBl9++SUiIyMBAN7e3ujbty9mzpyJlJQU/Pbbb3jttdcQGhqK4OBgADBbg4hIZDY9kt6zZw+Ki4vx1Vdf4auvvjJq69+/PxYtWoSEhAQsWbIE69evR4MGDbBkyRKjU+rmzZuHhQsXYvz48QCArl27YubMmXL7Y489ZrYGEZGobBrSL7/8Ml5++eUq+3Tt2hVdu3attN3V1RXz58/H/Pnzra5BRCQqm18WTkRElWNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJzOZXHNKDJS8PKCiovN3NDXB3v3/jIXrYMaTpjhQUAMuXAzk5Fds8PYHx4xnSRNWJIW1H7uKjSozk5AB/f1w3Ed1jDGk74eZWFtKXLpnvxyNhInEwpO2EWg1otUBioumlCoDLFUQiYkjbGS5VED1YeAoeEZHAGNJERAJjSBMRCYwhTUQkMIY0EZHAGNJUrW6/YEahUEClUt3RjTeJ6B88BY+qjakLZgwGFVxcmiE7WyXfxZwXzBBZjiFN1cbUBTMGA6DVGuDqCiiVvGCG6E4xpKna3XrBjMEAFBSUws0N8pE0EVmOa9JkpLo+hImIqgePpElm7kOYlMqyI2Miun8Y0iQz9yFM/v7AwIH3f1xE9owhTRVU9iFMXl73fyxE9o4rkEREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFNRCQwhjQRkcAY0kREAmNIExEJjCFN9x3vSE5kOaH+uaxatQrDhg0z2paWloaIiAgEBwcjLCwMGzZsMGovLS3Fe++9hy5duiA4OBijR4/GhQsX7qgG3T+33pG8sq+8PFuPkkgcwtyIduPGjVi2bBk6dOggb7t+/TpGjBiBsLAwzJkzB0ePHsWcOXNQo0YNhIeHAwASEhKQnJyMRYsWwcfHB0uWLEFkZCR27doFlUplUQ26f8zdkdzTExg/HnB3v/9jIxKRzUP66tWrmD17NlJSUtCkSROjti1btsDJyQlz586Fo6MjfH19ce7cOSQmJiI8PBx6vR5r1qzB5MmT0b17dwDA0qVL0aVLF+zduxf9+vUzW4Nso7I7khORMZsvd/zxxx9wcnLCZ599hjZt2hi1paamIjQ0FI6O//wu6dixIzIyMpCTk4P09HTcvHkTnTp1kttr1aqFFi1a4PDhwxbVICISmc2PpMPCwhAWFmayLTMzE/7+/kbb6tWrBwC4cuUKMv8+FKtfv36FPuVt5mp4enpaNW5JkqDVak226XQ6oz8VCgUMBhUMBsBgMF2vbLsDDIZSk33udfu9egzD33/550/zNQwGQKfTQ5Ik0wN9QN3+urB39jwfkiRBoVBY1NfmIV2VwsJCqFQqo23Ozs4AgKKiIvmHa6pP3t/vPpmrYa3i4mKkpaVV2ScjI0Men4tLM2i1BhQUlJrsW1ioRGmpK3Q6LQoKKqbXvW6/14+h02ktqqHVOqCoSAmN5gz0er3JcT7oyl8XVMZe5+P2XKqM0CHt4uJS4R9qebC6urrCxcUFAKDX6+W/l/dRq9UW1bCWk5MT/Pz8TLbpdDpkZGSgSZMmUKvVUCgUyM5WwdW17OwGU1xcAAcHB6jVrib73Ov2e/UYBoMBOp0WarUrlEql2RquroCzM9Cggd9DeSR96+vC3tnzfGg0Gov7Ch3SPj4+yMrKMtpW/r23tzdKSkrkbY0aNTLqExAQYFENaykUCrMhr1ar5T5K5T9fppRvVyqVJvvc6/Z7/Rhl25QW1VAq8VD/o731dUH2OR+WLnUAArxxWJWQkBAcOXJEXs8EgIMHD6Jp06bw8PBAYGAg3NzckJKSIrfn5+fjxIkTCAkJsagGiYcXuxD9Q+h/DuHh4SgoKMCMGTOg0WiwY8cOrFu3DlFRUQDK1nQiIiIQGxuL/fv3Iz09HRMnToSPjw969+5tUQ0SCy92ITIm9HKHh4cHVq9ejQULFqB///7w8vJCTEwM+vfvL/eJjo5GSUkJZs6cicLCQoSEhCApKQlOTk4W1yBx8GIXImNChfSiRYsqbAsKCsLmzZsr3UepVGLKlCmYMmVKpX3M1SDx8GIXojJCL3cQEdk7hjQRkcAY0kREAmNIExEJjCFNRCQwhjQ9cHixC9kToU7BIzLn1otdqurD86jpYcGQpgcKL3Yhe8OQpgcSL3Yhe8HVPSIigTGkiYgExpAmIhIYQ5oeOjxFjx4mfOOQHiqWnKJX3o9ngNCDgCFNDxVzp+gBPE2PHiwMaXoo8RQ9elhw9Y6ISGAMaSIigTGkiYgExpAmu8TT9OhBwTcOye7wk/ToQcKQJrtjySfpRUczpEkMDGmyW5WdpscjbRIJQ5roNvzMahIJQ5qoElVdEMM3Hul+YUgT3SF+PgjdTwxpojtk6eeD3P7mo0KhgEqlgkKhuD8DpYcCQ5rISlUth5g62jYYVHBxaYbsbBWUSh5pk2UY0kT3gKmjbYMB0GoNcHUFvL15mh9ZhiFNdA/derRtMAAFBaXyEbS5de2aNYFate7POElcDGkiGzC3rt24MTB6NHDjRtV1uGTy8GNIE9lQZevaXl7WvTlJDx+GNJHA7vTNydtxyeTBx5AmekBVx5IJQ1x8DGmiB5y1SyaWhDjXvG2PIU30kLM2xLnmLQaGNJGdu5tPAwS4ZHKvMaSJyCRLLn/nksm9x5AmoipVdYbJ3SyZlH+WiSXy8oCCgsrbH+ZfBAxpIrpr1iyZGAwq1KjRDFqtGtevV15bqQT0emDFCuvXzs2FvMhLNgxpIrpnqloyMRiAJk2AYcOqXlLx9wcGDrR+7dxcyFt6daetgpwhTUT3nKmANRiAmjVLK20v5+VVdW1za+fmQt6SqzttufbOkCaih0JVIXw3+5fXsNUt1ewmpEtLS7F8+XJs3boVN27cQEhICGbNmoWGDRvaemhE9ICoKsjvFbu5U1tCQgKSk5Mxb948bNq0CaWlpYiMjIRer7f10IiIKmUXIa3X67FmzRpER0eje/fuCAwMxNKlS5GZmYm9e/faenhERJWyi5BOT0/HzZs30alTJ3lbrVq10KJFCxw+fNiGIyMiqppCkiTJ1oO41/bu3YtXX30Vx44dg4uLi7x9woQJKCwsxKpVq+6o3i+//AJJkuDk5GSyXZIklJSUwNHRUb7pqMGgQH5+2Tvapjg5lb07XFmfe91+7x5DgiRJf8+D4iF+nnc2F05OCuGfx70fg/R3+4P/b0OpLDs9T6m0LE6Li4uhUCjQrl07s33t4o1DnU4HABWubnJ2dkZeXt4d1ysP3sru+mzqSipHR6BuXfO1zfW51+3V/xiKv7/u5WPcebttHqPiXDwIz+PejUFhpr06HqP62i3rY9md4BUKhcV3jbeLkC4/etbr9UZH0kVFRVCr1Xdcr23bttU2NiKiqtjFmnT9+vUBAFlZWUbbs7Ky4O3tbYshERFZxC5COjAwEG5ubkhJSZG35efn48SJEwgJCbHhyIiIqmYXyx0qlQoRERGIjY1F3bp18eijj2LJkiXw8fFB7969bT08IqJK2UVIA0B0dDRKSkowc+ZMFBYWIiQkBElJSZWeoUFEJAK7OAWPiOhBZRdr0kREDyqGNBGRwBjSREQCY0gTEQmMIU1EJDCGNBGRwBjSREQCY0hXo9LSUrz33nvo0qULgoODMXr0aFy4cMHWw6oWV69eRUBAQIWvHTt2AADS0tIQERGB4OBghIWFYcOGDUb7WzI35mqIYNWqVRg2bJjRtvvx3EV8bZmai5kzZ1Z4jYSFhcntD+tc3FMSVZv4+Hjp8ccfl7755hspLS1NGjlypNS7d2+pqKjI1kO7a99++63UunVr6erVq1JWVpb8pdPppNzcXOnxxx+Xpk+fLmk0Gmnbtm1S69atpW3btsn7m5sbS2rY2kcffSQFBgZKERER8rb79dxFe22ZmgtJkqSBAwdKcXFxRq+Ra9euye0P41zcawzpalJUVCS1bdtW2rhxo7wtLy9PCgoKknbt2mXDkVWPxMRE6emnnzbZtnLlSqlz585ScXGxvO2dd96RevfuLUmSZXNjroYtZWZmSlFRUVJwcLD01FNPGQXT/XjuIr22qpqL0tJSKTg4WNq7d6/JfR+2ubhfuNxRTR72W3T9+eef8PX1NdmWmpqK0NBQODr+81EwHTt2REZGBnJyciyaG3M1bOmPP/6Ak5MTPvvsM7Rp08ao7X48d5FeW1XNxfnz56HVatGsWTOT+z5sc3G/2M0HLN1rmX/f5738s6vL1atXT257kJ08eRJ16tTB0KFDcfbsWTRu3BivvPIKunbtiszMTPj7+xv1r1evHgDgypUrFs2NuRqenp735HlZIiwszGhd9Vb347mL9Nqqai5OnjwJAPjwww/x/fffw8HBAV27dsXEiRNRs2bNh24u7hceSVeTqm7RVVRUZIshVZuSkhKcOXMGeXl5ePXVV5GYmIjg4GCMGTMGBw4cQGFhocnnDZTd/caSuTFXQ1T347k/KK+tkydPwsHBAfXq1cPKlSsxbdo0/Pjjjxg7dixKS0vtai6qE4+kq0l136JLJI6OjkhJSYFSqZSfW6tWrXDq1CkkJSXBxcUFer3eaJ/yfzCurq4WzY25GqK6H8/9QXltvfLKKxgyZAjq1KkDAPD394eXlxcGDRqE48eP29VcVCceSVeTh/0WXTVq1DD6RwEAjz32GK5evQofHx+TzxsAvL29LZobczVEdT+e+4Py2nJwcJADutxjjz0GoGwZw57mojoxpKvJw3yLrlOnTqFdu3ZGzw0Afv/9d/j5+SEkJARHjhyB4ZZ73R88eBBNmzaFh4eHRXNjroao7sdzf1BeWzExMXjppZeMth0/fhwA4OfnZ1dzUa1sfXrJwyQuLk4KDQ2V9u3bZ3T+pl6vt/XQ7orBYJDCw8OlPn36SIcPH5Y0Go20cOFCqVWrVtKff/4p5eTkSCEhIdLUqVOlU6dOSdu3b5dat24t7dixQ65hbm4sqSGCqVOnGp12dr+eu4ivrdvnYt++fZK/v78UHx8vnTt3Tvr222+lsLAw6bXXXpP7PKxzcS8xpKtRSUmJtHjxYqljx45ScHCwNHr0aOnChQu2Hla1yM7OlqZNmyY9+eSTUuvWraXBgwdLhw8fltuPHTsmDRo0SGrVqpXUo0cP6cMPPzTa35K5MVdDBLcHkyTdn+cu4mvL1Fx88cUX0nPPPScFBQVJTz75pLRo0SKpsLBQbn9Y5+Je4u2ziIgExjVpIiKBMaSJiATGkCYiEhhDmohIYAxpIiKBMaSJiATGkCYiEhhDmugWw4YNq3BLqFsFBARg2rRp93FEZO8Y0kREAmNIExEJjCFNdBf27duHAQMGoHXr1njyyScxf/58aLVauT0+Ph4BAQEV9gsICEB8fLz8fXp6OsaPH4+OHTuiZcuW6NKlC+bPn4/CwsL78jxIXAxpIivt2rUL48aNQ7NmzfD+++9j/Pjx+OyzzzB27FjcyUfiZGVlYejQodDpdFi0aBE++OAD9O3bFx9++CE2bNhwD58BPQh4ZxYiK0iShNjYWHTp0gWxsbHy9iZNmuCll17Cd999h+7du1tU6+TJk2jevDneffdduLm5AQCeeOIJ/PTTT0hJScGYMWPuxVOgBwRDmsgKZ86cQWZmJqKiolBSUiJvDwkJgZubG3766SejkL61z+06d+6Mzp07o7i4GBqNBufOncPJkyeRm5uL2rVr38NnQQ8ChjSRFf766y8AwJw5czBnzpwK7bff3qlly5aV1iotLUVcXBw2btwIrVaL+vXrIygoSL4BK9k3hjSRFWrVqgWg7JZRoaGhFdrd3d2Nvt+2bZvR9wMHDpT/npiYiHXr1mHOnDno3bs3atasWaEP2S+GNJEVmjVrBg8PD1y8eBGjRo2St2dlZSEmJgb/+c9/0KhRI3l769atK6115MgR+Pn5ITw8XN529epVnDx5ssr9yD4wpIluk5mZiXXr1lXartFocODAAUycOBGzZs2CUqlEjx49kJ+fj4SEBFy9erXK5Y3bBQUFISEhAYmJiQgODsa5c+ewatUq6PV66HS6anhG9CBjSBPd5vz583jrrbcqbT9+/Dj+97//YdGiRahRowZWr16NzZs3w9XVFe3atUNsbCwaNmxo8eNFRUXh+vXr2LBhA95//33Ur18fzz77LBQKBVatWoX8/Hx5eYXsD+9xSHSHhg0bhkcffRSLFi2y9VDIDvBiFiIigTGkiYgExuUOIiKB8UiaiEhgDGkiIoExpImIBMaQJiISGEOaiEhgDGkiIoExpImIBMaQJiISGEOaiEhg/w+X0+k8aiIhsQAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "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/t2bOntDcBAAAAQAXm82D13nvv6emnn1bv3r21ceNG3XrrrRo1apR++OEH5eTkaODAgZKkNWvW6LnnntM///lPvfbaa8713333Xb3yyit67LHHtH79el1xxRXq37+/0tLSfLVJAAAAACqYAF/euWEYmjNnjvr166fevXtLkh599FHt2LFD27Zt05EjR/Tnn39q7dq1qlatmiIjI3X8+HG98soreuSRR2S1WrVw4UL16dNHt99+uyTpxRdf1I033qi3335bgwcP9uXmAQAAAKggfLrH6tChQzpy5Ihuu+02l+lLlizR4MGDtWPHDjVv3lzVqlVzzmvXrp3S09O1d+9eHT9+XElJSWrfvr1zfkBAgNq0aaPt27eX2nYAAAAAqNh8usfq0KFDkiSbzaaBAwdqz549uuKKK/Too48qLi5OycnJCgsLc1mnbt26kqS//vpLAQHnhh8eHp5vmX379nk8LsMwZLPZPF6/MBkZGS5/o/TQe9+i/75D732H3vsW/fcdeu879N77DMOQxWJxa1mfBqv09HRJ0rhx4zRs2DCNHj1an3zyiYYMGaJly5YpMzNTVatWdVmnUqVKkqSsrCznk8ZqteZbJisry+Nx5eTkaO/evR6vX5SkpKQSq42Lo/e+Rf99h977Dr33LfrvO/Ted+i9d12YNQrj02AVGBgoSRo4cKB69OghSWrWrJn27NmjZcuWKSgoSNnZ2S7r5AWmkJAQBQUFSVKBywQHB5saV0REhMfrFyYjI0NJSUlq0KCBqfGh+Oi9b9F/36H3vkPvfYv++w699x16732JiYluL+vTYFWvXj1JUmRkpMv0iIgIbd68WbGxsUpISHCZl5KS4lw37xDAlJQUNW7c2GWZvNqesFgsCgkJ8Xj9ogQHB5dofRSO3vsW/fcdeu879N636L/v0Hvfoffe4+5hgJKPT17RvHlzVa5cWbt27XKZnpCQoPr16ysmJkZ79uxxHjIoSVu2bFHlypXVtGlT1apVSw0bNtTWrVud83Nzc7Vjxw7FxMSU2nYAAAAAqNh8GqyCgoI0aNAgvfbaa/rwww/122+/acGCBfr222/Vv39/3XjjjapTp44ef/xx7du3T5s2bdLMmTM1YMAA57GOAwYM0LJly/Tuu+8qMTFRTz31lDIzM3X33Xf7ctMAAAAAVCA+PRRQkoYMGaLg4GDNmjVLR48eVePGjTVv3jy1bdtWkrR48WJNmjRJ99xzj6pVq6ZevXppyJAhzvXvuecenTlzRrNnz9bJkyfVokULLVu2TDVr1vTVJgEAAACoYHwerCSpf//+6t+/f4HzrrrqKi1duvSi6w8cOFADBw4siaEBAAAAQJF8eiggAAAAAFwKysQeK1zCsk9JuelFL+eJgFDJWq1kagMAAADFQLBCycpNlxJelTJTvVs3qLYUOYxgBQAAgDKBYIWSl5kqZSb7ehQAAABAieE3VgAAAABgEsEKAAAAAEwiWAEAAACASQQrAAAAADCJk1eUB5yyHAAAACjTCFblAacsBwAAAMo0glV5wSnLAQAAgDKL31gBAAAAgEkEKwAAAAAwiWAFAAAAACYRrAAAAADAJIIVAAAAAJhEsEI55v7T12KxyGq1ymKxlOB4AAAAUFFxunWUTwGhksVPsh1xa3Grw65G4UGy2o9JNn/374NrfAEAAMANBCuUT/7Bkt0mJca7d+Fkh132szapcojk50aw4uLJAAAAKAaCFco3dy+cbLfLYUuX/EIlfzf3WAEAAABu4jdWAAAAAGASwQoAAAAATCJYAQAAAIBJBCsAAAAAMIlgBQAAAAAmEawAAAAAwCSCFQAAAACYRLACAAAAAJMIVgAAAABgEsEKAAAAAEwiWAEAAACASQQrAAAAADCJYAUAAAAAJhGsAAAAAMAkghUAAAAAmESwAgAAAACTCFYAAAAAYBLBCgAAAABMIlgBAAAAgEkEKwAAAAAwiWAFFIqXBwAAANwT4OsBAGVSQKhk8ZNsR0quvrVaydQGAABAqSNYAQXxD5bsNikxXspM9W7toNpS5DCCFQAAwCWEYAVcTGaqlJns61EAAACgjONHJAAAAABgEsEKAAAAAEwiWAEAAACASQQrAAAAADCJYAUAAAAAJnFWQOBSlH1Kyk0vmdpcgwsAACAfghVwKcpNlxJe5RpcAAAApYRgBVyqSuwaXMU/gthischqtcpisZTAeAAAAHyPYAXAfQGhksVPsh0p1mpWh12NwoNktR+TbP4Xr8/eMAAAUA4RrAC4zz9YstukxPjiHWbosMt+1iZVDpH8CglWHGYIAADKMYIVgOIr7mGGdrsctnTJL1Tyv8geKwAAgHKK060DAAAAgEkEKwAAAAAwiWAFAAAAACYRrAAAAADAJIIV4BO89AAAAC4lnBWwwuMLfqnz8FpQbrP4S4a9ZGoDAACgQASriowv+L7h6bWg3FU1Uqp/t/frAgAAoFA+D1ZHjx5Vp06d8k1/6aWXdNddd2nv3r2aMmWKfv75Z9WsWVMPPvig+vXr51zO4XDo1Vdf1dtvv60zZ84oJiZGzz77rK688srS3IzyiS/4vlXca0G5q1Id79cEAADARfk8WO3bt0+VKlXSpk2bZLFYnNOrVKmiEydOqH///oqLi9OkSZP0448/atKkSapcubJ69uwpSZo/f75Wr16tqVOnKiwsTNOmTdOgQYP0wQcfyGq1+mqzyhe+4AMAAACm+DxYJSQkqEGDBqpbt26+eW+88YYCAwP1/PPPKyAgQI0bN9bhw4cVHx+vnj17Kjs7W0uXLtXo0aPVpUsXSdKsWbPUsWNHffrpp7r11ltLeWsAAAAAVEQ+P3PB/v371bhx4wLn7dixQ7GxsQoI+F/+a9eunZKSkpSamqp9+/bp7Nmzat++vXN+1apVdfXVV2v79u0lPnYAAAAAkMpAsEpISFBaWpp69+6t6667Tvfff7+++uorSVJycrLCwsJcls/bs/XXX38pOfnc4Wvh4eH5lsmbBwAAAAAlzaeHAubm5urgwYOKiIjQ+PHjFRoaqo0bN+rhhx/WsmXLlJmZme93UpUqVZIkZWVlKSMjQ5IKXObUqVMej8swDNlsNo/XL0zeePP+dofFYpHVYZccdsnu5TPsOezyk+QwSqB2SdcvZm27w+7yt7frF0sF6nset/r/3+d5dkaGDMMwOVDk8eR9B95B732L/vsOvfcdeu99hmG4nAfiYnwarAICArR161b5+/srKChIktSiRQsdOHBAS5YsUVBQkLKzs13WycrKkiSFhIQ418nOznb+O2+Z4OBgj8eVk5OjvXv3erx+UZKSktxe1mq1qlF4kOxnbXLY0r06Dv9KmQpxOGSzZcie7t3aJV3f09o2m3tvNGVx7GWhvtnaF+u/n8Mm/8wsHfwrMd/rHuYV530H3kXvfYv++w699x16713unhDP5yevqFy5cr5pf/vb3/TNN98oLCxMKSkpLvPybterV0+5ubnOafXr13dZpkmTJh6PKTAwUBERER6vX5iMjAwlJSWpQYMGbgc/i8Uiq/2YVDlE8gv17oCCg+Tn56eQkGBJXq5d0vWLWdvusMtmy1BISLD8/fy9Xr9YKlDf87jV/+AQKaiSIiKuYI+VF3nyvgPvoPe+Rf99h977Dr33vsTERLeX9WmwOnDggO69914tWLBAbdu2dU7/+eefFRERoWbNmmnNmjWy2+3y9z/3ZWzLli1q2LChatWqpSpVqig0NFRbt251BqvTp09rz5496tOnj8fjslgsCgkJMbdxFxEcHFy8+jZ/yc9f8ncjEBTHf7/g+ltKoHZJ1/ewtr+fv/O5VBL13VIB+57nov33O/c854OgZBT7fQdeQ+99i/77Dr33HXrvPe4eBij5+OQVjRs3VqNGjfT8889rx44d+vXXX/XSSy/pxx9/1KOPPqqePXsqPT1dTz/9tBITE7V+/XotX75cgwcPlnRut1yfPn00ffp0ffbZZ9q3b59GjhypsLAwde3a1ZebBgAAAKAC8ekeKz8/Py1cuFAzZszQ448/rtOnT+vqq6/WsmXLFBkZKUlavHixpkyZoh49eqhOnToaO3asevTo4awxYsQI5ebmasKECcrMzFRMTIyWLFmiwMBAX20WAAAAgArG57+xql27tl566aVC50dFRemtt94qdL6/v7/GjBmjMWPGlMTwAAAAAKBIPr+OFQAAAACUdwQrAAAAADCJYAUAAAAAJhGsAAAAAMAkghUAAAAAmESwAgAAAACTCFYAAAAAYBLBCgAAAABMIlgBAAAAgEkEKwAAAAAwiWAFAAAAACYRrAAAAADAJIIVAAAAAJhEsAIAAAAAkwhWAAAAAGASwQoAAAAATCJYAShDeEsCAADlU4CvBwAAkqSAUMniJ9mOlOx9WKuVXH0AAFBhEawAlA3+wZLdJiXGS5mp3q8fVFuKHEawAgAAJYJgBaBsyUyVMpN9PQoAAIBi4QcNAAAAAGASwQoAAAAATCJYAQAAAIBJBCsAAAAAMIlgBQAAAAAmEawAAAAAwCSCFQAAAACYRLACAAAAAJMIVgAAAABgEsEKAAAAAEwiWAEAAACASQQrAAAAADCJYAUAAAAAJhGsAAAAAMAkghUAAAAAmESwAgAAAACTCFYAAAAAYBLBCgAAAABMIlgBAAAAgEkEKwAAAAAwiWAFAAAAACYRrAAAAADAJIIVAAAAAJhEsAIAAAAAkwhWAAAAAGASwQoAAAAATCJYAQAAAIBJBCsAFQhveQAAoGQE+HoAAFAqAkIli59kO1Jy9a3VSqY2AAAo8whWACoG/2DJbpMS46XMVO/WDqotRQ4jWAEAUIERrABULJmpUmayr0cBAAAuMfzgAAAAAABMIlgBAAAAgEkEKwAAAAAwiWAFAAAAACYRrAAAAADAJIIVAAAAAJhEsAIAAAAAkwhWAAAAAGASwQoAAAAATCJYAQAAAIBJBCsAAAAAMIlgBQAAAAAmlalgdejQIbVq1Urr1693Ttu7d6/69Omj6OhoxcXFacWKFS7rOBwOzZ07Vx07dlR0dLQeeugh/f7776U9dAAAAAAVWJkJVjk5ORo9erRsNptz2okTJ9S/f3/Vr19f69at09ChQzV9+nStW7fOucz8+fO1evVqvfDCC1qzZo0cDocGDRqk7OxsX2wGAAAAgAqozASrefPmKTQ01GXa2rVrFRgYqOeff16NGzdWz5499eCDDyo+Pl6SlJ2draVLl2rEiBHq0qWLmjZtqlmzZik5OVmffvqpLzYDAAAAQAVUJoLV9u3b9dZbb2nq1Kku03fs2KHY2FgFBAQ4p7Vr105JSUlKTU3Vvn37dPbsWbVv3945v2rVqrr66qu1ffv2Uhs/AAAAgIotoOhFStbp06c1duxYTZgwQeHh4S7zkpOTFRkZ6TKtbt26kqS//vpLycnJkpRvvbp16zrnecIwDJdDEr0lIyPD5W93WCwWWR12yWGX7HbvDshhl58kh1ECtUu6fjFr2x12l7+9Xb9YKlDf87jV/3LeFznsys7IkGEY3q1tkifvO/AOeu9b9N936L3v0HvvMwxDFovFrWV9Hqyee+45tWrVSrfddlu+eZmZmbJarS7TKlWqJEnKyspyPmkKWubUqVMejyknJ0d79+71eP2iJCUlub2s1WpVo/Ag2c/a5LCle3Uc/pUyFeJwyGbLkD3du7VLur6ntW02995oyuLYy0J9s7Uv1v/y3Bc/h03+mVk6+Fdimf19Z3Hed+Bd9N636L/v0HvfoffedWHWKIxPg9WGDRu0Y8cOffDBBwXODwoKyvclJSsrS5IUEhKioKAgSed+a5X377xlgoODPR5XYGCgIiIiPF6/MBkZGUpKSlKDBg3cHp/FYpHVfkyqHCL5hRa9QnEEB8nPz08hIcGSvFy7pOsXs7bdYZfNlqGQkGD5+/l7vX6xVKC+53Gr/+W6LyFSUCVFRFxRJvdYFfd9B95B732L/vsOvfcdeu99iYmJbi/r02C1bt06HT9+XF26dHGZPnHiRH300UcKCwtTSkqKy7y82/Xq1VNubq5zWv369V2WadKkicfjslgsCgkJ8Xj9ogQHBxevvs1f8vOX/N0IBMXx3y+4/pYSqF3S9T2s7e/nL393li+DYy8T9U3Wvmj/y3tf/PzL9IdYsd934DX03rfov+/Qe9+h997j7mGAko+D1fTp05WZmekyrWvXrhoxYoRuv/12vffee1qzZo3sdrvzy9iWLVvUsGFD1apVS1WqVFFoaKi2bt3qDFanT5/Wnj171KdPn1LfHgAAAAAVk0+DVb169QqcXqtWLdWrV089e/bU4sWL9fTTT2vQoEH66aeftHz5ck2aNEnSueMd+/Tpo+nTp6tmzZq6/PLLNW3aNIWFhalr166luSkAAAAAKjCfn7ziYmrVqqXFixdrypQp6tGjh+rUqaOxY8eqR48ezmVGjBih3NxcTZgwQZmZmYqJidGSJUsUGBjow5EDAAAAqEjKXLDav3+/y+2oqCi99dZbhS7v7++vMWPGaMyYMSU9NAAAAAAoUJm4QDAAAAAAlGcEKwAAAAAwiWAFAAAAACYRrAAAAADAJIIVAAAAAJhEsAIAAAAAkwhWAAAAAGASwQoAAAAATCJYAYBX8HYKAEBFFuDrAQBAuRcQKln8JNuRkr0Pa7WSqw8AAEwhWAGAWf7Bkt0mJcZLmanerx9UW4ocRrACAKAMI1gBgLdkpkqZyb4eBQAA8AF+FAAAAAAAJhGsAAAAAMAkghUAAAAAmESwAgAAAACTCFYAAAAAYBLBCgAAAABMIlgBAAAAgEkEKwAoFzx7u7ZYLLJarbJYLF4eDwAAOJ+pCwSfPn1aP/74o86cOaMaNWooKipKoaGh3hobAECSAkIli59kO1LsVa0OuxqFB8lqPybZ/Auvb61mcpAAAFRsHger+Ph4zZ8/X1lZWTIMQ5JktVo1ePBgDR061GsDBIAKzz9YstukxHgpM7V46zrssp+1SZVDJL8CglVQbSlyGMEKAACTPApW69at08yZM3X33Xfr9ttvV+3atXXs2DG99957evXVV3XZZZepR48e3h4rAFRsmalSZnLx1rHb5bClS36hkn8he6wAAIBpHgWr5cuX6/7779fEiROd0xo1aqS2bdsqKChIK1asIFgBAAAAqDA8+jX04cOHdeONNxY474YbbtDBgwdNDQoAAAAAyhOPglW9evX0559/Fjjvjz/+4AQWAAAAACoUj4JVXFyc5syZo59++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": [ + "
" + ] + }, + "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": "aimenv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}