{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "f2485344",
      "metadata": {},
      "source": [
        "# Прогнозирование энергопотребления"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 81,
      "id": "c15bd427",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m25.3\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m26.0.1\u001b[0m\n",
            "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
            "Note: you may need to restart the kernel to use updated packages.\n"
          ]
        }
      ],
      "source": [
        "%pip -q install pandas numpy matplotlib seaborn scikit-learn"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 82,
      "id": "ad72f151",
      "metadata": {},
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "import pandas as pd\n",
        "import matplotlib.pyplot as plt\n",
        "import seaborn as sns\n",
        "\n",
        "from sklearn.model_selection import train_test_split\n",
        "from sklearn.compose import ColumnTransformer\n",
        "from sklearn.preprocessing import OneHotEncoder\n",
        "from sklearn.pipeline import Pipeline\n",
        "from sklearn.impute import SimpleImputer\n",
        "from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score\n",
        "from sklearn.linear_model import LinearRegression\n",
        "from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor\n",
        "\n",
        "pd.set_option(\"display.max_columns\", 50)\n",
        "sns.set_style(\"whitegrid\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 83,
      "id": "79315a77",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>Building Type</th>\n",
              "      <th>Square Footage</th>\n",
              "      <th>Number of Occupants</th>\n",
              "      <th>Appliances Used</th>\n",
              "      <th>Average Temperature</th>\n",
              "      <th>Day of Week</th>\n",
              "      <th>Energy Consumption</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>Residential</td>\n",
              "      <td>7063</td>\n",
              "      <td>76</td>\n",
              "      <td>10</td>\n",
              "      <td>29.84</td>\n",
              "      <td>Weekday</td>\n",
              "      <td>2713.95</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>Commercial</td>\n",
              "      <td>44372</td>\n",
              "      <td>66</td>\n",
              "      <td>45</td>\n",
              "      <td>16.72</td>\n",
              "      <td>Weekday</td>\n",
              "      <td>5744.99</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>Industrial</td>\n",
              "      <td>19255</td>\n",
              "      <td>37</td>\n",
              "      <td>17</td>\n",
              "      <td>14.30</td>\n",
              "      <td>Weekend</td>\n",
              "      <td>4101.24</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>Residential</td>\n",
              "      <td>13265</td>\n",
              "      <td>14</td>\n",
              "      <td>41</td>\n",
              "      <td>32.82</td>\n",
              "      <td>Weekday</td>\n",
              "      <td>3009.14</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>Commercial</td>\n",
              "      <td>13375</td>\n",
              "      <td>26</td>\n",
              "      <td>18</td>\n",
              "      <td>11.92</td>\n",
              "      <td>Weekday</td>\n",
              "      <td>3279.17</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "  Building Type  Square Footage  Number of Occupants  Appliances Used  \\\n",
              "0   Residential            7063                   76               10   \n",
              "1    Commercial           44372                   66               45   \n",
              "2    Industrial           19255                   37               17   \n",
              "3   Residential           13265                   14               41   \n",
              "4    Commercial           13375                   26               18   \n",
              "\n",
              "   Average Temperature Day of Week  Energy Consumption  \n",
              "0                29.84     Weekday             2713.95  \n",
              "1                16.72     Weekday             5744.99  \n",
              "2                14.30     Weekend             4101.24  \n",
              "3                32.82     Weekday             3009.14  \n",
              "4                11.92     Weekday             3279.17  "
            ]
          },
          "execution_count": 83,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Загрузка обучающей выборки\n",
        "df = pd.read_csv(\"train_energy_data.csv\")\n",
        "df.head()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "667f4766",
      "metadata": {},
      "source": [
        "## Очистка и предобработка\n",
        "\n",
        "- Удаляем дубликаты.\n",
        "- Удаляем пропуски (если есть).\n",
        "- Проверяем типы и качество данных."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 84,
      "id": "e3e30a9f",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "<class 'pandas.DataFrame'>\n",
            "RangeIndex: 1000 entries, 0 to 999\n",
            "Data columns (total 7 columns):\n",
            " #   Column               Non-Null Count  Dtype  \n",
            "---  ------               --------------  -----  \n",
            " 0   Building Type        1000 non-null   str    \n",
            " 1   Square Footage       1000 non-null   int64  \n",
            " 2   Number of Occupants  1000 non-null   int64  \n",
            " 3   Appliances Used      1000 non-null   int64  \n",
            " 4   Average Temperature  1000 non-null   float64\n",
            " 5   Day of Week          1000 non-null   str    \n",
            " 6   Energy Consumption   1000 non-null   float64\n",
            "dtypes: float64(2), int64(3), str(2)\n",
            "memory usage: 54.8 KB\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "None"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/plain": [
              "Building Type          0.0\n",
              "Square Footage         0.0\n",
              "Number of Occupants    0.0\n",
              "Appliances Used        0.0\n",
              "Average Temperature    0.0\n",
              "Day of Week            0.0\n",
              "Energy Consumption     0.0\n",
              "dtype: float64"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "df = df.drop_duplicates()\n",
        "df = df.dropna()\n",
        "display(df.info())\n",
        "display(df.isna().mean().sort_values(ascending=False))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "35e99891",
      "metadata": {},
      "source": [
        "Загружаем **тестовую выборку** (`test_energy_data.csv`) — на ней будем считать метрики качества моделей (без использования для обучения)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 85,
      "id": "c09c6a3a",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Train: 1000 объектов. Test: 100 объектов.\n"
          ]
        }
      ],
      "source": [
        "# Обучающая выборка (признаки и целевая переменная)\n",
        "df_model = df.dropna(subset=[\"Energy Consumption\"]).copy()\n",
        "X_train = df_model.drop(columns=[\"Energy Consumption\"])\n",
        "y_train = df_model[\"Energy Consumption\"]\n",
        "\n",
        "# Тестовая выборка из файла test_energy_data.csv\n",
        "df_test = pd.read_csv(\"test_energy_data.csv\").dropna(subset=[\"Energy Consumption\"])\n",
        "X_test = df_test.drop(columns=[\"Energy Consumption\"])\n",
        "y_test = df_test[\"Energy Consumption\"]\n",
        "print(\"Train:\", X_train.shape[0], \"объектов. Test:\", X_test.shape[0], \"объектов.\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "571cc12d",
      "metadata": {},
      "source": [
        "## Задание 1. Анализ исходных данных. Постановка задачи.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 86,
      "id": "861b82a1",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "image/png": "[encoded data, 26864 characters]",
            "text/plain": [
              "<Figure size 700x400 with 1 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "image/png": "[encoded data, 28956 characters]",
            "text/plain": [
              "<Figure size 700x400 with 1 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# График 1: распределение целевой переменной (энергопотребление)\n",
        "def hist(df, label):\n",
        "    plt.figure(figsize=(7, 4))\n",
        "    sns.histplot(df[\"Energy Consumption\"], bins=50)\n",
        "    plt.title(\"Распределение энергопотребления (\" + label + \")\")\n",
        "    plt.xlabel(\"Energy Consumption\")\n",
        "    plt.show()\n",
        "hist(df_model, \"train_energy_data.csv)\")  \n",
        "hist(df_test, \"test_energy_data.csv)\") \n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "72db1caa",
      "metadata": {},
      "source": [
        "**Описание графика 1:** Распределение целевой переменной Energy Consumption. Видно, что чаще всего встречается потребление около 4000 единиц\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 87,
      "id": "d75488be",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "image/png": "[encoded data, 145852 characters]",
            "text/plain": [
              "<Figure size 1200x400 with 2 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "image/png": "[encoded data, 63932 characters]",
            "text/plain": [
              "<Figure size 1200x400 with 2 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# График 2: зависимость энергопотребления от типа здания и площади\n",
        "def plot_building_and_area(df, label):\n",
        "    fig, axes = plt.subplots(1, 2, figsize=(12, 4))\n",
        "    sns.boxplot(data=df, x=\"Building Type\", y=\"Energy Consumption\", ax=axes[0])\n",
        "    axes[0].set_title(f\"Энергопотребление по типу здания ({label})\")\n",
        "    sns.scatterplot(data=df, x=\"Square Footage\", y=\"Energy Consumption\", alpha=0.4, ax=axes[1])\n",
        "    axes[1].set_title(f\"Энергопотребление от площади ({label})\")\n",
        "    plt.tight_layout()\n",
        "    plt.show()\n",
        "\n",
        "plot_building_and_area(df_model, \"train_energy_data.csv\")\n",
        "plot_building_and_area(df_test, \"test_energy_data.csv\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "462cc702",
      "metadata": {},
      "source": [
        "**Описание графика 2:** Слева — зависимость энергопотребления от типа здания (Residential, Commercial, Industrial). Справа — связь между площадью здания и энергопотреблением; \n",
        "Можно заметить, что у жилых помещений потребление меньше, чем у коммерческих, а у коммерческих меньше чем у индустриальных. Также видно, что бОльшая площадь ведёт к бОльшему потреблению."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 88,
      "id": "8837110e",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "image/png": "[encoded data, 100552 characters]",
            "text/plain": [
              "<Figure size 1200x400 with 3 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "image/png": "[encoded data, 101640 characters]",
            "text/plain": [
              "<Figure size 1200x400 with 3 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# График 3: среднее энергопотребление по дню недели и тепловая карта корреляций\n",
        "num_cols = [\"Square Footage\", \"Number of Occupants\", \"Appliances Used\", \"Average Temperature\", \"Energy Consumption\"]\n",
        "\n",
        "def plot_day_and_corr(df, label):\n",
        "    fig, axes = plt.subplots(1, 2, figsize=(12, 4))\n",
        "    sns.barplot(data=df, x=\"Day of Week\", y=\"Energy Consumption\", estimator=\"mean\", ax=axes[0])\n",
        "    axes[0].set_title(f\"Среднее энергопотребление: будни vs выходные ({label})\")\n",
        "    sns.heatmap(df[num_cols].corr(), annot=True, fmt=\".2f\", cmap=\"coolwarm\", center=0, ax=axes[1])\n",
        "    axes[1].set_title(f\"Корреляция числовых признаков ({label})\")\n",
        "    plt.tight_layout()\n",
        "    plt.show()\n",
        "\n",
        "plot_day_and_corr(df_model, \"train_energy_data.csv\")\n",
        "plot_day_and_corr(df_test, \"test_energy_data.csv\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e8ade242",
      "metadata": {},
      "source": [
        "**Описание графика 3:** Слева — сравнение среднего энергопотребления в будни и выходные. Справа — корреляционная матрица числовых признаков; видно, какие факторы сильнее связаны с энергопотреблением: площадь, количество проживающих, количество бытовой техники - положительно коррелируют с потреблением. А вот средняя температура - не коррелирует.\n",
        "\n",
        "---\n",
        "\n",
        "### Выводы о качестве датасета\n",
        "\n",
        "- **Очистка и предобработка:** выполнены удаление дубликатов и пропусков; после очистки датасет готов к моделированию.\n",
        "- **Качество:** датасет имеет не случайные данные, видна зависимость энергопотребления от других данных, даже на тестовой выборке."
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c4f56adf",
      "metadata": {},
      "source": [
        "## Задание 2. Построить прогнозную модель для оценки энергопотребления\n",
        "\n",
        "Целевая переменная — **Energy Consumption** (количественная). Используем несколько моделей для сравнения точности на train и test."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 89,
      "id": "8479ddf7",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>model</th>\n",
              "      <th>split</th>\n",
              "      <th>MAE</th>\n",
              "      <th>RMSE</th>\n",
              "      <th>R2</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>LinearRegression</td>\n",
              "      <td>train</td>\n",
              "      <td>0.011573</td>\n",
              "      <td>0.013650</td>\n",
              "      <td>1.000000</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>LinearRegression</td>\n",
              "      <td>test</td>\n",
              "      <td>0.012162</td>\n",
              "      <td>0.014197</td>\n",
              "      <td>1.000000</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>RandomForest</td>\n",
              "      <td>train</td>\n",
              "      <td>34.482342</td>\n",
              "      <td>43.957397</td>\n",
              "      <td>0.997780</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>RandomForest</td>\n",
              "      <td>test</td>\n",
              "      <td>93.290891</td>\n",
              "      <td>118.888277</td>\n",
              "      <td>0.979403</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>GradientBoosting</td>\n",
              "      <td>train</td>\n",
              "      <td>39.154710</td>\n",
              "      <td>50.360767</td>\n",
              "      <td>0.997085</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>5</th>\n",
              "      <td>GradientBoosting</td>\n",
              "      <td>test</td>\n",
              "      <td>65.365958</td>\n",
              "      <td>83.840513</td>\n",
              "      <td>0.989757</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "              model  split        MAE        RMSE        R2\n",
              "0  LinearRegression  train   0.011573    0.013650  1.000000\n",
              "1  LinearRegression   test   0.012162    0.014197  1.000000\n",
              "2      RandomForest  train  34.482342   43.957397  0.997780\n",
              "3      RandomForest   test  93.290891  118.888277  0.979403\n",
              "4  GradientBoosting  train  39.154710   50.360767  0.997085\n",
              "5  GradientBoosting   test  65.365958   83.840513  0.989757"
            ]
          },
          "execution_count": 89,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Признаки для препроцессинга (по обучающей выборке)\n",
        "cat_cols = X_train.select_dtypes(include=[\"object\", \"string\"]).columns.tolist()\n",
        "num_cols = X_train.select_dtypes(exclude=[\"object\", \"string\"]).columns.tolist()\n",
        "\n",
        "preprocess = ColumnTransformer(\n",
        "    transformers=[\n",
        "        (\"num\", Pipeline([\n",
        "            (\"imputer\", SimpleImputer(strategy=\"median\"))\n",
        "        ]), num_cols),\n",
        "        (\"cat\", Pipeline([\n",
        "            (\"imputer\", SimpleImputer(strategy=\"most_frequent\")),\n",
        "            (\"onehot\", OneHotEncoder(handle_unknown=\"ignore\"))\n",
        "        ]), cat_cols)\n",
        "    ]\n",
        ")\n",
        "\n",
        "models = {\n",
        "    \"LinearRegression\": LinearRegression(),\n",
        "    \"RandomForest\": RandomForestRegressor(n_estimators=200, random_state=42),\n",
        "    \"GradientBoosting\": GradientBoostingRegressor(random_state=42)\n",
        "}\n",
        "\n",
        "def evaluate_models(X_tr, y_tr, X_te, y_te, models):\n",
        "    \"\"\"Обучает модели на X_tr, y_tr; считает метрики на обучающей и на тестовой (X_te, y_te) выборках.\"\"\"\n",
        "    rows = []\n",
        "    for name, model in models.items():\n",
        "        pipe = Pipeline([\n",
        "            (\"preprocess\", preprocess),\n",
        "            (\"model\", model)\n",
        "        ])\n",
        "        pipe.fit(X_tr, y_tr)\n",
        "        for split, (X_s, y_s) in {\n",
        "            \"train\": (X_tr, y_tr),\n",
        "            \"test\": (X_te, y_te)\n",
        "        }.items():\n",
        "            pred = pipe.predict(X_s)\n",
        "            rows.append({\n",
        "                \"model\": name,\n",
        "                \"split\": split,\n",
        "                \"MAE\": mean_absolute_error(y_s, pred),\n",
        "                \"RMSE\": np.sqrt(mean_squared_error(y_s, pred)),\n",
        "                \"R2\": r2_score(y_s, pred)\n",
        "            })\n",
        "    return pd.DataFrame(rows)\n",
        "\n",
        "# Обучаем на train_energy_data.csv, оцениваем на train и на test_energy_data.csv\n",
        "results_before = evaluate_models(X_train, y_train, X_test, y_test, models)\n",
        "results_before"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 90,
      "id": "1fd412bc",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead tr th {\n",
              "        text-align: left;\n",
              "    }\n",
              "\n",
              "    .dataframe thead tr:last-of-type th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr>\n",
              "      <th></th>\n",
              "      <th colspan=\"2\" halign=\"left\">MAE</th>\n",
              "      <th colspan=\"2\" halign=\"left\">R2</th>\n",
              "      <th colspan=\"2\" halign=\"left\">RMSE</th>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>split</th>\n",
              "      <th>test</th>\n",
              "      <th>train</th>\n",
              "      <th>test</th>\n",
              "      <th>train</th>\n",
              "      <th>test</th>\n",
              "      <th>train</th>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>model</th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>GradientBoosting</th>\n",
              "      <td>65.365958</td>\n",
              "      <td>39.154710</td>\n",
              "      <td>0.989757</td>\n",
              "      <td>0.997085</td>\n",
              "      <td>83.840513</td>\n",
              "      <td>50.360767</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>LinearRegression</th>\n",
              "      <td>0.012162</td>\n",
              "      <td>0.011573</td>\n",
              "      <td>1.000000</td>\n",
              "      <td>1.000000</td>\n",
              "      <td>0.014197</td>\n",
              "      <td>0.013650</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>RandomForest</th>\n",
              "      <td>93.290891</td>\n",
              "      <td>34.482342</td>\n",
              "      <td>0.979403</td>\n",
              "      <td>0.997780</td>\n",
              "      <td>118.888277</td>\n",
              "      <td>43.957397</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "                        MAE                   R2                  RMSE  \\\n",
              "split                  test      train      test     train        test   \n",
              "model                                                                    \n",
              "GradientBoosting  65.365958  39.154710  0.989757  0.997085   83.840513   \n",
              "LinearRegression   0.012162   0.011573  1.000000  1.000000    0.014197   \n",
              "RandomForest      93.290891  34.482342  0.979403  0.997780  118.888277   \n",
              "\n",
              "                             \n",
              "split                 train  \n",
              "model                        \n",
              "GradientBoosting  50.360767  \n",
              "LinearRegression   0.013650  \n",
              "RandomForest      43.957397  "
            ]
          },
          "execution_count": 90,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Таблица результатов (train / test)\n",
        "pivot_before = results_before.pivot_table(index=\"model\", columns=\"split\", values=[\"MAE\", \"RMSE\", \"R2\"])\n",
        "pivot_before"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 91,
      "id": "eabdd5b5",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "image/png": "[encoded data, 36884 characters]",
            "text/plain": [
              "<Figure size 1400x400 with 3 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# Визуализация метрик на тесте\n",
        "test_before = results_before[results_before[\"split\"] == \"test\"]\n",
        "fig, axes = plt.subplots(1, 3, figsize=(14, 4))\n",
        "sns.barplot(data=test_before, x=\"model\", y=\"MAE\", ax=axes[0])\n",
        "sns.barplot(data=test_before, x=\"model\", y=\"RMSE\", ax=axes[1])\n",
        "sns.barplot(data=test_before, x=\"model\", y=\"R2\", ax=axes[2])\n",
        "axes[0].set_title(\"MAE (test)\")\n",
        "axes[1].set_title(\"RMSE (test)\")\n",
        "axes[2].set_title(\"R2 (test)\")\n",
        "plt.tight_layout()\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "23888437",
      "metadata": {},
      "source": [
        "### Почему выбраны эти метрики\n",
        "\n",
        "- **MAE** (Mean Absolute Error) — средняя абсолютная ошибка в тех же единицах, что и энергопотребление; интерпретируема и устойчива к выбросам.\n",
        "- **RMSE** (Root Mean Squared Error) — корень из средней квадратичной ошибки; сильнее штрафует большие ошибки, полезна для оценки риска крупных промахов.\n",
        "- **R2** (коэффициент детерминации) — доля объяснённой дисперсии: 0 означает, что модель не лучше предсказания средним, 1 — полное совпадение с целевой переменной."
      ]
    },
    {
      "cell_type": "markdown",
      "id": "eadb5756",
      "metadata": {},
      "source": [
        "## Задание 3. Добавление 20 новых записей и анализ изменений точности\n",
        "\n",
        "Добавляем 20 новых записей. Признаки генерируются по следующему **принципу**:\n",
        "- **Building Type**, **Day of Week** — случайный выбор из тех же категорий, что и в исходных данных (равновероятно или пропорционально).\n",
        "- **Square Footage**, **Number of Occupants**, **Appliances Used**, **Average Temperature** — случайные значения из диапазонов, совпадающих с минимумом и максимумом по обучающей выборке (равномерное распределение), чтобы новые точки не выходили за пределы уже наблюдаемых.\n",
        "- **Energy Consumption** — для новых записей задаём по упрощённой формуле, согласованной с данными: базовая составляющая от площади и числа жильцов плюс случайный шум в диапазоне стандартного отклонения целевой переменной, чтобы новые строки были «правдоподобны» и не ломали распределение."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 92,
      "id": "357262bb",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>Building Type</th>\n",
              "      <th>Square Footage</th>\n",
              "      <th>Number of Occupants</th>\n",
              "      <th>Appliances Used</th>\n",
              "      <th>Average Temperature</th>\n",
              "      <th>Day of Week</th>\n",
              "      <th>Energy Consumption</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>Industrial</td>\n",
              "      <td>47560.463166</td>\n",
              "      <td>73</td>\n",
              "      <td>30</td>\n",
              "      <td>13.94</td>\n",
              "      <td>Weekend</td>\n",
              "      <td>6346.46</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>Industrial</td>\n",
              "      <td>3348.819232</td>\n",
              "      <td>72</td>\n",
              "      <td>46</td>\n",
              "      <td>10.07</td>\n",
              "      <td>Weekend</td>\n",
              "      <td>4607.10</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>Residential</td>\n",
              "      <td>15600.823765</td>\n",
              "      <td>52</td>\n",
              "      <td>22</td>\n",
              "      <td>17.31</td>\n",
              "      <td>Weekday</td>\n",
              "      <td>3895.37</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>Industrial</td>\n",
              "      <td>5039.310304</td>\n",
              "      <td>62</td>\n",
              "      <td>19</td>\n",
              "      <td>34.57</td>\n",
              "      <td>Weekend</td>\n",
              "      <td>4711.79</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>Residential</td>\n",
              "      <td>43072.873888</td>\n",
              "      <td>68</td>\n",
              "      <td>23</td>\n",
              "      <td>10.38</td>\n",
              "      <td>Weekday</td>\n",
              "      <td>5582.57</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>5</th>\n",
              "      <td>Commercial</td>\n",
              "      <td>1349.323611</td>\n",
              "      <td>23</td>\n",
              "      <td>12</td>\n",
              "      <td>27.09</td>\n",
              "      <td>Weekday</td>\n",
              "      <td>3261.35</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>6</th>\n",
              "      <td>Residential</td>\n",
              "      <td>2260.065318</td>\n",
              "      <td>91</td>\n",
              "      <td>13</td>\n",
              "      <td>26.57</td>\n",
              "      <td>Weekend</td>\n",
              "      <td>4543.40</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>7</th>\n",
              "      <td>Commercial</td>\n",
              "      <td>9698.649718</td>\n",
              "      <td>96</td>\n",
              "      <td>38</td>\n",
              "      <td>33.48</td>\n",
              "      <td>Weekend</td>\n",
              "      <td>5503.54</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>8</th>\n",
              "      <td>Commercial</td>\n",
              "      <td>30118.381252</td>\n",
              "      <td>92</td>\n",
              "      <td>5</td>\n",
              "      <td>14.94</td>\n",
              "      <td>Weekend</td>\n",
              "      <td>5043.68</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>9</th>\n",
              "      <td>Residential</td>\n",
              "      <td>27240.759949</td>\n",
              "      <td>59</td>\n",
              "      <td>48</td>\n",
              "      <td>25.19</td>\n",
              "      <td>Weekend</td>\n",
              "      <td>5990.45</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>10</th>\n",
              "      <td>Residential</td>\n",
              "      <td>15206.873301</td>\n",
              "      <td>17</td>\n",
              "      <td>1</td>\n",
              "      <td>20.61</td>\n",
              "      <td>Weekday</td>\n",
              "      <td>2556.43</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>11</th>\n",
              "      <td>Industrial</td>\n",
              "      <td>10390.171931</td>\n",
              "      <td>71</td>\n",
              "      <td>39</td>\n",
              "      <td>25.16</td>\n",
              "      <td>Weekday</td>\n",
              "      <td>4978.12</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>12</th>\n",
              "      <td>Commercial</td>\n",
              "      <td>32747.294910</td>\n",
              "      <td>91</td>\n",
              "      <td>42</td>\n",
              "      <td>21.26</td>\n",
              "      <td>Weekday</td>\n",
              "      <td>6544.77</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>13</th>\n",
              "      <td>Commercial</td>\n",
              "      <td>33481.203544</td>\n",
              "      <td>59</td>\n",
              "      <td>14</td>\n",
              "      <td>24.05</td>\n",
              "      <td>Weekend</td>\n",
              "      <td>5094.18</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>14</th>\n",
              "      <td>Industrial</td>\n",
              "      <td>48598.530860</td>\n",
              "      <td>85</td>\n",
              "      <td>36</td>\n",
              "      <td>15.94</td>\n",
              "      <td>Weekday</td>\n",
              "      <td>6667.79</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>15</th>\n",
              "      <td>Residential</td>\n",
              "      <td>2113.764653</td>\n",
              "      <td>64</td>\n",
              "      <td>16</td>\n",
              "      <td>22.73</td>\n",
              "      <td>Weekday</td>\n",
              "      <td>3928.83</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>16</th>\n",
              "      <td>Commercial</td>\n",
              "      <td>12884.259932</td>\n",
              "      <td>41</td>\n",
              "      <td>38</td>\n",
              "      <td>15.76</td>\n",
              "      <td>Weekday</td>\n",
              "      <td>4165.87</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>17</th>\n",
              "      <td>Commercial</td>\n",
              "      <td>46521.462839</td>\n",
              "      <td>81</td>\n",
              "      <td>32</td>\n",
              "      <td>31.78</td>\n",
              "      <td>Weekend</td>\n",
              "      <td>7000.00</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>18</th>\n",
              "      <td>Commercial</td>\n",
              "      <td>27223.462414</td>\n",
              "      <td>80</td>\n",
              "      <td>44</td>\n",
              "      <td>17.98</td>\n",
              "      <td>Weekend</td>\n",
              "      <td>5941.62</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>19</th>\n",
              "      <td>Commercial</td>\n",
              "      <td>41000.195983</td>\n",
              "      <td>86</td>\n",
              "      <td>1</td>\n",
              "      <td>22.79</td>\n",
              "      <td>Weekday</td>\n",
              "      <td>5669.67</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "   Building Type  Square Footage  Number of Occupants  Appliances Used  \\\n",
              "0     Industrial    47560.463166                   73               30   \n",
              "1     Industrial     3348.819232                   72               46   \n",
              "2    Residential    15600.823765                   52               22   \n",
              "3     Industrial     5039.310304                   62               19   \n",
              "4    Residential    43072.873888                   68               23   \n",
              "5     Commercial     1349.323611                   23               12   \n",
              "6    Residential     2260.065318                   91               13   \n",
              "7     Commercial     9698.649718                   96               38   \n",
              "8     Commercial    30118.381252                   92                5   \n",
              "9    Residential    27240.759949                   59               48   \n",
              "10   Residential    15206.873301                   17                1   \n",
              "11    Industrial    10390.171931                   71               39   \n",
              "12    Commercial    32747.294910                   91               42   \n",
              "13    Commercial    33481.203544                   59               14   \n",
              "14    Industrial    48598.530860                   85               36   \n",
              "15   Residential     2113.764653                   64               16   \n",
              "16    Commercial    12884.259932                   41               38   \n",
              "17    Commercial    46521.462839                   81               32   \n",
              "18    Commercial    27223.462414                   80               44   \n",
              "19    Commercial    41000.195983                   86                1   \n",
              "\n",
              "    Average Temperature Day of Week  Energy Consumption  \n",
              "0                 13.94     Weekend             6346.46  \n",
              "1                 10.07     Weekend             4607.10  \n",
              "2                 17.31     Weekday             3895.37  \n",
              "3                 34.57     Weekend             4711.79  \n",
              "4                 10.38     Weekday             5582.57  \n",
              "5                 27.09     Weekday             3261.35  \n",
              "6                 26.57     Weekend             4543.40  \n",
              "7                 33.48     Weekend             5503.54  \n",
              "8                 14.94     Weekend             5043.68  \n",
              "9                 25.19     Weekend             5990.45  \n",
              "10                20.61     Weekday             2556.43  \n",
              "11                25.16     Weekday             4978.12  \n",
              "12                21.26     Weekday             6544.77  \n",
              "13                24.05     Weekend             5094.18  \n",
              "14                15.94     Weekday             6667.79  \n",
              "15                22.73     Weekday             3928.83  \n",
              "16                15.76     Weekday             4165.87  \n",
              "17                31.78     Weekend             7000.00  \n",
              "18                17.98     Weekend             5941.62  \n",
              "19                22.79     Weekday             5669.67  "
            ]
          },
          "execution_count": 92,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Генерация 20 новых записей\n",
        "np.random.seed(42)\n",
        "n_new = 20\n",
        "\n",
        "building_types = df[\"Building Type\"].unique()\n",
        "day_of_week = df[\"Day of Week\"].unique()\n",
        "sq_min, sq_max = df[\"Square Footage\"].min(), df[\"Square Footage\"].max()\n",
        "occ_min, occ_max = df[\"Number of Occupants\"].min(), df[\"Number of Occupants\"].max()\n",
        "app_min, app_max = df[\"Appliances Used\"].min(), df[\"Appliances Used\"].max()\n",
        "temp_min, temp_max = df[\"Average Temperature\"].min(), df[\"Average Temperature\"].max()\n",
        "y_mean, y_std = df[\"Energy Consumption\"].mean(), df[\"Energy Consumption\"].std()\n",
        "\n",
        "new_rows = []\n",
        "for _ in range(n_new):\n",
        "    bt = np.random.choice(building_types)\n",
        "    dow = np.random.choice(day_of_week)\n",
        "    sq = np.random.uniform(sq_min, sq_max)\n",
        "    occ = int(np.random.uniform(occ_min, occ_max + 1))\n",
        "    app = int(np.random.uniform(app_min, app_max + 1))\n",
        "    temp = np.random.uniform(temp_min, temp_max)\n",
        "    # Правдоподобное энергопотребление: линейная комбинация признаков + шум в масштабе y_std\n",
        "    energy = 0.05 * sq + 20 * occ + 30 * app + 50 * temp + np.random.normal(y_mean * 0.2, y_std * 0.3)\n",
        "    energy = max(1500, min(7000, energy))  # в разумных границах\n",
        "    new_rows.append({\n",
        "        \"Building Type\": bt, \"Square Footage\": sq, \"Number of Occupants\": occ,\n",
        "        \"Appliances Used\": app, \"Average Temperature\": round(temp, 2), \"Day of Week\": dow,\n",
        "        \"Energy Consumption\": round(energy, 2)\n",
        "    })\n",
        "\n",
        "df_new = pd.DataFrame(new_rows)\n",
        "df_new"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 93,
      "id": "53f17cc6",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Размер до: 1000 после: 1020\n"
          ]
        }
      ],
      "source": [
        "# Объединяем исходные данные и 20 новых записей\n",
        "df_extended = pd.concat([df_model, df_new], ignore_index=True)\n",
        "print(\"Размер до:\", len(df_model), \"после:\", len(df_extended))\n",
        "X_ext = df_extended.drop(columns=[\"Energy Consumption\"])\n",
        "y_ext = df_extended[\"Energy Consumption\"]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 94,
      "id": "5bea9f00",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>model</th>\n",
              "      <th>split</th>\n",
              "      <th>MAE</th>\n",
              "      <th>RMSE</th>\n",
              "      <th>R2</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>LinearRegression</td>\n",
              "      <td>train</td>\n",
              "      <td>35.939594</td>\n",
              "      <td>138.575984</td>\n",
              "      <td>0.978559</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>LinearRegression</td>\n",
              "      <td>test</td>\n",
              "      <td>19.108061</td>\n",
              "      <td>23.788196</td>\n",
              "      <td>0.999175</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>RandomForest</td>\n",
              "      <td>train</td>\n",
              "      <td>40.832184</td>\n",
              "      <td>72.347452</td>\n",
              "      <td>0.994156</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>RandomForest</td>\n",
              "      <td>test</td>\n",
              "      <td>91.188920</td>\n",
              "      <td>117.337753</td>\n",
              "      <td>0.979936</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>GradientBoosting</td>\n",
              "      <td>train</td>\n",
              "      <td>56.667122</td>\n",
              "      <td>101.997400</td>\n",
              "      <td>0.988384</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>5</th>\n",
              "      <td>GradientBoosting</td>\n",
              "      <td>test</td>\n",
              "      <td>74.311407</td>\n",
              "      <td>97.239319</td>\n",
              "      <td>0.986221</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "              model  split        MAE        RMSE        R2\n",
              "0  LinearRegression  train  35.939594  138.575984  0.978559\n",
              "1  LinearRegression   test  19.108061   23.788196  0.999175\n",
              "2      RandomForest  train  40.832184   72.347452  0.994156\n",
              "3      RandomForest   test  91.188920  117.337753  0.979936\n",
              "4  GradientBoosting  train  56.667122  101.997400  0.988384\n",
              "5  GradientBoosting   test  74.311407   97.239319  0.986221"
            ]
          },
          "execution_count": 94,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Обучаем модели на расширенной выборке и собираем метрики\n",
        "results_after = evaluate_models(X_ext, y_ext, X_test, y_test, models)\n",
        "results_after"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 95,
      "id": "90d16f0d",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>MAE_before</th>\n",
              "      <th>MAE_after</th>\n",
              "      <th>RMSE_before</th>\n",
              "      <th>RMSE_after</th>\n",
              "      <th>R2_before</th>\n",
              "      <th>R2_after</th>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>model</th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>LinearRegression</th>\n",
              "      <td>0.012162</td>\n",
              "      <td>19.108061</td>\n",
              "      <td>0.014197</td>\n",
              "      <td>23.788196</td>\n",
              "      <td>1.000000</td>\n",
              "      <td>0.999175</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>RandomForest</th>\n",
              "      <td>93.290891</td>\n",
              "      <td>91.188920</td>\n",
              "      <td>118.888277</td>\n",
              "      <td>117.337753</td>\n",
              "      <td>0.979403</td>\n",
              "      <td>0.979936</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>GradientBoosting</th>\n",
              "      <td>65.365958</td>\n",
              "      <td>74.311407</td>\n",
              "      <td>83.840513</td>\n",
              "      <td>97.239319</td>\n",
              "      <td>0.989757</td>\n",
              "      <td>0.986221</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "                  MAE_before  MAE_after  RMSE_before  RMSE_after  R2_before  \\\n",
              "model                                                                         \n",
              "LinearRegression    0.012162  19.108061     0.014197   23.788196   1.000000   \n",
              "RandomForest       93.290891  91.188920   118.888277  117.337753   0.979403   \n",
              "GradientBoosting   65.365958  74.311407    83.840513   97.239319   0.989757   \n",
              "\n",
              "                  R2_after  \n",
              "model                       \n",
              "LinearRegression  0.999175  \n",
              "RandomForest      0.979936  \n",
              "GradientBoosting  0.986221  "
            ]
          },
          "execution_count": 95,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Сравнение метрик на тесте (test_energy_data.csv): ДО и ПОСЛЕ добавления 20 записей\n",
        "# Оба варианта оценивались на одной и той же тестовой выборке из файла\n",
        "tb = results_before[results_before[\"split\"] == \"test\"].set_index(\"model\")\n",
        "ta = results_after[results_after[\"split\"] == \"test\"].set_index(\"model\")\n",
        "comparison = pd.DataFrame({\n",
        "    \"MAE_before\": tb[\"MAE\"],\n",
        "    \"MAE_after\": ta[\"MAE\"],\n",
        "    \"RMSE_before\": tb[\"RMSE\"],\n",
        "    \"RMSE_after\": ta[\"RMSE\"],\n",
        "    \"R2_before\": tb[\"R2\"],\n",
        "    \"R2_after\": ta[\"R2\"]\n",
        "})\n",
        "comparison"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a5852867",
      "metadata": {},
      "source": [
        "### Анализ изменений в точности моделей\n",
        "\n",
        "- Добавление 20 новых записей, сгенерированных в тех же диапазонах признаков и с правдоподобной целевой переменной, все же снижает качество работы моделей: модель которая не использует в обучении сгенерированные данные, показывает меньшую ошибку на тестовых данных, но эффект выражен несильно, т.к. данных совсем мало.\n",
        "- Для корректного сравнения метрики считаются на одной и той же тестовой выборке из файла `test_energy_data.csv`."
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": ".venv (3.14.2)",
      "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.14.2"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}
