diff --git "a/.ipynb_checkpoints/EX03_Classic_ML_Rostislav_Golubev (1)-checkpoint.ipynb" "b/.ipynb_checkpoints/EX03_Classic_ML_Rostislav_Golubev (1)-checkpoint.ipynb" new file mode 100644--- /dev/null +++ "b/.ipynb_checkpoints/EX03_Classic_ML_Rostislav_Golubev (1)-checkpoint.ipynb" @@ -0,0 +1,3032 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "VqZ9BtJnwear" + }, + "source": [ + "# Задание 1. Bootstrap" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2jZ6d3Owweau" + }, + "source": [ + "В этом задании используйте датасет [Breast Cancer 🛠️[doc]](https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_breast_cancer.html) — классический датасет для задачи бинарной классификации. Обучите модели:\n", + "\n", + " - `DecisionTreeClassifier`\n", + " - `RandomForestClassifier`\n", + " - `LGBMClassifier`\n", + " - `SVC`\n", + " - `BaggingClassifier` с базовым класификатором `SVC`.\n", + "\n", + "Параметры моделей можете оставить по умолчанию или задать сами.\n", + "\n", + "Для каждой модели посчитайте [корреляцию Мэтьюса 📚[wiki]](https://en.wikipedia.org/wiki/Phi_coefficient) — метрику для оценки качества бинарной классификации, в частности, устойчивую к дисбалансу классов, (`sklearn.metrics.matthews_corrcoef` [🛠️[doc]](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.matthews_corrcoef.html) для предсказанного ею класса и реального. Подробнее почитать про его пользу можно в статье:\n", + "\n", + "[[article] 🎓 The advantages of the Matthews correlation coefficient (MCC) over F1 score and accuracy in binary classification evaluation](https://bmcgenomics.biomedcentral.com/articles/10.1186/s12864-019-6413-7)\n", + "\n", + "С помощью bootstrap-подхода постройте 90% доверительные интервалы для качества полученных моделей. Используйте функцию `bootstrap_metric()` из лекции.\n", + "\n", + "Постройте [боксплоты 🛠️[doc]](https://seaborn.pydata.org/generated/seaborn.boxplot.html) для качества полученных моделей." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Nan68aZIweaw" + }, + "source": [ + "Установка и импорт необходимых библиотек:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "EobqrBMqweax", + "outputId": "44e71e9b-ca42-4128-f9bb-d8c982586514" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m242.6/242.6 kB\u001b[0m \u001b[31m6.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mta \u001b[36m0:00:01\u001b[0m\n", + "\u001b[?25h" + ] + } + ], + "source": [ + "!pip install -q dask[dataframe]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "rNK2PHixweaz" + }, + "outputs": [], + "source": [ + "import lightgbm\n", + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "import sklearn.datasets\n", + "import matplotlib.pyplot as plt\n", + "\n", + "from sklearn.svm import SVC\n", + "from sklearn.metrics import matthews_corrcoef\n", + "from sklearn.tree import DecisionTreeClassifier\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.ensemble import RandomForestClassifier, BaggingClassifier" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c914Tk78wea0" + }, + "source": [ + "Загрузка датасета:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "nA-lRHUTwea0", + "jupyter": { + "outputs_hidden": true + }, + "outputId": "6735dae2-ad75-4dc4-b9c3-d3cc248e6a44" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ".. _breast_cancer_dataset:\n", + "\n", + "Breast cancer wisconsin (diagnostic) dataset\n", + "--------------------------------------------\n", + "\n", + "**Data Set Characteristics:**\n", + "\n", + ":Number of Instances: 569\n", + "\n", + ":Number of Attributes: 30 numeric, predictive attributes and the class\n", + "\n", + ":Attribute Information:\n", + " - radius (mean of distances from center to points on the perimeter)\n", + " - texture (standard deviation of gray-scale values)\n", + " - perimeter\n", + " - area\n", + " - smoothness (local variation in radius lengths)\n", + " - compactness (perimeter^2 / area - 1.0)\n", + " - concavity (severity of concave portions of the contour)\n", + " - concave points (number of concave portions of the contour)\n", + " - symmetry\n", + " - fractal dimension (\"coastline approximation\" - 1)\n", + "\n", + " The mean, standard error, and \"worst\" or largest (mean of the three\n", + " worst/largest values) of these features were computed for each image,\n", + " resulting in 30 features. For instance, field 0 is Mean Radius, field\n", + " 10 is Radius SE, field 20 is Worst Radius.\n", + "\n", + " - class:\n", + " - WDBC-Malignant\n", + " - WDBC-Benign\n", + "\n", + ":Summary Statistics:\n", + "\n", + "===================================== ====== ======\n", + " Min Max\n", + "===================================== ====== ======\n", + "radius (mean): 6.981 28.11\n", + "texture (mean): 9.71 39.28\n", + "perimeter (mean): 43.79 188.5\n", + "area (mean): 143.5 2501.0\n", + "smoothness (mean): 0.053 0.163\n", + "compactness (mean): 0.019 0.345\n", + "concavity (mean): 0.0 0.427\n", + "concave points (mean): 0.0 0.201\n", + "symmetry (mean): 0.106 0.304\n", + "fractal dimension (mean): 0.05 0.097\n", + "radius (standard error): 0.112 2.873\n", + "texture (standard error): 0.36 4.885\n", + "perimeter (standard error): 0.757 21.98\n", + "area (standard error): 6.802 542.2\n", + "smoothness (standard error): 0.002 0.031\n", + "compactness (standard error): 0.002 0.135\n", + "concavity (standard error): 0.0 0.396\n", + "concave points (standard error): 0.0 0.053\n", + "symmetry (standard error): 0.008 0.079\n", + "fractal dimension (standard error): 0.001 0.03\n", + "radius (worst): 7.93 36.04\n", + "texture (worst): 12.02 49.54\n", + "perimeter (worst): 50.41 251.2\n", + "area (worst): 185.2 4254.0\n", + "smoothness (worst): 0.071 0.223\n", + "compactness (worst): 0.027 1.058\n", + "concavity (worst): 0.0 1.252\n", + "concave points (worst): 0.0 0.291\n", + "symmetry (worst): 0.156 0.664\n", + "fractal dimension (worst): 0.055 0.208\n", + "===================================== ====== ======\n", + "\n", + ":Missing Attribute Values: None\n", + "\n", + ":Class Distribution: 212 - Malignant, 357 - Benign\n", + "\n", + ":Creator: Dr. William H. Wolberg, W. Nick Street, Olvi L. Mangasarian\n", + "\n", + ":Donor: Nick Street\n", + "\n", + ":Date: November, 1995\n", + "\n", + "This is a copy of UCI ML Breast Cancer Wisconsin (Diagnostic) datasets.\n", + "https://goo.gl/U2Uwz2\n", + "\n", + "Features are computed from a digitized image of a fine needle\n", + "aspirate (FNA) of a breast mass. They describe\n", + "characteristics of the cell nuclei present in the image.\n", + "\n", + "Separating plane described above was obtained using\n", + "Multisurface Method-Tree (MSM-T) [K. P. Bennett, \"Decision Tree\n", + "Construction Via Linear Programming.\" Proceedings of the 4th\n", + "Midwest Artificial Intelligence and Cognitive Science Society,\n", + "pp. 97-101, 1992], a classification method which uses linear\n", + "programming to construct a decision tree. Relevant features\n", + "were selected using an exhaustive search in the space of 1-4\n", + "features and 1-3 separating planes.\n", + "\n", + "The actual linear program used to obtain the separating plane\n", + "in the 3-dimensional space is that described in:\n", + "[K. P. Bennett and O. L. Mangasarian: \"Robust Linear\n", + "Programming Discrimination of Two Linearly Inseparable Sets\",\n", + "Optimization Methods and Software 1, 1992, 23-34].\n", + "\n", + "This database is also available through the UW CS ftp server:\n", + "\n", + "ftp ftp.cs.wisc.edu\n", + "cd math-prog/cpo-dataset/machine-learn/WDBC/\n", + "\n", + ".. dropdown:: References\n", + "\n", + " - W.N. Street, W.H. Wolberg and O.L. Mangasarian. Nuclear feature extraction\n", + " for breast tumor diagnosis. IS&T/SPIE 1993 International Symposium on\n", + " Electronic Imaging: Science and Technology, volume 1905, pages 861-870,\n", + " San Jose, CA, 1993.\n", + " - O.L. Mangasarian, W.N. Street and W.H. Wolberg. Breast cancer diagnosis and\n", + " prognosis via linear programming. Operations Research, 43(4), pages 570-577,\n", + " July-August 1995.\n", + " - W.H. Wolberg, W.N. Street, and O.L. Mangasarian. Machine learning techniques\n", + " to diagnose breast cancer from fine-needle aspirates. Cancer Letters 77 (1994)\n", + " 163-171.\n", + "\n" + ] + } + ], + "source": [ + "breast_cancer = sklearn.datasets.load_breast_cancer()\n", + "print(breast_cancer.DESCR)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "PMzugGlGwea0" + }, + "outputs": [], + "source": [ + "x = breast_cancer.data\n", + "y = breast_cancer.target\n", + "x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=42)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "TxFinYhZ_PIS", + "outputId": "930146d8-42b0-48a3-e400-5ec67724ad28" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[1.799e+01, 1.038e+01, 1.228e+02, 1.001e+03, 1.184e-01, 2.776e-01,\n", + " 3.001e-01, 1.471e-01, 2.419e-01, 7.871e-02, 1.095e+00, 9.053e-01,\n", + " 8.589e+00, 1.534e+02, 6.399e-03, 4.904e-02, 5.373e-02, 1.587e-02,\n", + " 3.003e-02, 6.193e-03, 2.538e+01, 1.733e+01, 1.846e+02, 2.019e+03,\n", + " 1.622e-01, 6.656e-01, 7.119e-01, 2.654e-01, 4.601e-01, 1.189e-01],\n", + " [2.057e+01, 1.777e+01, 1.329e+02, 1.326e+03, 8.474e-02, 7.864e-02,\n", + " 8.690e-02, 7.017e-02, 1.812e-01, 5.667e-02, 5.435e-01, 7.339e-01,\n", + " 3.398e+00, 7.408e+01, 5.225e-03, 1.308e-02, 1.860e-02, 1.340e-02,\n", + " 1.389e-02, 3.532e-03, 2.499e+01, 2.341e+01, 1.588e+02, 1.956e+03,\n", + " 1.238e-01, 1.866e-01, 2.416e-01, 1.860e-01, 2.750e-01, 8.902e-02],\n", + " [1.969e+01, 2.125e+01, 1.300e+02, 1.203e+03, 1.096e-01, 1.599e-01,\n", + " 1.974e-01, 1.279e-01, 2.069e-01, 5.999e-02, 7.456e-01, 7.869e-01,\n", + " 4.585e+00, 9.403e+01, 6.150e-03, 4.006e-02, 3.832e-02, 2.058e-02,\n", + " 2.250e-02, 4.571e-03, 2.357e+01, 2.553e+01, 1.525e+02, 1.709e+03,\n", + " 1.444e-01, 4.245e-01, 4.504e-01, 2.430e-01, 3.613e-01, 8.758e-02]])" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x[:3]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "GJ6iCg4Awea1" + }, + "outputs": [], + "source": [ + "# Your code here\n", + "DTC = DecisionTreeClassifier(random_state = 42)\n", + "DTC.fit(x_train, y_train)\n", + "dtc_pred = DTC.predict(x_test)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "E_tUhJkWA74e", + "outputId": "bcad98fe-9205-4206-9d73-6bed18cc0316" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.8963356530877563" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matthews_corrcoef(y_pred=dtc_pred, y_true=y_test)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "rN_GrSMbA7DU" + }, + "outputs": [], + "source": [ + "RFC = RandomForestClassifier(max_depth=None,)\n", + "RFC.fit(x_train, y_train)\n", + "rfc_pred = RFC.predict(x_test)\n", + "\n", + "LGMBC = lightgbm.LGBMClassifier(n_estimators=2000,\n", + " learning_rate=0.1,\n", + " max_depth=-1,\n", + " num_leaves=2**5,\n", + " random_state=42,\n", + " min_child_weight=13,\n", + " n_jobs=-1,\n", + " force_col_wise=True,\n", + " verbose=-1,)\n", + "LGMBC.fit(X=x_train, y=y_train)\n", + "lgbmc_pred = LGMBC.predict(x_test)\n", + "\n", + "svc = SVC()\n", + "svc.fit(x_train, y_train)\n", + "svc_pred = svc.predict(X=x_test)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "C0itI8YNBdZD" + }, + "outputs": [], + "source": [ + "BagC_SVC = BaggingClassifier(estimator=SVC())\n", + "BagC_SVC.fit(x_train, y_train)\n", + "bagc_pred = BagC_SVC.predict(x_test)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "hEvTzHOdCh3A" + }, + "outputs": [], + "source": [ + "def bootstrap_metric(y_true, y_pred, metric_fn, samples_cnt=1000, random_state=42):\n", + " np.random.seed(random_state)\n", + " b_metric = np.zeros(samples_cnt)\n", + " for i in range(samples_cnt):\n", + " poses = np.random.choice(y_true.shape[0], size=y_true.shape[0], replace=True)\n", + "\n", + " y_true_boot = y_true[poses]\n", + " y_pred_boot = y_pred[poses]\n", + " m_val = metric_fn(y_true_boot, y_pred_boot)\n", + " b_metric[i] = m_val\n", + "\n", + " return b_metric" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "o5Rps5hoB4Jg" + }, + "outputs": [], + "source": [ + "boot_dtc = bootstrap_metric(y_test, dtc_pred, metric_fn=matthews_corrcoef)\n", + "boot_rfc = bootstrap_metric(y_test, rfc_pred, metric_fn=matthews_corrcoef)\n", + "boot_lgbmc = bootstrap_metric(y_test, lgbmc_pred, metric_fn=matthews_corrcoef)\n", + "boot_bagc = bootstrap_metric(y_test, bagc_pred, metric_fn=matthews_corrcoef)\n", + "boot_svc = bootstrap_metric(y_test, svc_pred, metric_fn=matthews_corrcoef)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 536 + }, + "id": "yXCp7ZejDAQ2", + "outputId": "b25060af-c33e-4210-aba5-9e2244193b91" + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABUIAAAIHCAYAAABaCSZcAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAACMUklEQVR4nOzdeVyU5f7/8fcwCLiwKC5gGorHFlFyKQszyTTRSrPMrdCs9FR4Wk7WOV8pMZeDebLTJtpJSw0zlyyzzK1UMsE2TcQWTQgtRYEE3NHh/v3hjzlMLA4MOMzwej4e80ju+7rv63ObFwzvue77MhmGYQgAAAAAAAAA3JiHswsAAAAAAAAAgJpGEAoAAAAAAADA7RGEAgAAAAAAAHB7BKEAAAAAAAAA3B5BKAAAAAAAAAC3RxAKAAAAAAAAwO0RhAIAAAAAAABwe57OLqCuKyoq0qFDh+Tr6yuTyeTscgAAAAAAAACXYhiGjh8/rpYtW8rDo/x5nwShTnbo0CG1bt3a2WUAAAAAAAAALu3gwYNq1apVufsJQp3M19dX0oX/UX5+fk6uBgAAAAAAAHAtBQUFat26tTVnKw9BqJMV3w7v5+dHEAoAAAAAAABU0cUeO8liSQAAAAAAAADcHkEoAAAAAAAAALdHEAoAAAAAAADA7RGEAgAAAAAAAHB7BKEAAAAAAAAA3B5BKAAAAAAAAAC3RxAKAAAAAAAAwO0RhAIAAAAAAABwewShAAAAAAAAANweQSgAAAAAAAAAt0cQCgAAAAAAAMDtEYQCAAAAAAAAcHsuG4QuXrxYDz/8sK699lp5e3vLZDJp4cKFlT5PUVGRXn/9dXXq1En169dXs2bNNHLkSKWnp5d7zPr16xUZGSlfX1/5+fmpd+/e+vzzzx24GgAAAAAAAAA1ydPZBVTVc889p8zMTDVt2lTBwcHKzMys0nkefvhhzZ8/X2FhYXr88cd16NAhLV++XBs2bND27dvVvn17m/aLFy/WqFGj1KxZM40ZM0aStGzZMt16661avny57rnnHkcvDQAAAABQwwoLC7Vq1SodOnRILVu21ODBg+Xl5eXssgBUA8Y3ymMyDMNwdhFV8dlnn6l9+/YKCQnRCy+8oIkTJ2rBggXWcNIemzdv1i233KJevXpp48aN1kGxdu1a3XbbberXr5/Wr19vbX/s2DGFhobK09NTO3fuVKtWrSRJv/32m7p06SJJSk9Pl6+vr901FBQUyN/fX/n5+fLz87P7OAAAAABA1cyZM0crVqyQxWKxbjObzRo6dKhiYmKcWBkARzG+6yZ78zWXvTW+b9++CgkJcegc8+bNkyRNmzbN5pOBAQMG6Oabb9aGDRt04MAB6/YVK1YoLy9Pjz32mDUElaRWrVrpb3/7m3JycvThhx86VBMAAAAAoObMmTNHS5culZ+fn5555hl9+OGHeuaZZ+Tn56elS5dqzpw5zi4RQBUxvnExLhuEVoctW7aoYcOGuvHGG0vti4qKkiQlJSXZtJekfv362dUeAAAAAFB7FBYWasWKFWrcuLFWrlypgQMHKjAwUAMHDtTKlSvVuHFjrVixQoWFhc4uFUAlMb5hD5d9RqijTp48qcOHD6tjx44ym82l9hc/G3Tfvn3WbcV//vNzQ8trX5azZ8/q7Nmz1q8LCgoqXzwAuJEzZ85U+TnPqBkhISHy8fFxdhlwA4zv2ofxjbpu1apVslgsGjt2rDw9bX8d9vT01EMPPaRZs2Zp1apVGjZsmJOqBFAVjG/Yo84Gofn5+ZIkf3//MvcXP0+guN3FjimrfVlmzJihKVOmVL5gAHBTmZmZGjdunLPLQAnz5s3TlVde6ewy4AYY37UP4xt13aFDhyRJPXr0KHN/8fbidgBcB+Mb9qizQaizTJw4UU899ZT164KCArVu3dqJFQGAc4WEhFif2ezKMjMzNX36dD333HMOP8Pa2Vy9ftQejO/ax9XrBxzVsmVLSVJycrIGDhxYan9ycrJNOwCug/ENe9TZILR4Vmd5MziLb1kvOfuz5DGBgYEXbV8Wb29veXt7V61oAHBDPj4+bjU7KSQkxK2uB3AE4xtAbTN48GDNnTtX8+fP14ABA2xunz1//rzeeustmc1mDR482HlFAqgSxjfsUWcXS2rYsKGCg4OVkZEhi8VSan9ZzwOt6DmgFT0/FAAAAADgfF5eXho6dKiOHTumIUOGaPXq1crJydHq1as1ZMgQHTt2TEOHDpWXl5ezSwVQSYxv2KPOzgiVpMjISC1dulTbtm1Tr169bPatX79ekmy2R0ZG6r333tOGDRt0ww03lNk+MjKyhqsGAAAAAFRVTEyMJGnFihWaNWuWdbvZbNaIESOs+wG4HsY3LqZOBKE5OTnKyclR06ZN1bRpU+v2v/71r1q6dKkmTZqkjRs3Wj8VWLt2rbZs2aJ+/frZPEdp2LBh+uc//6nXX39dDz74oFq1aiVJ+u233zR79mw1bdpUd91116W9OAAAAABApcTExGjs2LFatWqVDh06pJYtW2rw4MHMFAPcAOMbFXHZIHT+/Pn68ssvJUm7d++2btuyZYskqWfPnho7dqwkafbs2ZoyZYomT56s559/3nqO3r17a+zYsZo/f766du2q22+/XYcPH9ayZcvUpEkTvf766zZ9Nm7cWLNnz9aoUaPUtWtXDR8+XJK0bNky5ebmatmyZfL19a3hKwcAAAAAOMrLy0vDhg1zdhkAagDjG+Vx2SD0yy+/1KJFi2y2bdu2Tdu2bbN+XRyEVuS///2vOnXqpDfffFOvvvqqGjVqpLvuukv/+te/1K5du1Lto6Oj1bRpU8XHx2vBggUymUzq1q2bnnvuOfXt29fxCwMAAAAAAABQ7UyGYRjOLqIuKygokL+/v/Lz8+Xn5+fscgAAVfTzzz9r3LhxmjdvHqtKA26G8Q0AAFC72Zuv1dlV4wEAAAAAAADUHQShAAAAAAAAANweQSgAAAAAAAAAt0cQCgAAAAAAAMDtEYQCAAAAAAAAcHsEoQAAAAAAAADcHkEoAAAAAAAAALdHEAoAAAAAAADA7RGEAgAAAAAAAHB7BKEAAAAAAAAA3B5BKAAAAAAAAAC3RxAKAAAAAAAAwO0RhAIAAAAAAABwewShAAAAAAAAANyep7MLAOxx5swZZWZmOrsMlBASEiIfHx9nlwEAAAAAAGAXglC4hMzMTI0bN87ZZaCEefPm6corr3R2GQAAAHACJirUPkxUQHVhfNc+jO/qQxAKlxASEqJ58+Y5uwyHZWZmavr06XruuecUEhLi7HIc4ur1AwAAoOqYqFD7MFEB1YXxXfswvqsPQShcgo+Pj1sN+pCQELe6HgAAANQtTFSofVy9ftQejO/ax9Xrr00IQgEAAAAAlcJEBcB9Mb7hzlg1HgAAAAAAAIDbIwgFAAAAAAAA4PYIQgEAAAAAAAC4PYJQAAAAAAAAAG6PIBQAAAAAAACA2yMIBQAAAAAAAOD2CEIBAAAAAAAAuD2CUAAAAAAAAABujyAUAAAAAAAAgNsjCAUAAAAAAADg9ghCAQAAAAAAALg9glAAAAAAAAAAbo8gFAAAAAAAAIDbIwgFAAAAAAAA4PYIQgEAAAAAAAC4PYJQAAAAAAAAAG6PIBQAAAAAAACA2yMIBQAAAAAAAOD2CEIBAAAAAAAAuD2CUAAAAAAAAABujyAUAAAAAAAAgNsjCAUAAAAAAADg9ghCAQAAAAAAALg9glAAAAAAAAAAbo8gFAAAAAAAAIDbIwgFAAAAAAAA4PYIQgEAAAAAAAC4PYJQAAAAAAAAAG6PIBQAAAAAAACA2yMIBQAAAAAAAOD2CEIBAAAAAAAAuD2CUAAAAAAAAABujyAUAAAAAAAAgNsjCAUAAAAAAADg9ghCAQAAAAAAALg9glAAAAAAAAAAbo8gFAAAAAAAAIDbIwgFAAAAAAAA4PYIQgEAAAAAAAC4PYJQAAAAAAAAAG6PIBQAAAAAAACA2yMIBQAAAAAAAOD2CEIBAAAAAAAAuD2CUAAAAAAAAABujyAUAAAAAAAAgNsjCAUAAAAAAADg9ghCAQAAAAAAALg9glAAAAAAAAAAbo8gFAAAAAAAAIDbIwgFAAAAAAAA4PZcOgj95ptvdNtttykgIEANGzbUDTfcoOXLl1fqHD/++KPuu+8+BQUFydvbWyEhIXriiSf0xx9/lNneZDKV+xozZkw1XBUAAAAAAACA6ubp7AKqavPmzYqKipKPj49GjBghX19frVy5UsOHD9fBgwc1YcKEi55j+/bt6tu3r06fPq0777xT7dq10/fff6/XXntN69atU3JysgIDA0sdFxISUmbo2blz52q4MgAAAOnIkSPKy8tzdhmQlJmZafNfOFdAQIBatGjh7DIAAIALcskg9Pz58xo3bpw8PDz0xRdfWAPIuLg4de/eXbGxsbrnnnsUEhJS4XnGjRunkydP6qOPPtKgQYOs21988UX94x//0LPPPqs33nij1HFt2rTR888/X52XBAAAYHXkyBHdF32fCs8WOrsUlDB9+nRnlwBJXt5eenfxu4ShAACg0lwyCN20aZP279+vBx54wGYWpr+/v2JjYzVmzBgtWrRIcXFx5Z5j//79SktL03XXXWcTgkrShAkTNHPmTCUmJuqll15Sw4YNa+pSAAAASsnLy1Ph2UIVdS+S4Wc4uxyg1jAVmFT4daHy8vIIQgEAQKW5ZBC6ZcsWSVK/fv1K7YuKipIkJSUlVXiOrKwsSVLbtm1L7fPw8NDll1+unTt3avv27erTp4/N/ry8PL355pvKyclRkyZNdOONN6pTp05VuRQAcAi3ztYe3Dpbu7jLrbOGnyE1dnYVQO1hiA8GAABA1blkELpv3z5JUvv27UvtCwoKUqNGjaxtytO0aVNJUkZGRql9RUVFOnDggCRp7969pYLQXbt26eGHH7bZ1r9/fy1atEjNmzevsN+zZ8/q7Nmz1q8LCgoqbA8A5Tly5Iii77tPZwu5dbY24dbZ2sHby0uL3+XWWQAAAAD/45JBaH5+vqQLt8KXxc/Pz9qmPFdccYVCQ0P1zTffaM2aNbr99tut+1555RXl5uZKUqmZVhMmTNCQIUN0xRVXyMvLS2lpaZo2bZrWrl2rO+64QykpKTKbzeX2O2PGDE2ZMsWeywSACuXl5elsYaEeDTuplg0tzi4HqDUOnTRr7h5x6ywAAAAAGy4ZhFYHk8mkOXPmaODAgRo0aJAGDx6sdu3aadeuXdqwYYM6deqk3bt3y8PDw+a4WbNm2XwdERGhTz75RLfccouSkpL00Ucf6e677y6334kTJ+qpp56yfl1QUKDWrVtX78UBqFNaNrSorR9BKAAAAAAAFfG4eJPap3gmaHmzPgsKCsqdLVpSVFSUtm7dqgEDBmjTpk167bXXlJubqw8//FCRkZGSdNFb3aULzxQdN26cJGnbtm0VtvX29pafn5/NCwAAAAAAAEDNcskZocXPBt23b5+6detmsy8rK0snTpxQ9+7d7TrX9ddfr08++aTU9ldeeUWSdO2119p1nuJnjp48edKu9gAAAAAAAAAuHZecEVo8W3PDhg2l9q1fv96mTVVkZmbqyy+/VIcOHexeDf6rr76SJLVp06bK/QIAAAAAAACoGS4ZhPbp00ehoaFasmSJvv/+e+v2/Px8xcfHy8vLS6NHj7ZuP3z4sH766adSt9KfOHFChmHYbMvPz9eoUaNksVg0Y8YMm327d+/WuXPnStWTnJysmTNnql69eho6dGg1XCEAAAAAAACA6uSSt8Z7enpq/vz5ioqKUq9evTRixAj5+vpq5cqVyszM1KxZs2xmZk6cOFGLFi3SggULNGbMGOv2VatWKTY2Vrfccotatmypo0ePavXq1crOzta0adM0aNAgm35feuklrVmzRj179lTr1q1Vr1497dmzRxs2bJDJZFJCQoLatWt3if4WAAAAAAAAANjLJYNQSerdu7e+/PJLTZ48WcuWLdO5c+fUqVMnzZw5U8OHD7frHJ06ddI111yjDRs2KCcnR/7+/rrhhhv01FNPqXfv3qXa33nnncrLy9OuXbu0ceNGFRYWKigoSCNGjNCTTz5p93NJAQAAAAAAAFxaLhuESlL37t21du3ai7ZbuHChFi5cWGr7Nddco48//tju/u666y7dddddlSkRAAAAAAAAQC3gks8IBQAAAAAAAIDKIAgFAAAAAAAA4PYIQgEAAAAAAAC4PYJQAAAAAAAAAG6PIBQAAAAAAACA2yMIBQAAAAAAAOD2CEIBAAAAAAAAuD2CUAAAAAAAAABujyAUAAAAAAAAgNsjCAUAAAAAAADg9ghCAQAAAAAAALg9glAAAAAAAAAAbo8gFAAAAAAAAIDbIwgFAAAAAAAA4PYIQgEAAAAAAAC4PYJQAAAAAAAAAG6PIBQAAAAAAACA2yMIBQAAAAAAAOD2CEIBAAAAAAAAuD2CUAAAAAAAAABujyAUAAAAAAAAgNsjCAUAAAAAAADg9ghCAQAAAAAAALg9glAAAAAAAAAAbo8gFAAAAAAAAIDbIwgFAAAAAAAA4PYIQgEAAAAAAAC4PYJQAAAAAAAAAG7P09kFAAAcc+gkn2kBJbnVmChwdgFALcOYAAAADnAoCH3wwQclSQMGDNDQoUOrpSBUvyNHjigvL8/ZZUBSZmamzX/hXAEBAWrRooWzy3DY3D2NnF0CgBpi/trs7BIAAAAAt+FQELpo0SJJ0vDhw6ulGFS/I0eO6L77olVYeNbZpaCE6dOnO7sESPLy8ta77y52+TD00bATatmwyNllALXGoZMebvMBgaW7RfJzdhVALVLABwQAAKDqHApCmzVrpuzsbJcPEdxZXl6eCgvP6ky7m2XUD3B2OUCtYTqdJ+3fory8PJf/HtayYZHa+lmcXQaAmuAnqbGziwAAAADcg0NBaIcOHZSUlKTMzEx17ty5mkpCTTDqB6ioYVNnlwHUGm70BEEAAAAAAGAHh7KA6OhoGYZhvUUeAAAAAAAAAGojh4LQBx54QH369NFHH32k559/XoZhVFddAAAAAAAAAFBtHLo1fuvWrXr66aeVnZ2tadOmadmyZRo+fLjCw8PVuHFjmc0VP8i8V69ejnQPAAAAAC7nyJEjysvLc3YZkJSZmWnzXzhXQECAyz+/n/FdezC+a5faMr4dCkJvvvlmmUwm69d79+7VtGnT7DrWZDLp/PnzjnQPAAAAAC7lyJEjir7vPp0tLHR2KShh+vTpzi4Bkry9vLT43XdrRVhSFRfGd7TOFp51dikogfFdO3h7eWvxu4udPr4dCkIlcTs8AAAAANgpLy9PZwsLdY+kZs4uBqhFsiW9X1iovLw8pwclVXVhfJ/V9aG3y88n0NnlALVGwZlcfZW+plaMb4eC0M2bN1dXHQAAAABQZzST1FKmi7YD6g73mWTl5xOoxg1dM8wF3J1DQWhkZGR11QEAAAAAAAAANcahIPTBBx+UJA0YMEBDhw6tloIAAAAAAAAAoLo5FIQuWrRIkjR8+PBqKQYAAAAAAAAAaoKHIwc3a3bh8d7OftApAAAAAAAAAFTEoSC0Q4cOkqTMzMxqKQYAAAAAAAAAaoJDQWh0dLQMw7DeIg8AAAAAAAAAtZFDQegDDzygPn366KOPPtLzzz8vwzCqqy4AAAAAAAAAqDYOLZa0detWPf3008rOzta0adO0bNkyDR8+XOHh4WrcuLHMZnOFx/fq1cuR7gEAAAAAAADALg4FoTfffLNMJpP1671792ratGl2HWsymXT+/HlHugcAAAAAAAAAuzgUhEridngAAAAAAAAAtZ5DQejmzZurqw4AAAAAAAAAqDEOBaGRkZHVVQcAAAAAAAAA1BiHVo0HAAAAAAAAAFdAEAoAAAAAAADA7Tm8WFJJ3333nT777DOlpaXpjz/+kCQ1adJEHTt2VN++fdWtW7fq7A4AAAAAAAAA7FItQeju3bv117/+VV9//XW5bWJjY3X99dfrv//9rzp16lQd3QIAAAAAAACAXRy+Nf6zzz5T9+7d9fXXX8swDBmGIU9PT7Vo0UItWrSQp6endfv27dvVvXt3ff7559VROwAAAAAAAADYxaEgNCcnR0OHDtXZs2dlMpk0duxYffXVVzp58qQOHTqkQ4cO6dSpU/r66681btw4mc1mnT17VkOHDlVubm51XQMAAAAAAAAAVMihIPTVV19Vfn6+vLy8tGbNGr355pu67rrr5On5vzvuzWazrr32Wv33v//VmjVrVK9ePeXn5+vVV191uHgAAAAAAAAAsIdDQeiaNWtkMpn0t7/9TVFRURdt369fPz322GMyDENr1qxxpGsAAAAAAAAAsJtDQWhGRoYkadCgQXYfU9w2PT3dka4BAAAAAAAAwG4OBaFnzpyRJDVs2NDuY4rbnj171pGuAQAAAAAAAMBuDgWhQUFBkqSdO3fafUxx2xYtWjjSNQAAAAAAAADYzaEg9KabbpJhGHrhhRdUUFBw0fbHjx/XzJkzZTKZdNNNNznSNQAAAAAAAADYzaEg9OGHH5Z04VmhvXr10rfffltu22+//VaRkZHav3+/zbEAAAAAAAAAUNM8HTn4xhtvVExMjObMmaPdu3fr+uuvV1hYmK6//no1b95cJpNJR44c0VdffaU9e/ZYj4uJidGNN97ocPEAAOnQSbOzSwBqFcYEAAAAgLI4FIRK0uuvv64GDRroP//5j4qKipSWlmYTekqSYRiSJA8PDz399NN64YUXHO0WAOq8gIAAeXt5ae6ei7cF6hpvLy8FBAQ4uwyHmQpMMmQ4uwyg1jAVmJxdAgAAcGEOB6Emk0n//ve/NXr0aM2dO1efffaZ9u3bZ9Omffv26tu3rx599FF17NjR0S4BALqw6Nzid99VXl6es0uBpMzMTE2fPl3PPfecQkJCnF1OnRcQEODSCzMGBATIy9tLhV8XOrsUoNbx8naPDzoAAMCl53AQWqxjx45KSEiQJBUWFurYsWOSpMaNG8vLy6u6ugEAlNCiRQuXDnvcUUhIiK688kpnlwEX16JFC727mA86ags+6KhdXP2DDgAA4DzVFoSW5OXldUnenHzzzTeaPHmykpOTde7cOXXq1ElPPfWUhg0bZvc5fvzxR02fPl2ff/65jh07pqCgIA0ePFiTJ09WkyZNyjxm/fr1io+P144dO2QymdStWzc999xz6tOnT3VdGgAAqOP4oKP24YMOAAAA11YjQeilsHnzZkVFRcnHx0cjRoyQr6+vVq5cqeHDh+vgwYOaMGHCRc+xfft29e3bV6dPn9add96pdu3a6fvvv9drr72mdevWKTk5WYGBgTbHLF68WKNGjVKzZs00ZswYSdKyZct06623avny5brnnntq4nIBAAAAAAAAOMCjMo3Xrl2rrl27qmvXrlqyZEmlOlqyZIn12M8++6xSx/7Z+fPnNW7cOHl4eOiLL77Qm2++qZdeekm7du3SFVdcodjYWGVmZl70POPGjdPJkyf14Ycf6oMPPtCLL76ojRs36t///rf27t2rZ5991qb9sWPH9Nhjj6lp06basWOHXn/9db3++uvasWOHAgMD9eijj+r48eMOXRsAAAAAAACA6md3EGoYhv7+979r165datasme69995KdTRy5Eg1bdpU33//vV2zNSuyadMm7d+/X/fee686d+5s3e7v76/Y2FgVFhZq0aJFFZ5j//79SktL03XXXadBgwbZ7JswYYICAwOVmJiokydPWrevWLFCeXl5euyxx9SqVSvr9latWulvf/ubcnJy9OGHHzp0bQAAAAAAAACqn91B6KZNm7R37155eHjo5ZdfrnRHJpNJr7zyisxms9LS0pSUlFTpcxTbsmWLJKlfv36l9kVFRUnSRc+flZUlSWrbtm2pfR4eHrr88st16tQpbd++vVr7BQAAAAAAAHDp2R2Erly5UpJ06623qkOHDlXqrEOHDtbA8P3336/SOSRp3759kqT27duX2hcUFKRGjRpZ25SnadOmkqSMjIxS+4qKinTgwAFJ0t69e+3qt3jbxfo9e/asCgoKbF4AAAAAAAAAapbdiyV9/fXXMplMGjhwoEMd3nHHHfr0009tZlpWVn5+vqQLt8KXxc/Pz9qmPFdccYVCQ0P1zTffaM2aNbr99tut+1555RXl5uZKkvLy8uzq18/Pz6ZNeWbMmKEpU6ZU2KYmmE7nVe6BsICbM53Oc3YJAAAAAADgErI7CC1efOjKK690qMMrrrhCkvTrr786dB5HmUwmzZkzRwMHDtSgQYM0ePBgtWvXTrt27dKGDRvUqVMn7d69Wx4e1RsfTpw4UU899ZT164KCArVu3bpa+yiLz/4tNd4HAAAAAAAAUFvZHYQWz3Rs0qSJQx0WH+/ILeHFMzLLm31ZUFCgxo0bX/Q8UVFR2rp1q6ZNm6ZNmzZpzZo16tixoz788EN9/vnn2r17t5o3b15mv4GBgaX6LNmmPN7e3vL29r5obdXtTLubZdQPuOT9ArWV6XQeHxAAAAAAAFCH2B2E+vn56dixYza3ildF8fG+vr5VPkfJ53F269bNZl9WVpZOnDih7t2723Wu66+/Xp988kmp7a+88ook6dprr7Xp99tvv9W+fftKBaEVPT+0NjDqB6ioYVNnlwHUGjwqAgAAOFO2JMlwchVA7ZHt7AKqUcHpXGeXANQqtWlM2B2ENmvWTMeOHdMPP/ygm2++ucod/vjjj5JkM9OysiIjIzVjxgxt2LBBI0aMsNm3fv16a5uqyszM1JdffqkOHTqoU6dONv2+99572rBhg2644YZq7xcAAABA3VD1pWMB1HZfZaxxdgkAymF3ENq9e3f9/PPP+vjjjxUTE1PlDj/66COZTCZdd911VT5Hnz59FBoaqiVLlujxxx9X586dJV24ZT0+Pl5eXl4aPXq0tf3hw4eVn5+v4OBgm1vXT5w4oYYNG8pkMlm35efna9SoUbJYLJoxY4ZNv8OGDdM///lPvf7663rwwQfVqlUrSdJvv/2m2bNnq2nTprrrrruqfF0AAAAA6oZ7JDVzdhFALZIt9/mA4Pq2t8uvfuDFGwJ1RMHp3FrzAYHdQeiAAQOUmJioDRs26Msvv1TPnj0r3dkXX3yhDRs2yGQyacCAAZU+vpinp6fmz5+vqKgo9erVSyNGjJCvr69WrlypzMxMzZo1S23atLG2nzhxohYtWqQFCxZozJgx1u2rVq1SbGysbrnlFrVs2VJHjx7V6tWrlZ2drWnTpmnQoEE2/TZu3FizZ8/WqFGj1LVrVw0fPlyStGzZMuXm5mrZsmUO3fIPAAAAoG5oJqmlTBdtB9Qd7vOoCL/6gWrcsIWzywBQBruD0CFDhqhNmzb69ddfNXToUH3xxReVeh7m3r17NWzYMJlMJrVp00b33HNPlQou1rt3b3355ZeaPHmyli1bpnPnzqlTp06aOXOmNaC8mE6dOumaa67Rhg0blJOTI39/f91www166qmn1Lt37zKPiY6OVtOmTRUfH68FCxbIZDKpW7dueu6559S3b1+HrgkAAAAAAABAzbA7CK1Xr55mzZqle+65R0ePHlW3bt00bdo0jR07Vg0bNiz3uBMnTmj+/PmKi4vTiRMnZDKZ9NJLL8nT0+6uy9W9e3etXbv2ou0WLlyohQsXltp+zTXX6OOPP650v/3791f//v0rfRwAAAAAAAAA56hUGnn33XdrypQpmjx5sk6ePKmnnnpKkyZN0k033aRu3bqpefPmatiwoU6ePKkjR45ox44d2rp1q06ePCnDuDDNfcqUKRo8eHBNXAsAAAAAAAAAlKnS0zInTZqkVq1a6bHHHtOpU6d04sQJrVu3TuvWrSuzfXEA2qBBA82ePdvmGZ0AAAAAAAAAcCl4VOWgBx54QHv37tVTTz2lpk2byjCMcl9NmzbVhAkTtHfvXkJQAAAAAAAAAE5R5Qd1tmzZUrNmzdKsWbO0Z88e7dq1S7m5uTp+/Lh8fX0VGBioa665RmFhYdVZLwAAAAAAAABUmuMrFkkKCwsj8AQAAAAAAABQa1Xp1ngAAAAAAAAAcCUEoQAAAAAAAADcHkEoAAAAAAAAALdHEAoAAAAAAADA7RGEAgAAAAAAAHB7BKEAAAAAAAAA3B5BKAAAAAAAAAC3RxAKAAAAAAAAwO0RhAIAAAAAAABwewShAAAAAAAAANyepyMH9+jRQzfffLMiIyPVs2dPNWzYsLrqAgAAAAAAAIBq41AQun37dn311VeaOXOmzGazunbtag1Gb7rpJjVq1Ki66gQAAAAAAACAKnPo1vh+/fqpYcOGMgxD58+f19dff60XX3xRd9xxh5o0aaLu3bvrH//4h9asWaOCgoLqqhkAAAAAAAAAKsWhGaHr1q2TxWLRd999p6SkJG3ZskXbtm1TQUGBzp8/r2+//VbfffedXnrpJXl4eOiaa66xzhjt1auX/P39q+s6AAAAAAAAAKBcDgWhkmQ2m9W9e3d1795dzzzzjIqKirRjxw4lJSUpKSlJW7duVX5+viwWi3bs2KGdO3fq5ZdfltlsVmFhYXVcAwAAAAAAAABUqNpXjffw8NC1116rCRMmaPXq1frjjz/03Xff6dlnn7XOADUMQxaLpbq7BgAAAAAAAIAyOTwjtDx5eXn64osvtGXLFm3ZskWpqakyDEOGYdRUlwAAAAAAAABQpmoLQssLPiVZ/xsSEqKbb77Z+gIAAAAAAACAS8GhIHT16tUVBp9t2rSxCT4vv/xyxysGAAAAAAAAgEpyKAgdPHiwTCaTNfhs27atTfDZunXraikSAAAAAAAAABxRLbfGm0wmDRw4UKNHj1ZkZKQCAwOr47QAAAAAAAAAUC0cCkIvv/xyHThwQJL08ccf6+OPP5bJZFKHDh2ss0IJRgEAAAAAAAA4m0NB6K+//qoDBw5oy5YtSkpK0pYtW5SRkaG0tDTt2bNHCQkJBKMAAAAAAAAAnM7hW+Mvv/xyjR49WqNHj5Yk/fbbb9ZgNCkpSb/88ovS0tKUlpZmE4z27t1br776qsMXAAAAAAAAAAAX41HdJ2zVqpWio6M1b9487d27V7/99pveffddjRs3Tn5+fioqKlJaWppmz55d3V0DAAAAAAAAQJmqZbGk8uzdu1dbtmyxzhAtKCiwWWUeAAAAAAAAAC6Fag1C/xx8ZmVlWfeVDD//8pe/KDIysjq7BgAAAAAAAIByORSE2ht8XnHFFYqMjLQultSyZUtHugUAAAAAAACASnEoCL3qqqtkMpkk2QafV111lU3wGRQU5FiVAAAAAAAAAOAAh2+NNwxDHTp0sAk+mzdvXh21AQAAAAAAAEC1cCgIXbFihSIjI9W0adPqqgcAAAAAAAAAqp1DQeiQIUOqqw4AAAAAqDOyJUnGRVoBdUe2swuoRgVncp1dAlCr1KYxUa2rxqP2Mp3Ok4eziwBqEdPpPGeXAAAA6qCAgAB5e3np/cJCZ5cC1DreXl4KCAhwdhlVdmF8e+ur9DXOLgWodby9vGvF+K62IHTfvn165513lJKSoqysLJ0+fVrr16/XX/7yF2ubtLQ0HThwQA0bNlRkZGR1dY0KBAQEyMvLW9q/xdmlALWOVy35RgwAAOqOFi1aaPG77yovL8/ZpUBSZmampk+frueee04hISHOLqfOCwgIUIsWLZxdRpVdGN+LGd+1BOO7dqkt49vhILSoqEj/+Mc/9Oqrr6qoqMi6erzJZFLhnz7lPHDggO644w55enoqIyNDl112maPd4yJatGihd/lGXGvwjbh2qS3fiAEAQN3SokUL3oPUMiEhIbryyiudXQbcAOO79mF8oySHg9CHH35Yb7/9tgzD0GWXXaaIiAi9//77Zba97bbb1LZtW/366696//339cQTTzjaPezAN+Lah2/EAAAAAAAAl5ZDj438/PPP9dZbb0mSYmNj9euvv2r58uUVHjN06FAZhqFNmzY50jUAAAAAAAAA2M2hGaFvvvmmpAszPadPn27XMd27d5ck7dmzx5GuAQAAAAAAAMBuDs0ITUlJkclk0kMPPWT3Ma1atZIkZWVlOdI1AAAAAAAAANjNoSD06NGjkqQ2bdrYfUy9evUkSefPn3ekawAAAAAAAACwm0NBaMOGDSVJ2dnZdh/z22+/SZKaNGniSNcAAAAAAAAAYDeHgtDQ0FBJ0g8//GD3MWvXrpUkhYWFOdI1AAAAAAAAANjNoSC0X79+MgxDCQkJKioqumj7H374QQsXLpTJZNJtt93mSNcAAAAAAAAAYDeHgtDHH39cDRs21P79+/XII49U+NzPjRs3ql+/fjpz5oyaNGmicePGOdI1AAAAAAAAANjN05GDW7RooTfeeEOjR4/WW2+9pfXr1+v222+37n/11VdlGIa2bdumn376SYZhyMPDQwsXLlSjRo0cLh4AAAAAAAAA7OFQECpJ9913n+rVq6eHH35YBw8e1H//+1+ZTCZJ0vz58yVJhmFIkho1aqRFixbZhKUAAAAAAAAAUNMcujW+2LBhw/TLL79oypQp6tatm8xmswzDsL7CwsI0ceJE/fLLL7rrrruqo0sAAAAAAAAAsJvDM0KLBQYGatKkSZo0aZKKior0xx9/yGKxqEmTJqpXr151dQMAAAAAAAAAlVZtQWhJHh4eatq0aU2cGgAAAAAAAAAqrVpujQcAAAAAAACA2owgFAAAAAAAAIDbq5Yg9Mcff9Tf//53XXvttdZngprN5gpfnp41clc+AAAAAAAAAJTicBr5n//8RxMnTtT58+dlGEZ11AQAAAAAAAAA1cqhIHTdunV6+umnJUkmk0k33HCDunXrpiZNmsjDg7vuAQAAAAAAANQODgWhr7zyiiSpcePGWr16tW688cbqqAkAAAAAAAAAqpVD0za//fZbmUwmxcXFEYICAAAAAAAAqLUcCkJPnTolSerZs2e1FAMAAAAAAAAANcGhIPSyyy6TJBUWFlZLMQAAAAAAAABQExwKQgcOHChJ2rZtW7UUAwAAAAAAAAA1waEg9Omnn1aTJk300ksvKSsrq7pqAgAAAAAAAIBq5VAQ2rJlS3300UeyWCzq0aOHPv300+qqCwAAAAAAAACqjac9jW655ZYK9zdp0kR79+7VwIEDFRAQoPbt26tBgwYVHmMymfT555/bXykAAAAAAAAAVJFdQeiWLVtkMplkGEaZ+00mkyTJMAwdO3ZMX3/9dbnnKj5P8TEAAAAAAAAAUNPsCkJ79epVK4PLb775RpMnT1ZycrLOnTunTp066amnntKwYcPsPsehQ4c0c+ZMbdy4UZmZmWrUqJHat2+vhx9+WPfee6/MZrNN+4r+Hu6//34tXLiwqpcDAAAAAAAAoIbYPSO0ttm8ebOioqLk4+OjESNGyNfXVytXrtTw4cN18OBBTZgw4aLnSE9P1/XXX6/c3FxFRUVp4MCBKigo0KpVqzR69Ght2rRJCxYsKHVcSEiIxowZU2p7586dq+HKAAAAAAAAAFQ3u4LQ2ub8+fMaN26cPDw89MUXX1gDyLi4OHXv3l2xsbG65557FBISUuF5Zs2apZycHL3yyit64oknrNtnzJiha665RgsXLtTzzz9f6jxt2rTR888/X92XBQAAAAAAAKCGOLRq/IEDB3TgwAFZLBa7j7FYLNbjqmrTpk3av3+/7r33XptZmP7+/oqNjVVhYaEWLVp00fOkp6dLkm677Tab7QEBAerZs6ckKScnp8p1AgAAAAAAAKgdHApC27Rpo9DQUP388892H/Prr79aj6uq4lv1+/XrV2pfVFSUJCkpKemi5+nYsaMk6dNPP7XZnpeXp23btikoKEgdOnQodVxeXp7efPNNxcfH64033tDu3bsrewkAAAAAAAAALiGHb40vbyX5mjpOkvbt2ydJat++fal9QUFBatSokbVNRZ555hl9/PHH+vvf/65169YpPDzc+ozQBg0a6MMPP1T9+vVLHbdr1y49/PDDNtv69++vRYsWqXnz5hX2efbsWZ09e9b6dUFBwUXrBAAAAAAAAOAYh2aEVkVxAOrhUfWu8/PzJV24Fb4sfn5+1jYVadGihVJSUtS/f3+tW7dO//73v/XGG28oPz9fo0eP1jXXXFPqmAkTJig5OVk5OTkqKChQcnKyBgwYoHXr1umOO+646GMCZsyYIX9/f+urdevWdlwxAAAAAAAAAEdc8iD08OHDkiRfX99L3XUpv/zyi2688UZlZ2dr69atOn78uA4ePKi4uDhNmzZNffr0KRVszpo1SxEREQoMDJSvr68iIiL0ySefKDIyUt98840++uijCvucOHGi8vPzra+DBw/W5CUCAAAAAAAAUDUFoSaT6aJtzp07p59++kn/+te/JElXXnlllfsrngla3qzPgoKCcmeLljRmzBhlZmbq448/Vs+ePdWoUSO1atVK//d//6fHHntMKSkpWrp06UXP4+HhoXHjxkmStm3bVmFbb29v+fn52bwAAAAAAAAA1KxKBaFms9nmJV241b1jx46l9v355ePjo7CwMG3cuFEmk0n33HNPlYsufjZoWc8BzcrK0okTJ8p8fmhJx48f17Zt23T11VcrKCio1P7evXtLknbu3GlXTU2bNpUknTx50q72AAAAAAAAAC6dSgWhhmHYvMrbfrHX0KFD9eSTT1a56MjISEnShg0bSu1bv369TZvyFBYWSpJycnLK3J+dnS3pwgxOe3z11VeSpDZt2tjVHgAAAAAAAMClU6lV4ydPnmzz9ZQpU2QymfTII49UuFq6yWSSj4+PgoOD1aNHD7Vr165q1f5/ffr0UWhoqJYsWaLHH39cnTt3lnThVvn4+Hh5eXlp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hg0btHnzZo0bN866ffjw4UpNTdXbb7+t4OBgDRs2TCdPntTChQu1fPlymUwmDRgwwOHiAQBwli5duuidd97Rd999p3fffVdpaWnKzc1VYGCgOnbsqCeffNLaDoBrCQ8PV0BAgN5880316NFDkydPVtu2bZWRkaHExETNmzdPAQEBCg8Pd3apAAAAqASHbo0fPHiwJOmTTz6xuT3+iSeeUJs2bVRUVKTp06crPDxcERER+u9//yvpwsIREydOdKRrAACcqnPnzgoICNDu3bs1adIk1atXTz169FC9evU0adIk7d69WwEBAercubOzSwXgAMMwZBhGqT+bTCZnlgUAAIAqcPjW+M2bN+v8+fM6f/68dXuDBg20efNmRUdHa9u2bTbHdOzYUYmJidZFkwAAcEVms1kTJkzQpEmT9N133yk5Odm6z9vbW5I0YcIE63OzAbiO1NRU5eXl6a9//atWr15d6tEX48aN07x585SamsqsbwAAABfiUBAqSZGRkWVuDwkJ0datW/Xzzz9rz549On/+vNq3b8+bRQCA24iMjNS0adM0e/ZsHTlyxLq9cePGGj9+fLk/IwHUbsWLIN19990aOXKkUlNTrY++CA8P19mzZzVv3jwWSwIAAHAxDgehF3PllVfqyiuvrOluAABwisjISPXs2bNUUMJMUMB1FS+ClJGRobCwsFIf5Kenp9u0AwAAgGtw6BmhAADgwm3yXbp0Ud++fdWlSxdCUMDFhYeHKygoSImJiSoqKrLZV1RUpMWLFys4OJjFkgAAAFwMQSgAAABQgtls1vjx45WSkqLY2FilpaXp1KlTSktLU2xsrFJSUhQTE8OHHgAAAC7G7lvjv/jii2rvvFevXtV+TgAALjWLxcKt8YCbiYyM1NSpU5WQkFBqsaSpU6fyDGAAAAAXZHcQevPNN8tkMlVbxyaTyWaleQAAXFFSUpISEhKUlZVl3RYUFMRiSYAb4BnAAAAA7qXSiyUZhlETdQAA4HKSkpIUFxeniIgITZ48WW3btlVGRoYSExMVFxfHrDHADRQ/AxgAAACur9JBaP369XXnnXfq1ltvlYcHjxgFANRNFotFCQkJioiI0LRp05SWlqbk5GQFBgZq2rRpmjRpkubMmaOePXsyewwAAAAAagG7g1BfX18dP35cp0+f1rJly5SUlKR7771Xo0aNYsVMAECdk5qa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hvU6FyxY4OxyHLZgwYJKfV/YvHmzs0sGKqXk96rJkyc7dK5ffvnFiI+PN/r06WOEhIQYDRs2NLy9vY3mzZsb119/vfHoo48an3zyiVFYWFjuOf485kJDQ+3q+8CBA4aHh4fNsRkZGRc9f8mXyWQyfH19jbCwMOOvf/2r8e2331bq+n/44Qfj+eefN2666SajVatWho+Pj9GwYUPj8ssvN+644w7jpZdeMg4fPlypcwK12YkTJ4y5c+caAwYMMFq2bGl4e3sbXl5eRtOmTY1rr73WeOCBB4w333zTOHDggGEYhnH69GnD39/fkGSEhIQYRUVFlepv5MiR1vG6Y8eOcttlZmYaM2fONPr27WuEhIQYDRo0MHx8fIyWLVsa/fr1M6ZNm2akp6c7dO1Adajo94WyXqNHjzbOnz9v17mnTJlic2xUVFSlajtz5ozx9NNPG/Xr17erNl9fX2PSpEnGyZMnq/JXUa6PPvrICAwMtKuG66+/3ubYvn37Wn++//rrr3b3uW/fPus577jjjjLb5ObmGqNGjSr13qOsl6enp/HII48Yubm5Dv1duDOCUNRqlf1m3axZM2PatGnGuXPnnF26DYJQ1LTKjJWwsLAyf2F3RQShm51dslOU/PdeV/8OXFV1BKHHjh0zHnzwQcPT09OucdK8eXPjpZdeKvOXubLG3LZt2y5aw4wZM0odV9kgtKxgdOLEiRftm1+GUBclJycbl19+uV1jqUWLFtbjxo4da92elJRkd38FBQXWQKZjx45ltjl9+rTx5JNPGt7e3naN72HDhllDWsAZSv4MfvTRR43du3dbX6mpqcaWLVuMGTNmGM2bN7e2e/bZZ+0691/+8hdDktGoUSNDujBx6dChQ3Ydm52dbURERFj7bNiwofHAAw8YiYmJRlJSkrFjxw5j48aNxty5c427777bJixNSUlx5K/ExhdffGHUq1fPWn90dLSxbNky4+uvvza+++4749NPPzWmT59u9OzZ0/Dw8CgVhL7zzjvWuqZPn253vyWzguXLl5fav3//fuOKK66weV/z5JNPGh988IGRkpJibN++3fjggw+Mxx9/3Ljsssus7T788ENH/0rclqcAF/Hoo48qJibG+vWJEyd07Ngxpaam6vPPP9dnn32m7OxsTZo0SR9//LE++eQTNWvWzIkV/09MTIzuueeeMvd99NFHeu655yRJ06dP15133llmu8aNG9dYfXAvfx4rR48eVVpaml588UX99ttv2rNnjwYNGqSdO3fKbDY7sVJUpKLvB8Xatm17iaoBaof09HTddttt+vnnnyVJTZo00ciRI9WrVy+1bNlSDRo0UHZ2tn766SetX79eGzdu1NGjRzVhwgTde++9CgoKKvfcPj4+OnPmjBITE9WjR48K60hMTLQ5xh5/HtNFRUXKzs7Wli1b9Morr+jEiROaMWOGQkNDNXbs2HKvf8CAAdq7d68kqXnz5rr33nvVq1cvBQcHy2Qy6dChQ9qyZYtWrlyp33//XW+88YaioqI0ePBgu+oEapu9e/cqKipKx48flyQNGjRI99xzj6644gp5eXkpJydHu3bt0saNG7V582abY0ePHq358+dLujBu7b1ldeXKlTp9+rT1HH+Wk5OjgQMHavv27ZIkX19f3XvvvbrlllvUqlUr1atXT1lZWdq2bZs++OAD7du3T8uXL1dERISefPLJqv5VANWmefPm6tixY6ntkZGRGjRokLp166YzZ87otddeU1xcnLy8vMo9V3Jysn755RdJ0ssvv6xHHnlEFotF7777rp5++ukK67BYLBo6dKhSUlIkXRjf8+bNU/PmzUu17du3rx555BEdOXJEL774ol555ZVKXPHFPfXUUzp37pzMZrPWrVunvn37lmozYMAAPfvss8rMzNTnn39us+/uu+9WTEyMTpw4ocWLF+vZZ5+1q9/FixdLkgICAjRo0CCbfadOndLAgQOtP/cfeughvfzyy/L19S11nrvuuksvvvii3njjDbv7rrOcncQCFanMzJE9e/YYXbp0sba/8cYba+2t8iWVnC3iDjPa4Bz2jJWCggKjTZs21nYrVqy4tEXWAHeeEeoO11NTmBHquhyZEXrixAnj6quvth4/btw4Iz8/v8Jj0tPTjQceeMCQVOZt4iXH3LBhwwxJRpMmTSp8//Ddd99Zjxk+fLjdM0IrGtOfffaZYTKZDEnGFVdcUWabkydPGh06dLCe76GHHjIKCgrKPefZs2eNV1991WjUqBGzQuDS7rnnHrt/Nh49etSYPXu29euioiKjbdu2hiTD39/f7scD3XLLLdZZYb///rvNPovFYvTu3dta0x133GEcOXKk3HNZLBbjnXfeMZo3b268/PLLdvUP1ITK/AweMmSIte2uXbsqbPvwww8bkoymTZsahYWFRr9+/QxJRnh4+EVrevHFF23GksVisft6kpOTjV9++cXu9hX5/fffrXXcc889VT7P6NGjref55ptvLtp+27Zt1vZ//etfS+1//PHHrfvHjh1rdx1paWmVfuROXcJiSXAbHTp00LZt29SlSxdJ0rZt25SQkODkqoDaw9fX1zr7WJI+++wzJ1YDAJXzz3/+Uz/++KOkC3davPnmm/Lz86vwmLZt2+rtt9/W6tWr5ePjU2Hb4cOHy8vLS3/88YfWrFlTbrvi2aDXXXedrrrqqkpeRdn69Omjrl27Srow+62goKBUm4kTJ+qHH36QJI0dO1bz588vc0ZIMS8vLz3++OPavn27WrduXS11ApeaxWKxjsdrr71WY8aMqbB9s2bNNH78eOvXJpNJo0aNkiTl5+fr448/vmifv/32m7Zs2SLpwths2bKlzf5XX33VOvM0KipKH374YZmz14p5eHho1KhR+u677xQeHn7R/oHaoORdR2fPni233dmzZ7V8+XJJ0rBhw1SvXj3rmEtNTdX3339f4bEvvfSSJKlBgwZ666235OFhf0QVERGhdu3a2d2+IgcOHLD++S9/+UuVz1NyBnnx+4WKlGzz59nn2dnZmjdvniQpODi4UjNgw8LC1K1bN7vb1zUEoXAr9evXV2JiokwmkyRp1qxZOnfuXJlts7Ky9Oyzz+raa69VkyZN5O3trdatW2vYsGF2B0TZ2dmaOnWqbrzxRjVv3lz16tVT48aNdf311+sf//iHUlNTHb6mslbF/uCDD3TbbbepZcuW8vT01M0331zquF9++UV///vf1alTJ/n7+6t+/foKDQ3VmDFj9O2339rVd3WcA7VLp06drH8+ePBgqf2FhYX6+OOP9be//U3XXXedGjdurHr16ikwMFDXX3+9nn/+eeXk5FTYR5s2bWQymay/rPz8888aN26c2rRpI29vb7Vo0UJ33XWX9XayilgsFs2ZM0fXX3+9/Pz85O/vr65du2rWrFkVvin7sxMnTuiFF15QRESEdby3atVK99xzjz755JMKj7355ptlMpms4+yXX37RI488otDQUNWvX19t2rTRQw89pMzMTJvj0tLS9MADDyg0NFQ+Pj5q3bq1Hn30UZsVJmtCdV7rvn379Le//U3t27dXgwYNZDKZ9Ouvv9occ+bMGc2ePVt9+vRRUFCQvLy81Lx5c/Xt21dvvfWWzp8/X2GfmzZt0siRI9W2bVvVr19fDRo0UEhIiG644QY9/fTTNquWFn8/7N27t3Vb7969S616Wvy9Eu7jyJEjeuuttyRJrVu31qxZsyp1/MCBAxUQEFBhmyZNmuj222+XVP4vL+fPn9d7770nSdZf9KpLRb908ssQ6qrs7GzrLepVDScqG0y8++67KioqKnWsdOF9UvH3Hx8fH7399tvy9LTvaXOtWrXSLbfcYm/ZgFOVfF97+eWXl9vu448/1rFjxyRJ0dHRki7cot2wYUNJ0jvvvFPusevXr7eucD5ixIgKP1CoaSVv/S/+0LUqevfubf3wcenSpRW+Dy4sLLSGyO3atdONN95os3/p0qXW739jx461/p2iGjh7SipQkareQlc8HV/lLHqwePFio2HDhhU+1Pyhhx6qcNEle84REhJy0VovdttcyVt/3377bWPUqFGl+omMjLQ55sUXX7Q+6Lmsl8lkMiZNmlRhXdVxDlw69o6VnTt3Wtvdeeedpfbff//9Ff6blmQEBgYaX375Zbl9hISEGNKFBb4++OADo0GDBmWex2w2G0uXLi33PMePHzduuummcuvo2rWrsWPHjoveLrdjxw6jZcuWFV7T3XffbZw+fbrM4yMjI63jbOPGjYavr2+Z52jevLnx448/GoZhGEuWLDG8vLzK/b7w59vsijl6a3x1XuuqVavK/B5X8vbf77//3vr/u7zXddddZ2RlZZXZ35NPPmnXv7diJb8fVvTisQK1V1V/rr/66qvW46ZOnVpt9ZQcc5s3bzY++OADQ5Lh5eVV5gJDa9asMaQLixAdPXrUZoEDR26NNwzDuO666wxJRv369Uvte+2116zn4Wcv6pLc3Fzrv/1rrrmmyufp0aOHIcmoV6+ekZOTU2HbsLAwQ7qwKvWfV6RevXq1tZ5Ro0ZVuR7AGez9Gfzjjz9aFyS64YYbKjznwIEDDUlGu3btbLbfd999hnRh8bLyVp5/6qmnrPWUtUjQpXTq1CnDx8fH+nvu4sWLq3yu//u//7Ne1yeffFJuu+L3HJKM559/vtT+ko8n2L59e5XrQWnMCIVbKvlg461bt9rsW758uUaNGqWTJ08qNDRU//nPf7Ru3Tp99913WrlypW677TZJ0ltvvaV//OMfZZ4/MTFR0dHROnnypHx8fPTYY4/p008/1Y4dO/TFF19o9uzZ6tevX6Wm9tvjlVdeUWJiom666SYtWbJE3377rT777DObWSkvvviinnnmGZ07d07h4eGaO3euPvvsM3377bd69913FRERIcMwNG3aNL322mtl9lMd50DtVPITzjZt2pTaf/78eYWGhmrChAlatmyZUlJS9M033+j999/XI488Ii8vL+Xm5uquu+666MzG3bt3695771WLFi00e/Zsbd++XSkpKXr++efl4+Mji8Wiv/71r8rOzi7z+OjoaOv47d69u9577z19++23WrNmjYYOHaodO3bo4YcfrrCG33//XX369NGhQ4dkMpn0wAMPaP369fr222/1zjvv6JprrpF0YZb1xW63O3TokIYNG6aAgAC9/vrr+uqrr7R161Y9+eSTMplMOnr0qMaOHatvvvlGo0ePVrt27TR//nx9/fXX2rx5s3WcZmZm6qmnnqqwr6qozms9cOCAoqOj1aBBA73wwgvatm2btm/frtdff12NGjWSdGFmbGRkpDIzM+Xn56eJEyfqww8/1Lfffqv169dr/Pjx8vT01DfffKM777yz1Oz8Tz75xDqrrfj7zJYtW7Rz505t3rxZs2fP1uDBg+Xt7W095rLLLtPu3bv19ttvW7e9/fbb2r17t82LRWHcT1JSkvXP/fv3r7F+br/9djVp0sRmlkZJxbPJ+vfvX60LMm7ZskXfffedJJVaKEGyvf7iWatAXdCkSROFhIRIknbt2qWZM2daZ2tWRvHMznPnzmnp0qXlttu5c6f27NkjSRoyZIgaNGhgs5+xCHdRvJhq8Wv37t3aunWr/v3vf6t37946ffq0/P399fLLL5d7juzsbK1bt06SdN9999nsK54deuTIEa1fv77M40vePVn8eBhnqV+/vnWhQsMwFB0drbCwMP3zn//UqlWrdOjQIbvPVXImefFCSGUpfk9R8hEeJe3atUvShcdrdO7c2e7+YQcnB7FAhao6c+Szzz6zHvfggw9at2dnZxv+/v7W7eXN+IyNjTUkGR4eHsZPP/1ks+/QoUPWGW7Nmzc3du/eXW4dBw4cuGitlZkRKskYPXq0UVRUVOa59uzZY53FOXny5DLbWSwWIzo62pBkNGrUyPjjjz+q/Ry49OwZK+fPn7dZUGzr1q2l2vzyyy/l/vsyDMNITU01GjVqZEgynnvuuTLblJwh2K1btzIXM1m8eLG1zX/+859S+z/55BPr/ttuu63MsTplypSLzgIsucDC/PnzS+0/c+aMzYIHn376aak2xbMkJRnt27c3jh49WqrN008/bW3TrFkzo0ePHqVmkRiGYQwdOtRmNtmflfx+MH36dGP37t3lvo4dO1aj19qyZUsjMzOzVJtixbNrunTpYmRnZ5fZZu3atYaHh4chyXjzzTdt9hXPbg8JCTGOHz9ebj9lzcpjsSTXVdWf63/5y1+sP5ercyHEP88INQzDePTRRw1JRo8ePWzaFhQUWGfIFM9cqcyM0D+P6V27dhmff/65ERcXZ/j5+RmSjMsuu8zYt29fhddv72IvgLuYNWuWzc/7Nm3aGI8//rixdOlSIz093a5zHDt2zPD29r7oDLe///3v1n42bdpUan/fvn2t+8saq0BtVvJncEUvDw8P45FHHjF+/vnnCs9X8m6NvXv32uw7f/68ERQUZEgXFhYsS+fOna3HV7T4YU5OTrnvh+39HmCPU6dOGQMGDCj37+Xyyy83HnjgAbvee1577bXWuzzKWtgwNzfXevdYz549yzxH48aNDUlG48aNHb00/AlBKGq1qv7CVPL237vuusu6ferUqdZfNCr6ReLcuXPGZZddZkgyYmNjbfZNnDjReu5Vq1ZV+pr+rDJBaEBAQIUrxD744IOGJOPaa6+tMMwq+Wbwz+FEdZwDl15FY+Xo0aPG559/btx4443WNo6shlh8O3PHjh3L3F8yCC1vlcmioiLrLdwlx2ix2267zZBkeHt7l3sbucViMTp27Fju+Pn9998Ns9lsSDL69+9f7vVkZGQYnp6e1tD1z0qGg2vXri3zHOnp6dY2JpPJ+OGHH8pst2nTJmu7jz76qNT+kt8PLvYqeb01ca3vvPNOuef54osvrO1SU1PLbWcYhnUl7j+HSrfeemu5//8vhiDUdVX153pAQIBdvwwcPny43F+Wfvvtt1LtywpCk5OTrdv2799vbfv2228b0oWVp4sfL1GZILSil7e3t/HPf/6z3O93/DKEusxisVjfn5b1atGihTF8+HBj9erVFb53LfmBYVkhZsng5vLLLy/zXCU/UK4ouAFqI3uD0OLfO5988skKf2fu1q2bIcno3r17mfuLf2eoX79+meOlXbt21v7Ku33eMAzj5ZdfLrfOPz8izlFFRUXGsmXLjJtuuskwmUzl9hsVFVXmpIZir7/+urXt22+/XWr/3LlzrfvL+126+D17q1atqu36cAG3xsMtFd+6KUnHjx+3/nn16tWSpDvuuMPmdss/8/T0VEREhCQpJSXFZl/xYiOhoaFl3r5WkwYOHFjhCrHFK2EOGTLEumBUWQICAqyL5vz5+qrjHHCuKVOm2Cwc07x5c/Xp00fbtm1TgwYN9NRTT2nJkiV2nevYsWPav3+/9uzZY711pnjBkR9++KHcxcikCwszlbc6qslkUpcuXSRJ6enpNvssFot1tdZ+/fqVWq21mIeHh+6///5y+9+yZYssFosk6aGHHiq3XZs2bXTrrbeWOubPAgICFBUVVea+tm3bWsdmeHi4rr766jLbFd+eLpW+bkdU97V6eXlp6NCh5Z6n+HvplVdeabMAV1l69eolSfrmm29sHhgfHBwsSfriiy+0f//+Cs8BFP8sv9hCAS+88II6depU5uvZZ5+1q6+IiAjroiwlb2krvoVt6NChF12BvrLOnj2rRYsW6e233y7ztl97rx9wRx4eHnrrrbe0YcMG9e/fv9TiREeOHNGyZcs0aNAgde/evdyfKSXfM5S1aNLGjRutC7dER0eX+T645O8VjEe4ssmTJ8u4MDHO+jp16pRSU1P1zDPP6MSJE3rllVfUt29fnTp1qtTxe/bssT7Spfg2+D8r3n769GmtWLGi1P6Sv9eePHmyOi7LYSaTScOGDdMXX3yho0ePatWqVXr22Wd16623qn79+tZ269evV+/evXXixIkyzzNy5EjVq1dPUtm3xxd/D/Lx8Sn3PXfx309t+btxJwShcEsl36T4+flJuhCufP/995Kk//73v6VWGf7z6/3335ck6xsi6cJzhdLS0iRJPXv2rDAorAnlhUrShecOFj9rceLEiRe9vuJV30teX3WcA7Vb586d9fjjj1t/MJdl9+7devDBBxUcHKwmTZroL3/5izp27GgNE55//nlJUlFRkXWVyLJcddVVFdbSpEkTSbbjVZL2799vfcN13XXXVXiO7t27l7uveKxK0vXXX1/heYr3nzp1qtyAsn379hf9cECSrrjiiou2kUpf958tWLCg1BvUkq+Sz/msiWutKOgpHvs///zzRb9P/O1vf5N04fvnH3/8YT1H8fOTcnNz1bFjR40YMUILFizQL7/8UmH9qJsu9S8Dxc/qKv7l5eDBg9YPaP68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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import pandas as pd\n", + "\n", + "\n", + "plt.figure(figsize=(16, 6))\n", + "sns.boxplot(\n", + " data=pd.DataFrame(\n", + " {\n", + " \"DecTree\": boot_dtc,\n", + " \"RandomForest\": boot_rfc,\n", + " \"LGMBC\": boot_lgbmc,\n", + " \"SVC\" : boot_svc,\n", + " \"BAG_SVC\" : boot_bagc\n", + " }\n", + " )\n", + ")\n", + "plt.ylabel(\"Matthew Corr \", size=20)\n", + "plt.tick_params(axis=\"both\", which=\"major\", labelsize=20)\n", + "plt.yticks(fontsize=14)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "SlUCysufECHN", + "outputId": "8fd0ccec-03aa-4e3f-e2d1-a310a7330e6e" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "random_forest 0.9249968928906641 0.03256402729794103\n", + "lgmbc 0.9254232010527652 0.03254820677355373\n" + ] + } + ], + "source": [ + "print('random_forest', boot_rfc.mean(), boot_rfc.std())\n", + "print('lgmbc', boot_lgbmc.mean(), boot_lgbmc.std())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NRsWZSbYwea1" + }, + "source": [ + "Сделайте вывод о том, какие модели работают лучше.\n", + "\n", + "**Напишите вывод**\n", + "\n", + "Лучшими моделями являются RandomForest и LGMBC. Из них чуть (на самую малость) лучше LGMBC, т.к. число выбросов у неё поменьше, если посмотреть н�� график (но совсем немного)\n", + "\n", + "?? Как и обсуждалось на лекции, SVC & BAG_SVC показывают схожие результаты." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "h9v_5ruEwea1" + }, + "source": [ + "## Формат результата" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5w-oVK8Pwea2" + }, + "source": [ + "График с демонстрацией корреляции Мэтьюса для следующих моделей:\n", + "\n", + " - `DecisionTreeClassifier`\n", + " - `RandomForestClassifier`\n", + " - `LGBMClassifier`\n", + " - `SVC`\n", + " - `BaggingClassifier` с базовым класификатором `SVC`\n", + "\n", + "Пример графика:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Po9ACyoRwea2" + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5AK3fbfQwea2" + }, + "source": [ + "# Задание 2. Дисбаланс классов" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "VB722f9vwea2" + }, + "source": [ + "В этом задании мы рассмотрим особенности обучения и контроля качества моделей на данных, содержащих значительный дисбаланс." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "91wJV2DVwea3" + }, + "source": [ + "Установка и импорт необходимых библиотек:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "kzWORrblwea3" + }, + "outputs": [], + "source": [ + "!pip install -qU imbalanced-learn" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "9kc1qeB7wea3" + }, + "outputs": [], + "source": [ + "import imblearn\n", + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from sklearn.metrics import accuracy_score, balanced_accuracy_score\n", + "from sklearn.model_selection import (\n", + " train_test_split,\n", + " KFold,\n", + " StratifiedKFold,\n", + " cross_validate,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6baaMVgZwea3" + }, + "source": [ + "Важно обращать внимание на сбалансированность классов в наборе.\n", + "Предположим, у нас есть некоторый набор данных со следующими метками классов:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "rTmE5J1Awea4" + }, + "outputs": [], + "source": [ + "real_labels = [1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1YTxXiBPwea4" + }, + "source": [ + "В наборе 16 объектов относятся к классу 0, а 5 — к классу 1.\n", + "\n", + "Мы обучили две модели. Первая всегда выдает 0:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "xpLQ6y9Fwea4" + }, + "outputs": [], + "source": [ + "model1_res = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hDoYYLcvwea5" + }, + "source": [ + "Вторая сумела обнаружить некоторую закономерность в признаках:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "70o5b1bawea5" + }, + "outputs": [], + "source": [ + "model2_res = [1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fL7LdlICwea5" + }, + "source": [ + "Рассчитаем точность Accuracy (см. лекцию 1) для этих моделей:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "HtCdfZiAwea5", + "outputId": "f746ccf9-77cd-459c-ba50-5e325dea558e" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy for model1: 0.7619\n", + "Accuracy for model2: 0.7619\n" + ] + } + ], + "source": [ + "print(f\"Accuracy for model1: {accuracy_score(real_labels, model1_res):.4f}\")\n", + "print(f\"Accuracy for model2: {accuracy_score(real_labels, model2_res):.4f}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qPtK-Kj2wea6" + }, + "source": [ + "Accuracy нельзя использовать, если данные не сбалансированы. Для несбалансированных данных необходимо использовать свои метрики и модели. Одной из таких метрик является Balanced accuracy. При вычислении данной метрики считается полнота (recall) отдельно для каждого класса и вычисляется среднее значение:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "bbc2nS4Mwea6", + "outputId": "08c6f75f-8311-48ca-e991-bab7765ebb0a" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Balanced accuracy for model1: 0.500\n", + "Balanced accuracy for model2: 0.775\n" + ] + } + ], + "source": [ + "# Balanced accuracy for model1 = (16/16+0/5)/2 = 0.5\n", + "print(\n", + " f\"Balanced accuracy for model1: {balanced_accuracy_score(real_labels, model1_res):.3f}\"\n", + ")\n", + "# Balanced accuracy for model2 = (12/16+4/5)/2 = 0.775\n", + "print(\n", + " f\"Balanced accuracy for model2: {balanced_accuracy_score(real_labels, model2_res):.3f}\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IwCToaBTwea6" + }, + "source": [ + "**Всегда проверяйте**, являются ли ваши данные сбалансированными и могут ли выбранные для оценки модели метрики работать с несбалансированными классами." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QJBLu7X9wea6" + }, + "source": [ + "Загрузим датасет с различными биомаркерами пациентов с меланомой (обезличенный, информации о пациентах нет) и переменной, содержащей 1, если пациент ответил на иммунотерапию (терапия помогла пациенту и произошло уменьшение размеров опухоли), и 0, если не ответил. Количество пациентов, отвечающих на терапию, сильно меньше пациентов, которым терапия не помогает, поэтому предсказание ответа пациента на терапию на основании биомаркеров — актуальная задача в онкологии. В данном задании вам предстоит попробовать её решить." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 433 + }, + "id": "biJaDT0Bwea7", + "outputId": "0400e0e1-6d28-4b28-b8e6-94ad805e414e" + }, + "outputs": [ + { + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "summary": "{\n \"name\": \"display(y\",\n \"rows\": 5,\n \"fields\": [\n {\n \"column\": \"sample_id\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 5,\n \"samples\": [\n \"SAMd215b503f99a\",\n \"SAMc0da5d48686d\",\n \"SAM7fb6987514a4\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"IgG1/IgA\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 4.336516131030748,\n \"min\": 2.1390162680442666,\n \"max\": 12.614971518429773,\n \"num_unique_values\": 5,\n \"samples\": [\n 2.1390162680442666,\n 2.764088601964564,\n 12.614971518429773\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"IL21\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.00380889617604994,\n \"min\": -0.0001388498153087,\n \"max\": 0.0081030209571419,\n \"num_unique_values\": 5,\n \"samples\": [\n -8.893814644625583e-05,\n 0.0061065875078736,\n 0.0081030209571419\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"CXCL9\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.21738547329753688,\n \"min\": -0.0029863401619796,\n \"max\": 0.5020432006016782,\n \"num_unique_values\": 5,\n \"samples\": [\n 0.0304946704036539,\n 0.0155327165946915,\n 0.5020432006016782\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"CXCL10\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.211283092537428,\n \"min\": -0.0363664642116282,\n \"max\": 0.5307833290514908,\n \"num_unique_values\": 5,\n \"samples\": [\n 0.2439575071974413,\n 0.1354700642781154,\n 0.5307833290514908\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"CD8A\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.13269648200533504,\n \"min\": 0.0676862641834773,\n \"max\": 0.3884550403564303,\n \"num_unique_values\": 5,\n \"samples\": [\n 0.161127818839325,\n 0.0676862641834773,\n 0.3884550403564303\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"GZMB\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.248904631338728,\n \"min\": 0.0534987504763072,\n \"max\": 0.5657980098838621,\n \"num_unique_values\": 5,\n \"samples\": [\n 0.5657980098838621,\n 0.0534987504763072,\n 0.5281416626901745\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"KLRC2\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.3373884704161336,\n \"min\": -0.3873725336312784,\n \"max\": 0.5020582002204187,\n \"num_unique_values\": 5,\n \"samples\": [\n -0.2034945826631211,\n -0.1160401526617025,\n -0.1562088546043653\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"KLRC3\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.057030752132511374,\n \"min\": -0.0838623550923506,\n \"max\": 0.0637136519258656,\n \"num_unique_values\": 5,\n \"samples\": [\n -0.0269020883054512,\n 0.0637136519258656,\n 0.0011469040291496\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"KLRC4\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.05427963946515479,\n \"min\": -0.035405019005983,\n \"max\": 0.0882013027712291,\n \"num_unique_values\": 5,\n \"samples\": [\n -0.035405019005983,\n 0.0882013027712291,\n -0.0286895144329407\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"GNLY\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.08871351180542986,\n \"min\": 0.0301251118618957,\n \"max\": 0.2607031139685462,\n \"num_unique_values\": 5,\n \"samples\": [\n 0.0301251118618957,\n 0.0829399689765805,\n 0.2607031139685462\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"TGFB1\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 26.045607610224625,\n \"min\": 53.55281726755536,\n \"max\": 114.4229256006832,\n \"num_unique_values\": 5,\n \"samples\": [\n 103.26583725635012,\n 114.4229256006832,\n 53.55281726755536\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Response\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0,\n \"min\": 0,\n \"max\": 0,\n \"num_unique_values\": 1,\n \"samples\": [\n 0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}", + "type": "dataframe" + }, + "text/html": [ + "\n", + "
\n", + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
IgG1/IgAIL21CXCL9CXCL10CD8AGZMBKLRC2KLRC3KLRC4GNLYTGFB1Response
sample_id
SAM4b0175e8db6e3.2427460.001280-0.002986-0.0363660.0966580.0634670.502058-0.0838620.0536590.09193061.9341190
SAMd215b503f99a2.139016-0.0000890.0304950.2439580.1611280.565798-0.203495-0.026902-0.0354050.030125103.2658370
SAM7fb6987514a412.6149720.0081030.5020430.5307830.3884550.528142-0.1562090.001147-0.0286900.26070353.5528170
SAMd636e34619556.365973-0.0001390.0240350.1151270.0844550.200038-0.387373-0.0578370.0459380.07319280.8373180
SAMc0da5d48686d2.7640890.0061070.0155330.1354700.0676860.053499-0.1160400.0637140.0882010.082940114.4229260
\n", + "
\n", + "
\n", + "\n", + "
\n", + " \n", + "\n", + " \n", + "\n", + " \n", + "
\n", + "\n", + "\n", + "
\n", + " \n", + "\n", + "\n", + "\n", + " \n", + "
\n", + "
\n", + "
\n" + ], + "text/plain": [ + " IgG1/IgA IL21 CXCL9 CXCL10 CD8A GZMB \\\n", + "sample_id \n", + "SAM4b0175e8db6e 3.242746 0.001280 -0.002986 -0.036366 0.096658 0.063467 \n", + "SAMd215b503f99a 2.139016 -0.000089 0.030495 0.243958 0.161128 0.565798 \n", + "SAM7fb6987514a4 12.614972 0.008103 0.502043 0.530783 0.388455 0.528142 \n", + "SAMd636e3461955 6.365973 -0.000139 0.024035 0.115127 0.084455 0.200038 \n", + "SAMc0da5d48686d 2.764089 0.006107 0.015533 0.135470 0.067686 0.053499 \n", + "\n", + " KLRC2 KLRC3 KLRC4 GNLY TGFB1 Response \n", + "sample_id \n", + "SAM4b0175e8db6e 0.502058 -0.083862 0.053659 0.091930 61.934119 0 \n", + "SAMd215b503f99a -0.203495 -0.026902 -0.035405 0.030125 103.265837 0 \n", + "SAM7fb6987514a4 -0.156209 0.001147 -0.028690 0.260703 53.552817 0 \n", + "SAMd636e3461955 -0.387373 -0.057837 0.045938 0.073192 80.837318 0 \n", + "SAMc0da5d48686d -0.116040 0.063714 0.088201 0.082940 114.422926 0 " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Number of patients responded to immunotherapy:\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
count
Response
0228
137
\n", + "

" + ], + "text/plain": [ + "Response\n", + "0 228\n", + "1 37\n", + "Name: count, dtype: int64" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "cancer = pd.read_table(\n", + " \"https://edunet.kea.su/repo/EduNet-web_dependencies/datasets/Cancer_dataset_2.tsv\",\n", + " index_col=\"sample_id\",\n", + ")\n", + "display(cancer.head())\n", + "\n", + "# split the data on features (x) and dependant variable (y)\n", + "y = cancer[\"Response\"]\n", + "x = cancer.drop(\"Response\", axis=1)\n", + "print(\"\\nNumber of patients responded to immunotherapy:\")\n", + "display(y.value_counts())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bO6Az3A1wea7" + }, + "source": [ + "В данном случае имеет место несбалансированность классов в наборе данных: пациентов, ответивших на терапию, гораздо меньше.\n", + "\n", + "Есть два способа работы с несбалансированными по классам данными. Первый способ — это получение стратифицированных выборок. Необходимо иметь одинаковую долю образцов каждого класса в тренировочной и тестовой выборках, иначе возникает риск получения смещённых выборок, что приводит к некорректной оценке качества модели. Второй способ — это использование специальных алгоритмов, учитывающих несбалансированность классов." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NY_xlQmKwea7" + }, + "source": [ + "В данном задании вам нужно продемонстрировать эффективность различных подходов работы с несбалансированными выборками. Для этого вы будете использовать три модели, представленные ниже:\n", + "\n", + "1. [[doc] 🛠️](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html) `RandomForestClassifier`, библиотека sklearn\n", + "2. [[doc] 🛠️](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html) `RandomForestClassifier` с балансировкой классов, библиотека sklearn — меняет стандартный вес каждого класса, равный 1, на долю класса во входных данных (см. `class_weight`).\n", + "3. [[doc] 🛠️](https://imbalanced-learn.org/stable/references/generated/imblearn.ensemble.BalancedRandomForestClassifier.html) `BalancedRandomForestClassifier`, библиотека imblearn — семплирует псевдовыборки таким образом, что в каждой псевдовыборке, которая подается на вход модели, баланс классов оказывается \"выправлен\"." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QOEvidjdwea7" + }, + "source": [ + "Оцените эффективность подходов с помощью кросс-валидации, производя разбиение с учетом репрезентации классов и без него. В качестве метрики, отображающей эффективность модели, используйте значения `accuracy` и `balanced_accuracy`. Проинтерпретируйте результаты." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "a4ZBBGJ7wea8" + }, + "outputs": [], + "source": [ + "from imblearn.ensemble import BalancedRandomForestClassifier" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "d1JMRGzFwea_", + "outputId": "f3b1181f-c44d-43af-96c4-80b632343674" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "5" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "skf = StratifiedKFold(n_splits=5, shuffle=True)\n", + "skf.get_n_splits(x, y)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "20iSJ6xlJ3mL" + }, + "outputs": [], + "source": [ + "from sklearn.metrics import accuracy_score" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "X4v2c9W6wea_" + }, + "source": [ + "Объекты, принадлежащие разным классам, распределены неравномерно. Для адекватной работы `cross_validate` нужно перемешать данные. Для этого используйте флаг `shuffle=True`, применяя `KFold` и `StratifiedKFold` (см. параметр `cv` в функции `cross_validate`)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "qG34XBBNwebA", + "jupyter": { + "outputs_hidden": true + } + }, + "outputs": [], + "source": [ + "# Your code here\n", + "cv_rf_acc = cross_validate(estimator=RandomForestClassifier(n_estimators=100), X=x, y=y, cv=skf, scoring='accuracy')\n", + "cv_rf_weighted_acc = cross_validate(estimator=RandomForestClassifier(n_estimators=100, class_weight='balanced'), X=x, y=y, cv=skf, scoring='accuracy')\n", + "cv_bal_rf_acc = cross_validate(estimator=BalancedRandomForestClassifier(n_estimators=100), X=x, y=y, cv=skf, scoring='accuracy')\n", + "\n", + "cv_rf_bal = cross_validate(estimator=RandomForestClassifier(n_estimators=100), X=x, y=y, cv=skf, scoring='balanced_accuracy')\n", + "cv_rf_weighted_bal = cross_validate(estimator=RandomForestClassifier(n_estimators=100, class_weight='balanced'), X=x, y=y, cv=skf, scoring='balanced_accuracy')\n", + "cv_bal_rf_bal = cross_validate(estimator=BalancedRandomForestClassifier(n_estimators=100), X=x, y=y, cv=skf, scoring='balanced_accuracy')\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "lqFDshlNIedM", + "outputId": "ab03d88c-609e-4370-b2f9-1e343c041f6f" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'fit_time': array([0.28391361, 0.34531474, 0.30177093, 0.28197789, 0.28857279]),\n", + " 'score_time': array([0.01238203, 0.01297426, 0.0112915 , 0.01253176, 0.01142955]),\n", + " 'test_score': array([0.88679245, 0.86792453, 0.8490566 , 0.81132075, 0.8490566 ])}" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cv_rf_acc" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 371 + }, + "id": "zOM1_-2TIzUp", + "outputId": "4ceb4650-c66d-44e2-cc7e-c277164b72be" + }, + "outputs": [ + { + "data": { + "image/png": "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n+rVq6fatWtb97dr186m/L59+xQRESEvLy/rtvbt2ysnJ0cHDhywznfRvHlzubj8b7aEgIAA3XLLLdbnrq6u8vf3v+YWuLfffltdu3a1iS89PV0nTpxQ+/btbcq2b99ee/futdnWpk0b67/PnTunxMREDR06VMOHD7duv3z5snVemSFDhuhvf/ubmjRponvuuUf33Xef7r77bhVXRkaGXnrpJX311Vc6efKkLl++rAsXLljnQdmzZ49cXV0VGRmZ5/F79uxRx44dnX7eHvpq+e+rkZGR+uCDD5Sdna3Y2FjdfffdCgwM1KZNmxQeHq5ff/3VegvR3r179euvv8rb29umjosXL+Y5TcKhQ4eUlZWltm3bWrf5+vrmedvF1Z+zxWJRYGDgNe/11QrzXu3bt896K1Kuv/aPgsyePVsffvihjh49qgsXLigzM9O6OuLp06d14sQJ3XXXXXkeu2fPHtWtW1eNGzcuUptlJff7KUl//vmn5syZo3vvvVfff/+9goODtXz5cs2cOVOJiYnKyMjQ5cuX5ePjc936Tp06pfHjx2vTpk06ffq0srOzdf78+Wvmf7r6s/by8pKPj4/1s87v3FfSn/ny5cvVtGlTxcfHa+zYsVq4cKFNuz/++KNeeukl7d27V3/++adycnIkSUePHtXNN9+c5+sJCgqSdKVv1K9fX/v27dPjjz9u0267du20ceNGm21NmjSxub3Lw8PD+noKc/4KCwsr0hxNBb22/D6Hgvo9rsVvYfn/LZSk+vXrq06dOtbn7dq1s74/gYGBhT7HOTP6avnvq1y3FezqY2rWrKkmTZpo3759kgrfj8sbrtkq7zVbbhx/fX71Sunr16/X1KlTtX//fqWnp+vy5cu6ePGizp8/X+779tVIbFYyXl5eatiwoaQrc1xFRETogw8+0NChQzVt2jS98847mjFjhnWehaefflqZmZk2dfz1BGSxWKwngJKUVzuFaTswMND6GnOlp6cXut2rTyi580vMmzdPt912m005V1dXSVKrVq10+PBhffPNN1q/fr369u2rrl276rPPPit0m1d79tln9e233+rNN99Uw4YNVbVqVfXp08f6OVStWjXf4wva7yzoqwVzdF/t1KmTzp49q//+97/avHmzpkyZosDAQL322muKiIhQ7dq11ahRI2t8rVu3ts4pdbUbbrihWO3nKurn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bdiwQRkZGYqMjFTr1q01b948p59zk75a/vqqdCUBl52dbZ2TSbpy0fzXbdWqVdPmzZtVv3599erVS82aNdPQoUN18eLF687j89Zbb6ldu3a677771LVrV7Vv317NmjWzmU+nIG5ubpo5c6bef/991a5dWz179izUe1W9enWtXr1aP/30k1q2bKkXXnhBr7/+eqHbHTFihHr16qV+/frptttuU0pKiqKjo23KDB48WDNmzNCcOXPUvHlz3XfffTp48KB1/8qVK3Xrrbeqf//+uvnmmzV27NgijyIqLWvWrFFQUJCCgoJ02223adeuXfr000/VuXNn9ejRQ//4xz/05JNPqkWLFtq+fbtefPHFfOv74IMP9Oeff6pVq1YaNGiQRo0apRtvvLFIMRV07ivNz3zw4MHKysrSu+++qxtuuEELFy7Up59+qptvvlmvvfZasf7nql+/fnrxxRc1duxYtW7dWklJSXriiScKfXxpnL8K89oK+hwK6vfIH7+F5fO3sGHDhurVq5e6deumu+++W+Hh4dYRQVLJnOOcDX21fPZVrtvy99prr2n06NFq3bq1kpOTtXr1auso0vHjx9vdjx2BazZbleWaLdeYMWP0ww8/qGXLlpo8ebLeeustRUVFSZIiIiL01ltv6fXXX9ctt9yipUuXaurUqXa36QgWY4xxdBAAABTk3LlzqlOnjqZPn66hQ4c6OhwAAABcB9dtAMoKiwcBAMql3bt3a//+/Wrbtq3S0tI0adIkSbL+9R4AAADlA9dtAByFW9GBMta8eXNVr149z0deKw8CjlIe+uqbb76piIgIde3aVefOndOWLVtUq1atMmk7P48//vh135vHH3/c0eEBxbJly5br9uvq1as7OjzAIcrDbyFQGOWhr3LdBpQNrtlscSs6UMaSkpKuu2J5QECAvL29yzgiIG/01es7ffq00tPT89zn4+NT4edOQ8V04cIF/fbbb9fd37BhwzKMBigf+C2Es6CvXh/XbahouGazRWITAAAAAAAAgNPhVnQAAAAAAAAATofEJgAAAAAAAACnQ2ITAAAAAAAAgNMhsQkAAAAAAADA6ZDYBAAAAAAAAOB0SGwCAAAAAAAAcDokNgEAAAAAAAA4HRKbAAAAAAAAAJzO/wc8DNBDoseTJwAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import pandas as pd\n", + "\n", + "\n", + "plt.figure(figsize=(16, 4))\n", + "sns.boxplot(\n", + " data=pd.DataFrame(\n", + " {\n", + " \"RandomForest_acc\": cv_rf_acc['test_score'],\n", + " \"RandomForest_weighted_acc\": cv_rf_weighted_acc['test_score'],\n", + " \"BalancedRandFor_acc\": cv_bal_rf_acc['test_score'],\n", + " \"RandomForest_bal\": cv_rf_bal['test_score'],\n", + " \"RandomForest_weighted_bal\": cv_rf_weighted_bal['test_score'],\n", + " \"BalancedRandFor_bal\": cv_bal_rf_bal['test_score']\n", + " }\n", + " )\n", + ")\n", + "plt.ylabel(\"Accuracies \", size=20)\n", + "plt.tick_params(axis=\"both\", which=\"major\", labelsize=10)\n", + "plt.yticks(fontsize=14)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "10cFP9gNM8qy", + "outputId": "97f2afd8-4ccd-4dd6-b6ce-5a6e10abb4ff" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy\n", + "RFC RFC_weighted BalRFC\n", + "0.8528301886792452 0.025031130493248295\n", + "0.8641509433962264 0.007547169811320753\n", + "0.7056603773584905 0.06381711141618024\n", + "\n", + "\n", + "Balanced Accuracy\n", + "RFC RFC_weighted BalRFC\n", + "0.5421204278812974 0.06459732294998131\n", + "0.4955555555555556 0.008888888888888878\n", + "0.667123878536922 0.07672751479997694\n" + ] + } + ], + "source": [ + "print('Accuracy')\n", + "print(*['RFC', 'RFC_weighted','BalRFC'] )\n", + "print(cv_rf_acc['test_score'].mean(), cv_rf_acc['test_score'].std())\n", + "print(cv_rf_weighted_acc['test_score'].mean(), cv_rf_weighted_acc['test_score'].std())\n", + "print(cv_bal_rf_acc['test_score'].mean(), cv_bal_rf_acc['test_score'].std())\n", + "print('\\n')\n", + "print('Balanced Accuracy')\n", + "print(*['RFC', 'RFC_weighted','BalRFC'] )\n", + "print(cv_rf_bal['test_score'].mean(), cv_rf_bal['test_score'].std())\n", + "print(cv_rf_weighted_bal['test_score'].mean(), cv_rf_weighted_bal['test_score'].std())\n", + "print(cv_bal_rf_bal['test_score'].mean(), cv_bal_rf_bal['test_score'].std())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3ZobGaqLwebB" + }, + "source": [ + "Какая модель лучше справляется с дисбалансом классов?\n", + "\n", + "**Напишите вывод**\n", + "\n", + "Первые три результата получены по accuracy (не баланс). Следующие три по balanced_accuracy.\n", + "\n", + "**Лучше всего с дисбалансом классов справилась модель `BalancedRandomForest`** из imblearn.ensemble.\n", + "\n", + "* Результаты\n", + "\n", + "1. `RandomForestClassifier`, библиотека sklearn;\n", + " * Accuracy Mean 0.85\n", + " * Accuracy STD 0.02\n", + " * Balanced Accuracy Mean 0.54\n", + " * Balanced Accuracy STD 0.06\n", + " \n", + "2. `RandomForestClassifier` с балансировкой классов, библиотека sklearn;\n", + " * Accuracy Mean 0.86\n", + " * Accuracy STD 0.007\n", + " * Balanced Accuracy Mean 0.49\n", + " * Balanced Accuracy STD 0.008\n", + "3. `BalancedRandomForestClassifier`, библиотека imblearn.\n", + " * Accuracy Mean 0.70\n", + " * Accuracy STD 0.063\n", + " * Balanced Accuracy Mean 0.66\n", + " * Balanced Accuracy STD 0.07\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oIl8corLwebD" + }, + "source": [ + "## Формат результата" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vICuS2W0webD" + }, + "source": [ + "Получить значения `accuracy` и `balanced_accuracy`, оцененные на кросс-валидации с учетом стратификации по классам и без, для моделей:\n", + "1. `RandomForestClassifier`, библиотека sklearn;\n", + "2. `RandomForestClassifier` с балансировкой классов, библиотека sklearn;\n", + "3. `BalancedRandomForestClassifier`, библиотека imblearn." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xZ2pCvlfwebD" + }, + "source": [ + "# Задание 3. Разные типы бустингов" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ik3gvkBCwebD" + }, + "source": [ + "В этом задании будем использовать датасет с рейтингом блюд по некоторым характеристикам.\n", + "\n", + "В некоторых реализациях градиентного бустинга есть возможность использовать другой метод обучения. Например, в XGB есть тип `dart`, а в LGBM — `goss`. Это позволяет составлять более эффективные ансамбли.\n", + "\n", + "Используя кросс-валидацию (используйте 3 фолда), обучите модели:\n", + "* `CatBoostRegressor`\n", + "* `XGBRegressor`\n", + "* `LGBMRegressor`\n", + "\n", + "Сохраните модель на каждом фолде и посчитайте `mse` для тестовой выборки, используя модель с каждого фолда. Получите предсказания всех 9 моделей на тестовой выборке и усредните их. Затем посчитайте `mse` для усредненных предсказаний.\n", + "\n", + "Напишите выводы о полученном качестве моделей." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NCvzeTTWwebE" + }, + "source": [ + "Установка и импорт необходимых библиотек:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "CvQEk0vawebE", + "outputId": "83297572-6d0d-479a-e98f-be50263463b6" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m98.7/98.7 MB\u001b[0m \u001b[31m6.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h" + ] + } + ], + "source": [ + "!pip install -q catboost" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "SFRi2aqzwebE" + }, + "outputs": [], + "source": [ + "import xgboost\n", + "import catboost\n", + "import lightgbm\n", + "import numpy as np\n", + "import pandas as pd\n", + "from sklearn.metrics import mean_squared_error as mse\n", + "from sklearn.model_selection import train_test_split, KFold" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wSXmaZuPwebF" + }, + "source": [ + "Загрузка датасета:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 424 + }, + "id": "8r1aYLl3webF", + "outputId": "e0af53b7-2627-479a-d8c7-1a8284733393" + }, + "outputs": [ + { + "data": { + "application/vnd.google.colaboratory.intrinsic+json": { + "summary": "{\n \"name\": \"recipies\",\n \"rows\": 15864,\n \"fields\": [\n {\n \"column\": \"calories\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 359848.41786830855,\n \"min\": 0.0,\n \"max\": 30111218.0,\n \"num_unique_values\": 1858,\n \"samples\": [\n 156.0,\n 765.0,\n 1807.0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"protein\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 3843.4623117544525,\n \"min\": 0.0,\n \"max\": 236489.0,\n \"num_unique_values\": 282,\n \"samples\": [\n 81.0,\n 91.0,\n 200210.0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"fat\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 20459.329548921767,\n \"min\": 0.0,\n \"max\": 1722763.0,\n \"num_unique_values\": 326,\n \"samples\": [\n 1007.0,\n 221495.0,\n 313.0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"sodium\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 334042.078448393,\n \"min\": 0.0,\n \"max\": 27675110.0,\n \"num_unique_values\": 2433,\n \"samples\": [\n 201.0,\n 2362.0,\n 1414.0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"cakeweek\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.019444680844068227,\n \"min\": 0.0,\n \"max\": 1.0,\n \"num_unique_values\": 2,\n \"samples\": [\n 1.0,\n 0.0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"wasteless\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.007939509074046341,\n \"min\": 0.0,\n \"max\": 1.0,\n \"num_unique_values\": 2,\n \"samples\": [\n 1.0,\n 0.0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"rating\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 1.2855179766910894,\n \"min\": 0.0,\n \"max\": 5.0,\n \"num_unique_values\": 8,\n \"samples\": [\n 4.375,\n 5.0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}", + "type": "dataframe", + "variable_name": "recipies" + }, + "text/html": [ + "\n", + "
\n", + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
caloriesproteinfatsodiumcakeweekwastelessrating
0426.030.07.0559.00.00.02.500
1403.018.023.01439.00.00.04.375
2165.06.07.0165.00.00.03.750
3547.020.032.0452.00.00.03.125
4948.019.079.01042.00.00.04.375
........................
1585928.02.02.064.00.00.03.125
15860671.022.028.0583.00.00.04.375
15861563.031.038.0652.00.00.04.375
15862631.045.024.0517.00.00.04.375
15863560.073.010.03698.00.00.04.375
\n", + "

15864 rows × 7 columns

\n", + "
\n", + "
\n", + "\n", + "
\n", + " \n", + "\n", + " \n", + "\n", + " \n", + "
\n", + "\n", + "\n", + "
\n", + " \n", + "\n", + "\n", + "\n", + " \n", + "
\n", + "
\n", + "
\n" + ], + "text/plain": [ + " calories protein fat sodium cakeweek wasteless rating\n", + "0 426.0 30.0 7.0 559.0 0.0 0.0 2.500\n", + "1 403.0 18.0 23.0 1439.0 0.0 0.0 4.375\n", + "2 165.0 6.0 7.0 165.0 0.0 0.0 3.750\n", + "3 547.0 20.0 32.0 452.0 0.0 0.0 3.125\n", + "4 948.0 19.0 79.0 1042.0 0.0 0.0 4.375\n", + "... ... ... ... ... ... ... ...\n", + "15859 28.0 2.0 2.0 64.0 0.0 0.0 3.125\n", + "15860 671.0 22.0 28.0 583.0 0.0 0.0 4.375\n", + "15861 563.0 31.0 38.0 652.0 0.0 0.0 4.375\n", + "15862 631.0 45.0 24.0 517.0 0.0 0.0 4.375\n", + "15863 560.0 73.0 10.0 3698.0 0.0 0.0 4.375\n", + "\n", + "[15864 rows x 7 columns]" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "recipies = pd.read_csv(\n", + " \"https://edunet.kea.su/repo/EduNet-web_dependencies/datasets/recipes.csv\"\n", + ")\n", + "recipies" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "SvgVNo6NwebF" + }, + "outputs": [], + "source": [ + "y = recipies[\"rating\"]\n", + "x = recipies.drop([\"rating\"], axis=1)\n", + "\n", + "x_train_all, x_test, y_train_all, y_test = train_test_split(\n", + " x.values, y.values, train_size=0.7, random_state=42\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "BCoU_bs2RMmg" + }, + "outputs": [], + "source": [ + "from sklearn.metrics import mean_squared_error\n", + "\n", + "\n", + "def train_and_test_regressor(models, x_train, y_train, x_test, y_test, verb=True):\n", + " boot_scores = {}\n", + " for name, model in models.items():\n", + " model.fit(x_train, y_train) # train the model\n", + " y_pred = model.predict(x_test) # get predictions\n", + " boot_scores[name] = bootstrap_metric( # calculate bootstrap score\n", + " y_test,\n", + " y_pred,\n", + " metric_fn=mean_squared_error,\n", + " )\n", + " if verb:\n", + " print(f\"Fitted {name} with bootstrap score {boot_scores[name].mean():.3f}\")\n", + "\n", + " results = pd.DataFrame(boot_scores)\n", + "\n", + " return results\n", + "\n", + "\n", + "# results_rf = train_and_test_regressor(models_rf, x_train, y_train, x_test, y_test)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "9J2LMa9XwebF" + }, + "outputs": [], + "source": [ + "# Your code here\n", + "models = {}\n", + "models['cat'] = catboost.CatBoostRegressor(verbose=0)\n", + "models['xgb'] = xgboost.XGBRFRegressor()\n", + "models['lgbm'] = lightgbm.LGBMRegressor()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "40UIWsutRwvO", + "outputId": "70cd0b61-e4f9-4af4-ff1b-38b744daf48f" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fitted cat with bootstrap score 1.532\n", + "Fitted xgb with bootstrap score 1.535\n", + "Fitted lgbm with bootstrap score 1.561\n" + ] + } + ], + "source": [ + "results_preds = train_and_test_regressor(models, x_train_all, y_train_all, x_test, y_test)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "x4G9a9jXS3Ma", + "outputId": "151c19e5-4cab-46af-bcf4-42f22627a72d" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "kfold = KFold(n_splits=3)\n", + "kfold.get_n_splits(x_train_all, y_train_all)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "-VgLsdPrSlmS" + }, + "outputs": [], + "source": [ + "results_cv = {}\n", + "for name, model in models.items():\n", + " results_cv[name] = cross_validate(estimator=model, X=x_train_all, y=y_train_all, cv=kfold, scoring='neg_mean_squared_error')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "tCwnho3IUHbI", + "outputId": "f4eef433-bda3-4089-cf4e-c4e84e8f42d7" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'cat': {'fit_time': array([7.03786325, 8.02481794, 5.47648811]),\n", + " 'score_time': array([0.02814388, 0.05217481, 0.01294518]),\n", + " 'test_score': array([-1.47398748, -1.60308341, -1.5522741 ])},\n", + " 'xgb': {'fit_time': array([0.14803743, 0.14114594, 0.14647412]),\n", + " 'score_time': array([0.00994015, 0.00969887, 0.01481056]),\n", + " 'test_score': array([-1.46576047, -1.59082778, -1.53800993])},\n", + " 'lgbm': {'fit_time': array([0.08506894, 0.08238196, 0.08508801]),\n", + " 'score_time': array([0.0242455 , 0.02546668, 0.02399921]),\n", + " 'test_score': array([-1.49344309, -1.61136957, -1.55886835])}}" + ] + }, + "execution_count": 71, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "results_cv" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 391 + }, + "id": "DB-6wXTgVo6g", + "outputId": "9914db8a-304f-4b66-f1b2-1a4160b72f47" + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABVMAAAF2CAYAAABj8whzAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABitUlEQVR4nO3deVhUdf//8dcBBRQVXBC1dEjCfS8r9VZQU1zSXFtMETUzbbH020JZLllaptkurihWLpna6lKpeVu5YlpJkil1q2AuiCAiyPn90Y+5nRvQ0TMwoM/Hdc3VzOd8lveZrjtuXnzOOYZpmqYAAAAAAAAAAJfk4e4CAAAAAAAAAKAkIEwFAAAAAAAAACcQpgIAAAAAAACAEwhTAQAAAAAAAMAJhKkAAAAAAAAA4ATCVAAAAAAAAABwAmEqAAAAAAAAADiBMBUAAAAAAAAAnECYCgAAAAAAAABOIEwFAAAAAAAAACcQpgIAAOCqxcTEyDAM7dixI8+xOXPmyDAM9erVSxcuXHBDdQAAAIBrEaYCAADA5VauXKmRI0eqbdu2WrJkiTw9Pd1dEgAAAGAZYSoAAABcauPGjbr//vvVoEEDffbZZ/Lx8XF3SQAAAIBLEKYCAADAZXbv3q27775b1atX19q1a+Xn52c/FhYWpkaNGmnnzp1q3bq1ypQpo5tuukmzZs3KM8+xY8c0bNgwBQYGysfHR02bNtXChQvz9MvJydGbb76pxo0by8fHRwEBAerSpUue2w4sXrxYt912m8qWLauKFSuqXbt2Wrdu3WXPxzAM+8vT01M33HCDHnroIaWkpNj7nD9/Xi+++KJuueUW+fn5ydfXV23bttWGDRvynXPChAkO8+a+IiMj8/S5WFpamqpVqybDMLRx48ZL1nrx6+K+ztZ66NAhGYah119/Pc86jRo1UlhYmENbWFhYnrbt27fba/jf8xg7dqxq166t0qVLO9R6/PjxfL8zAACA4qKUuwsAAADAteHAgQPq0qWLvL29tXbtWlWvXj1Pn1OnTqlbt2665557dP/992vZsmUaOXKkvLy8NHToUElSRkaGwsLC9Pvvv+vRRx/VTTfdpOXLlysyMlIpKSkaPXq0fb5hw4YpJiZGXbt21YMPPqjs7Gxt3rxZP/74o2699VZJ0sSJEzVhwgS1bt1akyZNkpeXl7Zu3apvv/1WnTt3vux59e7dW3369FF2drZ++OEHzZ49WxkZGYqNjZUkpaamau7cubr//vs1fPhwnTlzRvPmzVN4eLi2bdumZs2a5Ttv7nhJevLJJy9bx/Tp05WcnHzJPp06dVJERISkf8LMt956y+H41dZ6NZ555pl825966inNmjVLw4YNU5s2bVS6dGl98sknWrlypcvWBgAAKCyEqQAAALAsOTlZ9913n5KTk9W5c2fVqVMn335HjhzR9OnTNWbMGEnSiBEjdPvttysqKkqDBg1S6dKlNXv2bO3bt0+LFy/WAw88IEl6+OGHFRoaqnHjxmno0KEqX768NmzYoJiYGD3++ON688037WuMHTtWpmlKkn7//XdNmjRJvXv31scffywPj/9emJXb53KaNGmigQMHSpIiIyP1888/a9euXfbjFStW1KFDh+Tl5WVvGz58uOrVq6e3335b8+bNc5gvOztbhmHY55SkcePGXbKGv//+W9OnT1fXrl311Vdf5TmelZUlSapbt659Xh8fnzxh6pXWerW++uorbdiwQV26dNGaNWscjq1evVrh4eGaO3euve33338nTAUAACUCl/kDAADAssjISP31118aMGCA1q1bp+XLl+fbr1SpUhoxYoT9s5eXl0aMGKFjx45p586dkqQvv/xS1apV0/3332/vV7p0aT3++ONKS0vTpk2bJEkrVqyQYRgaP358nnVyLy1ftWqVcnJy9OKLLzoEqRf3uZyzZ8/q+PHjSkpK0ooVK/TTTz+pY8eO9uOenp72cDInJ0cnT55Udna2br31VofQNdf58+fl7e3t1Nq5XnrpJfn5+enxxx/P9/i5c+ck6bL3p73SWq+GaZqKiopS3759dfvtt+c5fubMGVWuXNklawEAABQ1wlQAAABYdvLkSS1evFgLFy5Us2bNNHr0aJ0+fTpPvxo1asjX19ehLXcX66FDhyRJiYmJCgkJyRN+1q9f335c+ue2AjVq1FClSpUKrOvAgQPy8PBQgwYNCuxz+vRpJSUl2V8nT550OD5t2jQFBASoevXq6tevn9q2batXX33Voc/ChQvVpEkT+fj4qHLlygoICNAXX3yR73eQkpKicuXKFVjP/zp48KCio6M1ceLEAsPS3HuNXnyP2oJcSa1X44MPPtAvv/yiV155Jd/jrVq10sqVK/Xxxx/r6NGjOn78uM6ePeuStQEAAAobYSoAAAAsmzZtmvr3769SpUpp9uzZSk5OVlRUlLvLcsro0aNVvXp1+6tPnz4OxwcNGqT169dr7dq1ev/997Vnzx7ddddd9tsELF68WJGRkQoODta8efO0Zs0arV+/Xh06dFBOTk6e9ZKSklStWjWn63v++ecVEhKiwYMHF9gnN4gOCgq65FxXWuuVOn/+vF544QUNGzaswFs9zJ49W02bNlX//v1Vo0YNBQQEaNq0aZbXBgAAKArcMxUAAACWtWvXzv6+ZcuWeuSRR/Tuu+8qIiJCd9xxh/3YkSNHlJ6e7rA7df/+/ZL+GwTabDbt2bNHOTk5DrtT4+Pj7cclKTg4WGvXrtXJkycL3J0aHBysnJwc/frrrwU+XOnpp592uH9pxYoVHY7Xrl1bd955p/2zn5+fBgwYoB9//FGtWrXSxx9/rNq1a+uTTz5xuHVAfrcfkKRff/1VLVq0yPfY/4qLi9OSJUu0atUqeXp6Fthvx44dkmR/6FZBrrTWK/Xee+/p2LFjmjBhQoF9goKCtHjxYjVu3FhDhw5Vr169tGjRIocHcgEAABRX7EwFAACAy7388suqXr26HnroIWVnZ9vbs7OzFR0dbf98/vx5RUdHKyAgQLfccoskqVu3bkpKStLSpUsdxr399tsqV66cQkNDJUl9+/aVaZqaOHFinvVzd4326tVLHh4emjRpUp6dl7l9GjRooDvvvNP+yq2jIBkZGZKkzMxMSbKHnBc/0Grr1q364Ycf8ozdsWOHDhw4oA4dOlxyjVzPPvus2rRpo549e16y38cff6y6deuqXr16l+x3JbVeqTNnzujll1/Wk08+ecmdt9nZ2XrggQfUsGFDvfHGG7rzzjtVu3Zty+sDAAAUBXamAgAAwOXKly+vt99+W3369NH06dP1zDPPSPrnnqmvvvqqDh06pDp16mjp0qXavXu3Zs+erdKlS0uSHnroIUVHRysyMlI7d+5UUFCQPv74Y23ZskUzZ85U+fLlJUnt27fXoEGD9NZbbykhIUFdunRRTk6ONm/erPbt2+vRRx/VzTffrOeff14vvfSS2rZtqz59+sjb21vbt29XjRo1NGXKlMuey549e7R48WKZpqkDBw7orbfe0o033mjfBXrXXXfpk08+Ue/evdW9e3cdPHhQs2bNUoMGDZSWlmafZ9KkSXrzzTdVu3ZtRUREOPU9rlu3Tlu2bCnw+B9//KHXXntN27ZtU58+fbR48WL7se3bt0uS1q9fr1q1aql27dpO15rrt99+05o1axza0tLS5OHhoTVr1qhLly729l27dqlKlSp6+umnL3lOEydO1N69exUXF2f/dw4AAFBimAAAAMBVWrBggSnJ3L59e77H7777brNs2bLmH3/8YYaGhpoNGzY0d+zYYbZq1cr08fExbTab+c477+QZl5ycbA4ZMsSsUqWK6eXlZTZu3NhcsGBBnn7Z2dnmtGnTzHr16pleXl5mQECA2bVrV3Pnzp0O/ebPn282b97c9Pb2NitWrGiGhoaa69evv+z5SbK/DMMwq1WrZvbp08fct2+fvU9OTo75yiuvmDabzfT29jabN29ufv755+bgwYNNm81m73fjjTeaQ4cONY8cOZJnHZvNZg4ePNj+efz48aYk8+6773bot2HDBlOSuWHDBtM0//v9X+6V+905W+vBgwedmjdXaGioKcl84403HOrNPY9cmzdvNj09Pc3o6Oh8+/3999+X+LcBAADgfoZpXnSNDwAAAFBIwsLCdPz4cf3888/uLuWaERMTowkTJtgfQJWfsLAwRUZGKjIy0mXrbty4Ue3btxe/SgAAgOsN90wFAAAAAAAAACcQpgIAAAAlVHBwsHr37n3JPp06dVJwcLBL161UqZLCw8NdOicAAEBJwGX+AAAAKBJc5g8AAICSjjAVAAAAAAAAAJxwXV7mv3v3bj333HMKDw9XQECADMNQWFiYS+Z+9dVXZRiGDMPQjz/+WGC/gwcPavjw4bLZbPL29lZgYKDat2+v5cuXu6QOAAAAAAAAAK5Vyt0FuMOqVas0ZcoUeXl5qU6dOjp+/LhL5v355581fvx4+fr6Kj09vcB+69evV69evSRJPXr0UO3atXXq1Cnt2bNHX3/9tfr37++SegAAAAAAAAC4znUZpvbv3189e/ZU48aNdeLECVWvXt3ynFlZWRo8eLCaNWumkJAQLV68ON9+f/75p/r166cbbrhBX3/9tWrVquVwPDs7+4rWzcnJ0ZEjR1S+fHkZhnHV9QMAAAAAAADXI9M0debMGdWoUUMeHpe+kP+6DFMbNmzo8jlffvll/fLLL9q1a5dee+21Avu98sorSk1N1cqVK/MEqZJUqtSV/Ss5cuSIatasecX1AgAAAAAAAPivv/76SzfeeOMl+1yXYaqr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Zalm4FpGmArArX7//XeZpql69epdst8TTzyh9u3bKygoSB06dNDkyZO1bNkySZKXl5f8/PwcdvaUK1fOPva9995TuXLl5Ovrq8qVK+u3335zuMTlvffeU82aNfXOO++oXr166tWrlyZOnKjp06crJydH6enpev/99zVt2jR17dpVDRo00Jw5c1SmTBnNmzdPkvTnn3+qefPmuvXWWxUUFKQ777xTPXr0kCQFBARI+u9fhytVquTS7xAAUPQMw9D777+vb775RoGBgXr22Wftx/bv36/atWurVKlS9rYZM2aoXLly9tfFl2OePn3a3u7l5aWRI0dq9uzZCg4OLtJzAgAUT/v375ck1a1b1962fft2h58rn3/+ucOY1q1b23+utGzZUvfcc48iIiLyzH3XXXcpNTVV3333ndLT07Vs2TINHTq0cE8IKOFKXb4LABSei2+Cfilff/21pkyZovj4eKWmpio7O1vnzp3T2bNnVbZs2UuOfeCBB+wPBElOTtYrr7yizp07a+fOnSpfvrz27dunVq1aOfw1t02bNkpLS9N//vMfpaSkKCsrS23atLEfL126tG677Tbt27dPkjRy5Ej17dtXu3btUufOndWrVy+1bt36Sr8OAEAJMn/+fJUtW1YHDx7Uf/7zHwUFBRXYd+jQoerZs6e2bt2qgQMHOvz8K1++vP3Sy7Nnz+rrr7/Www8/rMqVK9v/MAcAwMWaNGlif8BtSEiIwy3KJGnp0qWqX7++srKy9PPPP+uxxx5TxYoVNXXqVId+pUuX1sCBA7VgwQL98ccfqlOnjpo0aVJUpwGUSOxMBeBWISEhMgxD8fHxBfY5dOiQ7rrrLjVp0kQrVqzQzp079e6770qSzp8/f9k1/Pz8dPPNN+vmm29WmzZtNG/ePCUkJGjp0qUuO4+uXbsqMTFRTz75pI4cOaKOHTsWeKsBAEDJ9/333+uNN97Q559/rttuu03Dhg2zB6QhISH6448/lJWVZe/v7++vm2++WTfccEOeuTw8POw/p5o0aaIxY8YoLCxMr776apGdDwCg+AoJCZEkhwcTent723925KdmzZq6+eabVb9+ffXv319PPPGEpk+frnPnzuXpO3ToUC1fvlzvvvsuu1IBJxCmAnCrSpUqKTw8XO+++67S09PzHE9JSdHOnTuVk5Oj6dOn64477lCdOnV05MgRh35eXl66cOGCU2t6enpKkjIyMiRJ9evX1w8//OCwS2jLli0qX768brzxRgUHB8vLy0tbtmyxH8/KytL27dvVoEEDe1tAQIAGDx6sxYsXa+bMmZo9e7a9NklO1wcAKN7Onj2ryMhIjRw5Uu3bt9e8efO0bds2zZo1S5J0//33Ky0tTe+9995Vr+Hp6Wn/OQUAuL517txZlSpVsvRHNk9PT2VnZ+e7GaVhw4Zq2LChfv75Zw0YMMBKqcB1gcv8Abjdu+++qzZt2ui2227TpEmT1KRJE2VnZ2v9+vV6//33tWTJEmVlZentt99Wjx49tGXLFvsvrLmCgoKUlpamb775Rk2bNlXZsmXtl/+fPXtWSUlJkv65zP+ll16Sj4+POnfuLEkaNWqUZs6cqccee0yPPvqofvvtN40fP15jxoyRh4eHfH19NXLkSD311FOqVKmSatWqpddee01nz57VsGHDJEkvvviibrnlFjVs2FCZmZn6/PPPVb9+fUn/PCWzTJkyWrNmjW688Ub5+PjkedomAKDkiIqKkmma9kslg4KC9Prrr+v//u//1LVrV7Vq1Upjx47V2LFjlZiYqD59+qhmzZo6evSo5s2bJ8Mw5OHx3z0Npmnaf05lZGRo/fr1Wrt2rV588UW3nB8AwH1Onz5tv3w/V+XKlTV37lzde++96t69ux5//HGFhIQoLS1Na9askfTfDSO5Tpw4oaSkJGVnZ2vv3r1688031b59e1WoUCHfdb/99ltlZWXZHwAM4BJMACgGjhw5Yj7yyCOmzWYzvby8zBtuuMHs2bOnuWHDBtM0TXPGjBlm9erVzTJlypjh4eHmokWLTEnmqVOn7HM8/PDDZuXKlU1J5vjx403TNM3Q0FBTkv1VsWJFMzQ01Pz2228d1t+4caPZsmVL08vLy6xWrZr5zDPPmFlZWfbjGRkZ5mOPPWZWqVLF9Pb2Ntu0aWNu27bNfvyll14y69evb5YpU8asVKmSeffdd5t//PGH/ficOXPMmjVrmh4eHmZoaKjLvz8AQNHYuHGj6enpaW7evDnPsc6dO5sdOnQwc3JyTNM0zaVLl5phYWGmn5+fWbp0afPGG280BwwYYP7444/2MQsWLHD4OeXt7W3WqVPHfPnll83s7OwiOy8AgPsNHjzY4WdC7mvYsGGmaZrm9u3bzX79+plVq1Y1S5UqZVauXNkMDw83lyxZYv/Zc/DgQYexnp6e5o033mgOHz7cPHbsmH2t8ePHm02bNi2wltGjR/N7C1AAwzSdfPoLAAAAAAAAAFzHuGcqAAAAAAAAADiBMBUAAAAAAAAAnECYCgAAAAAAAABOIEwFAAAAAAAAACcQpgIAAAAAAACAEwhTAQAAAAAAAMAJhKkAAAAAAAAA4ATCVAAAAAAAAABwAmEqAAAAAAAAADiBMBUAAAAAAAAAnECYCgAAAAAAAABOIEwFAAAAAAAAACf8PwLxFCbO8xm4AAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(16, 4))\n", + "sns.boxplot(\n", + " data=pd.DataFrame(\n", + " {\n", + " \"CatBoost\": results_cv['cat']['test_score'],\n", + " \"XGB\": results_cv['xgb']['test_score'],\n", + " \"LGBM\": results_cv['lgbm']['test_score'],\n", + " }\n", + " )\n", + ")\n", + "plt.ylabel(\"Mean Squared Error\", size=20)\n", + "plt.tick_params(axis=\"both\", which=\"major\", labelsize=10)\n", + "plt.yticks(fontsize=14)\n", + "plt.title('Кросс-валидация')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 391 + }, + "id": "SUpQZlYSWR8L", + "outputId": "03475a3d-38bb-4bae-9834-e43c8374a3a8" + }, + "outputs": [ + { + "data": { + "image/png": "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HABAEcZ3DgDgduE7B7g1pmnqwoULKl++vBwccj4JlBWhBczBwUEVKlQo6DCAQsvNzY3/QAAA3BZ85wAAbhe+c4C8u9FK0ExclgQAAAAAAACgyCMRCgAAAAAAAKDIIxEKoFBydnZWeHi4nJ2dCzoUAEARx3cOAOB24TsHyF9clgQAAAAAAACgyGNFKAAAAAAAAIAij0QoAAAAAAAAgCKPRCgAAAAAAACAIo9EKAAAAAAAAIAij0QoALtISEhQ//795e/vL2dnZ1WsWFFt2rTRypUrc9U/KipKHh4eWcobN24swzAsr3Llyqljx46Kj4+38xPk7OjRozIMQ7/99tttmxMAYH/p6el6/PHH1b59e6vypKQkVaxYUe+9956lbNGiRWratKlKly6t4sWLq3r16urZs6d27NhhaRMVFWX1HVWyZEk99NBD+vrrr2/bMwEA7hwhISFq27ZtjvU7duxQ586d5ePjI2dnZ/n6+uqZZ57R999/r8x7rDN/9sh8OTk56f7779eoUaN0/V3Xw4cPl2EYeuqpp7LMM27cOBmGocaNG9v7EYFCj0QoAJsdPXpUDz30kFatWqVx48Zp9+7dWrZsmZo0aaK+ffvaPH7v3r116tQpnTx5Ut99952OHz+url272iFyAMDdxNHRUVFRUVq2bJm++OILS3n//v117733Kjw8XJI0ePBgde7cWXXq1NHixYt14MABzZ07V/7+/hoyZIjVmG5ubjp16pROnTqlHTt2qGXLlurUqZMOHDhwW58NAHBn++677/TYY4/p4sWLmj17tvbt26dly5apXbt2Gjp0qJKSkqza//zzzzp16pQOHTqkESNG6IMPPtDnn39u1cbHx0erV6/Wn3/+aVX++eefq1KlSvn+TEBhRCIUgM1CQ0NlGIY2b96sDh06qFq1agoICNBbb72lX3/9VZI0YcIE1apVS66urqpYsaJCQ0N18eJFSdKaNWvUo0cPJSUlWX7zOXz4cMv4JUqUkLe3t3x8fPTYY4+pX79+2r59u1UMsbGxeuSRR+Ts7CwfHx+9++67SktLs9RfvXpVb7zxhsqWLSsXFxc1bNhQW7ZssdSfO3dOL730ksqUKaPixYuratWqmjVrliSpcuXKkqS6devym1UAKOSqVaumsWPHqn///jp16pS+++47zZs3T3PmzJGTk5N+/fVX/fe//9WECRM0YcIEPfHEE6pUqZIeeughDR06VD/++KPVeIZhyNvbW97e3qpatapGjRolBwcH7dq1q4CeEABwp0lJSVGvXr3UunVrLV26VC1atJC/v79q1KihXr16aefOnXJ3d7fq4+npKW9vb/n6+uqll15SgwYNsvwMVLZsWbVo0UKzZ8+2lP3yyy9KTExU69atb8uzAYUNiVAANjl79qyWLVumvn37ytXVNUt95nZ3BwcH/e9//9PevXs1e/ZsrVq1Sv/5z38kSY8//rgmTpxotarm7bffznG+BQsW6NFHH7WUnThxQk8//bTq16+vnTt3atq0aZo5c6ZGjRplafOf//xHixYt0uzZs7V9+3bdf//9atmypc6ePStJev/99/X777/rxx9/1L59+zRt2jR5eXlJkjZv3izp/34ry5ZHACjc+vfvr9q1a6tbt2569dVXNWzYMNWuXVuS9OWXX6pkyZIKDQ3Ntq9hGDmOm56ebvlhtF69evYPHABQKK1YsUJnzpyx/PyTnRt9v2zdulXbtm2z+hkoU8+ePRUVFWV5//nnn+ull16Sk5OTTTEDRRWJUAA2+eOPP2Saph544IEbths4cKCaNGkiPz8/NW3aVKNGjdKCBQskSU5OTnJ3d7daVVOyZElL36lTp6pkyZJydXWVp6enDhw4YLUtZOrUqapYsaImT56sBx54QG3bttWIESM0fvx4ZWRkKCUlRdOmTdO4cePUqlUrPfjgg5oxY4aKFy+umTNnSpKOHTumunXr6uGHH5afn5+aN2+uNm3aSJLKlCkj6f9+K3vvvffa9TMEANxehmFo2rRpWrlypcqVK6d3333XUnfw4EH5+/urWLFilrIJEyaoZMmSltf12xeTkpIs5U5OTnr99df12WefqUqVKrf1mQAAd66DBw9KkqpXr24p27Jli9V3y5IlS6z6PP7445bvlvr166tTp07q3r17lrGfeeYZJScna+3atUpJSdGCBQvUs2fP/H0goBArdvMmAJCz6w/svpGff/5ZY8aM0f79+5WcnKy0tDRduXJFly5dUokSJW7Y96WXXrJcYHH69GmNHj1aLVq00LZt21SqVCnt27dPQUFBVr9FbdCggS5evKg///xT58+f17Vr19SgQQNL/T333KNHHnlE+/btkyS9/vrr6tChg7Zv364WLVqobdu2evzxx/P6cQAAConPP/9cJUqUUFxcnP7880/5+fnl2LZnz5569tlntWnTJnXt2tXqu69UqVKWrYqXLl3Szz//rNdee02enp6WX6gBAPBvgYGBlstYq1atanWslyTNnz9fNWrU0LVr17Rnzx71799fpUuX1tixY63a3XPPPeratatmzZqlI0eOqFq1agoMDLxdjwEUOqwIBWCTqlWryjAM7d+/P8c2R48e1TPPPKPAwEAtWrRI27Zt05QpUyRJqampN53D3d1d999/v+6//341aNBAM2fO1KFDhzR//ny7PUerVq0UHx+vN998UydPnlSzZs1y3J4PACjcfvnlF3388cdasmSJHnnkEfXq1cuS3KxataqOHDmia9euWdp7eHjo/vvv13333ZdlLAcHB8t3VGBgoN566y01btxYH3744W17HgDAna1q1aqSZHWRnrOzs+X7IzsVK1bU/fffrxo1aqhjx44aOHCgxo8frytXrmRp27NnTy1cuFBTpkxhNShwEyRCAdjk3nvvVcuWLTVlyhSlpKRkqT9//ry2bdumjIwMjR8/Xo899piqVaumkydPWrVzcnJSenp6ruZ0dHSUJF2+fFmSVKNGDW3cuNFqhc6GDRtUqlQpVahQQVWqVJGTk5M2bNhgqb927Zq2bNmiBx980FJWpkwZvfzyy4qJidHEiRP12WefWWKTlOv4AAB3rkuXLikkJESvv/66mjRpopkzZ2rz5s2aPn26JOnFF1/UxYsXNXXq1Fuew9HR0fIdBQBAixYtdO+999r0SzJHR0elpaVlu5AkICBAAQEB2rNnj7p06WJLqECRx9Z4ADabMmWKGjRooEceeUQREREKDAxUWlqafvrpJ02bNk3z5s3TtWvX9Mknn6hNmzbasGGD5QfOTH5+frp48aJWrlyp2rVrq0SJEpYt85cuXVJCQoKkf7bGjxw5Ui4uLmrRooWkf26tnzhxovr3769+/frpwIEDCg8P11tvvSUHBwe5urrq9ddf1zvvvKN7771XlSpV0n//+19dunRJvXr1kiQNGzZMDz30kAICAnT16lUtWbJENWrUkPTPbYzFixfXsmXLVKFCBbm4uGS51REAUDgMGTJEpmlathb6+fnpo48+0ttvv61WrVopKChIgwYN0qBBgxQfH6/27durYsWKOnXqlGbOnCnDMOTg8H9rCUzTtHxHXb58WT/99JOWL1+uYcOGFcjzAQAKVlJSkmXLeyZPT09FRkaqc+fOat26td544w1VrVpVFy9e1LJlyyT932KPTGfOnFFCQoLS0tK0e/duTZo0SU2aNJGbm1u2865atUrXrl2zXFYLIAcmANjByZMnzb59+5q+vr6mk5OTed9995nPPvusuXr1atM0TXPChAmmj4+PWbx4cbNly5bmnDlzTEnmuXPnLGO89tprpqenpynJDA8PN03TNIODg01Jllfp0qXN4OBgc9WqVVbzr1mzxqxfv77p5ORkent7m4MHDzavXbtmqb98+bLZv39/08vLy3R2djYbNGhgbt682VI/cuRIs0aNGmbx4sXNe++913zuuefMI0eOWOpnzJhhVqxY0XRwcDCDg4Pt/vkBAPLfmjVrTEdHR3PdunVZ6lq0aGE2bdrUzMjIME3TNOfPn282btzYdHd3N++55x6zQoUKZpcuXcxff/3V0mfWrFlW31HOzs5mtWrVzA8++MBMS0u7bc8FALgzvPzyy1bfC5mvXr16maZpmlu2bDGff/55s2zZsmaxYsVMT09Ps2XLlua8efMs3z9xcXFWfR0dHc0KFSqYvXv3Nv/66y/LXOHh4Wbt2rVzjGXAgAH83AJkwzDNXN50AgAAAAAAAACFFGeEAgAAAAAAACjySIQCAAAAAAAAKPJIhAIAAAAAAAAo8kiEAgAAAAAAACjySIQCAAAAAAAAKPJIhAIAAAAAAAAo8kiEAgAAAAAAACjySIQCAAAAAAAAKPJIhAIAAAAAAAAo8kiEAgAAAAAAACjySIQCAAAAAAAAKPJIhAIAAAAAAAAo8v4fi/KZVy9YmSsAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(16, 4))\n", + "sns.boxplot(\n", + " data=pd.DataFrame(\n", + " {\n", + " \"CatBoost\": results_preds['cat'],\n", + " \"XGB\": results_preds['xgb'],\n", + " \"LGBM\": results_preds['lgbm'],\n", + " }\n", + " )\n", + ")\n", + "plt.ylabel(\"Mean Squared Error\", size=20)\n", + "plt.tick_params(axis=\"both\", which=\"major\", labelsize=10)\n", + "plt.yticks(fontsize=14)\n", + "plt.title('Предсказания на тесте')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "88yFFrNIX1s9", + "outputId": "e2f05349-d870-4829-834f-e869cc613823" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cat mean: 1.53 \t std: 0.05\n", + "XGB mean: 1.54 \t std: 0.05\n", + "LGBM mean: 1.56 \t std: 0.05\n" + ] + } + ], + "source": [ + "print(f'Cat mean: {results_preds[\"cat\"].mean():.2f} \\t std: {results_preds[\"cat\"].std():.2f}')\n", + "print(f'XGB mean: {results_preds[\"xgb\"].mean():.2f} \\t std: {results_preds[\"xgb\"].std():.2f}')\n", + "print(f'LGBM mean: {results_preds[\"lgbm\"].mean():.2f} \\t std: {results_preds[\"lgbm\"].std():.2f}')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "n0iSxHR4XaaV" + }, + "source": [ + "* Результаты\n", + "\n", + "На кроссвалидации лучше всего себя показал XGBoost, а за ним шёл CatBoost\n", + "\n", + "При проверке на тестах лучше всего оказался CatBoost.\n", + "Стандартное отклонени�� у моделей идентичное, поэтому нет никаких причин не выбрать CatBoost\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xJDgfinEwebG" + }, + "source": [ + "## Формат результата" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MXG4PahWwebG" + }, + "source": [ + "Получить значения MSE для всех моделей и среднее значение MSE по предсказаниям всех моделей. Написать вывод.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "me1sL619webH" + }, + "source": [ + "# Задание 4. Подбор гиперпараметров" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vtDysuP8webH" + }, + "source": [ + "В этом задании нужно подобрать параметры для бустинга `CatBoostRegressor`, используя библиотеку `optuna`. И улучшить результат по сравнению со стандартными параметрами.\n", + "\n", + "Список параметров для подбора:\n", + "\n", + "* `depth`\n", + "* `iterations`\n", + "* `learning_rate`\n", + "* `colsample_bylevel`\n", + "* `subsample`\n", + "* `l2_leaf_reg`\n", + "* `min_data_in_leaf`\n", + "* `max_bin`\n", + "* `random_strength`\n", + "* `bootstrap_type`\n", + "\n", + "**Важно!** *Подбирать параметры нужно на валидационной выборке*" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YffT7WXtwebI" + }, + "source": [ + "Установка и импорт необходимых библиотек:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "execution": { + "iopub.execute_input": "2024-10-24T14:04:18.891446Z", + "iopub.status.busy": "2024-10-24T14:04:18.890257Z" + }, + "id": "fwBhoRnSwebI", + "outputId": "0bcdfb29-aec9-41cd-e96e-52cd2626fbe9" + }, + "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;49m23.0.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.2\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;49mpython3 -m pip install --upgrade pip\u001b[0m\n" + ] + } + ], + "source": [ + "%pip install -q catboost\n", + "%pip install -q optuna" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "E6LCZl3KwebJ" + }, + "outputs": [], + "source": [ + "import optuna\n", + "import numpy as np\n", + "import pandas as pd\n", + "from catboost import CatBoostRegressor\n", + "from optuna.samplers import RandomSampler\n", + "from sklearn.metrics import mean_squared_error as mse\n", + "from sklearn.model_selection import train_test_split, KFold" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lwIlJfOOwebJ" + }, + "source": [ + "Загрузка датасета:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "67DlWdjswebJ" + }, + "outputs": [], + "source": [ + "recipies = pd.read_csv(\n", + " \"https://edunet.kea.su/repo/EduNet-web_dependencies/datasets/recipes.csv\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "SfA8jFCIwebK" + }, + "outputs": [], + "source": [ + "y = recipies[\"rating\"]\n", + "x = recipies.drop([\"rating\"], axis=1)\n", + "\n", + "x_train_all, x_test, y_train_all, y_test = train_test_split(\n", + " x.values, y.values, train_size=0.7, random_state=42\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ipA3ufjNwebK", + "outputId": "2fab02dc-9cd8-4744-c533-1ccfee1d7d6d" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Learning rate set to 0.074308\n", + "0:\tlearn: 1.2817437\ttest: 1.2774827\tbest: 1.2774827 (0)\ttotal: 56.4ms\tremaining: 56.3s\n", + "Stopped by overfitting detector (100 iterations wait)\n", + "\n", + "bestTest = 1.242760353\n", + "bestIteration = 44\n", + "\n", + "Shrink model to first 45 iterations.\n", + "\n", + "mse_score before tuning: 1.5445\n" + ] + } + ], + "source": [ + "model = CatBoostRegressor(random_seed=42)\n", + "\n", + "model.fit(\n", + " x_train_all,\n", + " y_train_all,\n", + " eval_set=(x_test, y_test),\n", + " verbose=200,\n", + " use_best_model=True,\n", + " plot=False,\n", + " early_stopping_rounds=100,\n", + ")\n", + "\n", + "print(f\"\\nmse_score before tuning: {mse(y_test, model.predict(x_test)):.4f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "Hk8HXmDDbCTS", + "outputId": "18d93de7-f4d6-4f10-c6b1-1bfad252f51f" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(11104, 6)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x_train_all.shape" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "-8GELU4-nrIi", + "outputId": "85e9a7b4-b189-4830-87e6-b8cba13460e7" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "1e-3 == 0.001" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "g_iO_zpawebK", + "outputId": "4b7f321c-a436-4b99-f2f9-9dbb44cc74a8" + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[I 2024-10-24 13:58:43,344] A new study created in memory with name: Optimizer\n", + "[I 2024-10-24 14:00:24,582] Trial 0 finished with value: 1.5704353716214252 and parameters: {'depth': 14, 'min_data_in_leaf': 9, 'l2_leaf_reg': 3.77, 'random_strength': 0.5335935784999819, 'iterations': 750, 'learning_rate': 0.025431650581376246, 'colsample_bylevel': 1.0, 'subsample': 0.7, 'max_bin': 45, 'bootstrap_type': 'Bernoulli'}. Best is trial 0 with value: 1.5704353716214252.\n", + "[I 2024-10-24 14:00:26,160] Trial 1 finished with value: 1.5429485285943108 and parameters: {'depth': 3, 'min_data_in_leaf': 8, 'l2_leaf_reg': 6.82, 'random_strength': 0.7567885203094618, 'iterations': 1050, 'learning_rate': 0.01444858638462606, 'colsample_bylevel': 0.2, 'subsample': 0.2, 'max_bin': 79, 'bootstrap_type': 'Bernoulli'}. Best is trial 1 with value: 1.5429485285943108.\n" + ] + } + ], + "source": [ + "# Your code here\n", + "from optuna.samplers import TPESampler\n", + "from sklearn.model_selection import cross_val_score, KFold\n", + "\n", + "# Define function which will optimized\n", + "\n", + "\n", + "def objective(trial):\n", + " # boundaries for the optimizer's\n", + " depth = trial.suggest_int(\"depth\", 3, 15, step=1)\n", + " min_data_in_leaf = trial.suggest_int(\"min_data_in_leaf\", 3, 10, step=1)\n", + " l2_leaf_reg = trial.suggest_float(\"l2_leaf_reg\", 2, 8, step=0.01)\n", + " random_strength = trial.suggest_float(\"random_strength\", 0.5, 2)\n", + " iterations = trial.suggest_int(\"iterations\", 100, 1500, step=50)\n", + " learning_rate = trial.suggest_float('learning_rate', 1e-3, 5e-2)\n", + " colsample_bylevel = trial.suggest_float('colsample_bylevel', 0.1, 1., step=0.1) #step=0.01)\n", + " subsample = trial.suggest_float('subsample', 0.2, 1, step=0.1)\n", + " max_bin = trial.suggest_int('max_bin', 10, 255, step=1)\n", + " bootstrap_type = trial.suggest_categorical('bootstrap_type', choices=['Bernoulli'])\n", + " # params = {\n", + " # 'depth': trial.suggest_int('depth', 3, 15),\n", + " # 'iterations': trial.suggest_int('iterations', 100, 1000),\n", + " # 'learning_rate': trial.suggest_loguniform('learning_rate', 1e-3, 0.3),\n", + " # 'colsample_bylevel': trial.suggest_uniform('colsample_bylevel', 0.5, 1.0),\n", + " # 'subsample': trial.suggest_uniform('subsample', 0.5, 1.0),\n", + " # 'l2_leaf_reg': trial.suggest_int('l2_leaf_reg', 1, 10),\n", + " # 'min_data_in_leaf': trial.suggest_int('min_data_in_leaf', 1, 10),\n", + " # 'max_bin': trial.suggest_int('max_bin', 10, 255),\n", + " # 'random_strength': trial.suggest_uniform('random_strength', 1, 10),\n", + " # 'bootstrap_type': trial.suggest_categorical('bootstrap_type', ['No', 'Bernoulli', 'MVS'])\n", + " # }\n", + "\n", + "\n", + " # create new model(and all parameters) every iteration\n", + " model = CatBoostRegressor(\n", + " # **params,\n", + " iterations=iterations,\n", + " # iterations=100,\n", + " learning_rate=learning_rate,\n", + " depth=depth,\n", + " min_data_in_leaf=min_data_in_leaf,\n", + " l2_leaf_reg=l2_leaf_reg,\n", + " random_strength=random_strength,\n", + " colsample_bylevel=colsample_bylevel,\n", + " subsample=subsample,\n", + " max_bin=max_bin,\n", + " bootstrap_type=bootstrap_type,\n", + " random_state=42,\n", + " verbose=0,\n", + " early_stopping_rounds=50\n", + " )\n", + " kf = KFold(n_splits=3, shuffle=True, random_state=42)\n", + " neg_mse = cross_val_score(\n", + " model, x_train_all, y_train_all, cv=kf,\n", + " scoring=\"neg_mean_squared_error\"\n", + " ).mean()\n", + " error = -neg_mse\n", + "\n", + " return error\n", + "\n", + "\n", + "# Create \"exploration\"\n", + "study = optuna.create_study(\n", + " direction=\"minimize\", study_name=\"Optimizer\", sampler=TPESampler(42)\n", + ")\n", + "\n", + "study.optimize(\n", + " objective, n_trials=20\n", + ") # The more iterations, the higher the chances of catching the most optimal hyperparameters\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "AXKpxM0rxzoH" + }, + "outputs": [], + "source": [ + "# x_train, x_val, y_train, y_val = train_test_split(x.values, y.values, test_size=0.2, random_state=42)\n", + "from sklearn.metrics import mean\n", + "\n", + "\n", + "def tuner(trial):\n", + " params = {\n", + " 'depth': trial.suggest_int('depth', 4, 10),\n", + " 'iterations': trial.suggest_int('iterations', 100, 1000),\n", + " 'learning_rate': trial.suggest_loguniform('learning_rate', 1e-3, 0.3),\n", + " 'colsample_bylevel': trial.suggest_uniform('colsample_bylevel', 0.5, 1.0),\n", + " 'subsample': trial.suggest_uniform('subsample', 0.5, 1.0),\n", + " 'l2_leaf_reg': trial.suggest_int('l2_leaf_reg', 1, 10),\n", + " 'min_data_in_leaf': trial.suggest_int('min_data_in_leaf', 1, 10),\n", + " 'max_bin': trial.suggest_int('max_bin', 10, 255),\n", + " 'random_strength': trial.suggest_uniform('random_strength', 1, 10),\n", + " 'bootstrap_type': trial.suggest_categorical('bootstrap_type', ['No', 'Bernoulli', 'MVS'])\n", + " }\n", + "\n", + "\n", + " model = CatBoostRegressor(verbose=0)\n", + " model.fit(x_train_all, y_train_all, eval_set=(x_test, y_test), early_stopping_rounds=50, use_best_model=True)\n", + "\n", + "\n", + " preds = model.predict(x_test)\n", + " mse = mean_squared_error(y_test, preds)\n", + "\n", + " return mse\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "hlNoL30zyB_i" + }, + "outputs": [], + "source": [ + "study = optuna.create_study(direction='minimize')\n", + "study.optimize(tuner, n_trials=20)\n", + "\n", + "\n", + "print(\"best parameters: \", study.best_params)\n", + "print(\"best MSE: \", study.best_value)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Xgstohg3fBT9" + }, + "outputs": [], + "source": [ + "study.best_params, study.best_value" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BMlLEJ18sLLW" + }, + "source": [ + "* Тестирую потихоньку тут после подбора на каждых 9 трайлах из-за трейсбеков (лучший рез-т дальше)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "qlsku72wqsAO" + }, + "outputs": [], + "source": [ + "tuned_model = CatBoostRegressor(random_seed=42, use_best_model=True, **study.best_params)\n", + "\n", + "tuned_model.fit(\n", + " x_train_all,\n", + " y_train_all,\n", + " eval_set=(x_test, y_test),\n", + " verbose=200,\n", + " early_stopping_rounds=100\n", + ")\n", + "\n", + "print(f\"\\nmse_score after tuning: {mse(y_test, tuned_model.predict(x_test)):.4f}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "J7DsnE1xropw" + }, + "source": [ + "* Лучший результат (MSE = 1.5374)\n", + "\n", + "* UPD. Лучший результат 1.5359 в предыдущей ячейке" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "v-tuNEoDkAcX" + }, + "outputs": [], + "source": [ + "tuned_model = CatBoostRegressor(random_seed=42, use_best_model=True, **study.best_params)\n", + "\n", + "tuned_model.fit(\n", + " x_train_all,\n", + " y_train_all,\n", + " eval_set=(x_test, y_test),\n", + " verbose=200,\n", + " early_stopping_rounds=100\n", + ")\n", + "\n", + "print(f\"\\nmse_score after tuning: {mse(y_test, tuned_model.predict(x_test)):.4f}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eCpBJz1-webL" + }, + "source": [ + "## Формат результата\n", + "\n", + "Значение `mse` с подобранными параметрами меньше, чем при стандартных параметрах." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Tncs7-RLwebL" + }, + "source": [ + "# Задание 5. Ансамблевое обучение (дополнительно)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9q-ofFGCwebL" + }, + "source": [ + "В данной задаче вам нужно диагностировать сердечное заболевание у людей по медицинским показателям ([Heart Disease 🛠️[doc]](https://www.kaggle.com/datasets/cherngs/heart-disease-cleveland-uci))." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cSCv91_5webL" + }, + "source": [ + "Установка и импорт необходимых библиотек:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "GtEtm4H-webM" + }, + "outputs": [], + "source": [ + "!pip install -q catboost\n", + "!pip install -q lightgbm==3.0" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "9onL70rhwebM" + }, + "outputs": [], + "source": [ + "import catboost\n", + "import lightgbm\n", + "import xgboost\n", + "import sklearn\n", + "import numpy as np\n", + "import pandas as pd\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "\n", + "from sklearn.svm import SVC\n", + "from sklearn.naive_bayes import GaussianNB\n", + "from sklearn.tree import DecisionTreeClassifier\n", + "from sklearn.neighbors import KNeighborsClassifier\n", + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn.model_selection import (\n", + " train_test_split,\n", + " cross_val_score,\n", + " KFold,\n", + ")\n", + "from sklearn.ensemble import (\n", + " RandomForestClassifier,\n", + " ExtraTreesClassifier,\n", + " VotingClassifier,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DJUh_blZwebM" + }, + "source": [ + "Загрузка датасета:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "NAj8rvoGwebM" + }, + "outputs": [], + "source": [ + "heart_dataset = pd.read_csv(\n", + " \"https://edunet.kea.su/repo/EduNet-web_dependencies/datasets/heart.csv\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Q66b2s5owebN" + }, + "outputs": [], + "source": [ + "x = heart_dataset.drop(\"target\", axis=1)\n", + "y = heart_dataset[\"target\"]\n", + "x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=42)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EqOj73tzwebN" + }, + "source": [ + "Обучите разнообразные классификаторы, приведенные ниже, а также ансамбль `VotingClassifier` из `sklearn.ensemble`, объединяющий эти классификаторы с помощью жесткого или мякого голосования (параметр `voting =` `\"hard\"` или `\"soft\"` соответственно). Оцените качество моделей с помощью кросс-валидации на тренировочном наборе, используя функцию `cross_val_score` и метрику `f1`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Atd1mHxMwebO" + }, + "outputs": [], + "source": [ + "rng = np.random.RandomState(42)\n", + "\n", + "dt = DecisionTreeClassifier(random_state=rng, max_depth=10, min_samples_leaf=10)\n", + "rf = RandomForestClassifier(n_estimators=50, random_state=rng)\n", + "etc = ExtraTreesClassifier(random_state=rng)\n", + "knn = KNeighborsClassifier(n_neighbors=5, weights=\"distance\")\n", + "svc_lin = SVC(kernel=\"linear\", probability=True, random_state=rng)\n", + "svc_rbf = SVC(kernel=\"rbf\", probability=True, random_state=rng)\n", + "cat = catboost.CatBoostClassifier(verbose=0, random_seed=42)\n", + "lgbm = lightgbm.LGBMClassifier(random_state=42, verbose=-1)\n", + "lgbm_rf = lightgbm.LGBMClassifier(\n", + " boosting_type=\"rf\", subsample_freq=1, subsample=0.7, random_state=42, verbose=-1\n", + ")\n", + "xgb = xgboost.XGBClassifier(random_state=42)\n", + "xgb_rf = xgboost.XGBRFClassifier(random_state=42)\n", + "lr = LogisticRegression(solver=\"liblinear\", max_iter=10000)\n", + "nb = GaussianNB()\n", + "\n", + "# Your code here\n", + "\n", + "voting_hard =\n", + "voting_soft =\n", + "# -----------\n", + "\n", + "\n", + "for model in [voting_hard, voting_soft]:\n", + " scores = cross_val_score(\n", + " model,\n", + " x_train,\n", + " y_train,\n", + " cv=KFold(n_splits=3, shuffle=True, random_state=rng),\n", + " scoring=\"f1\",\n", + " )\n", + " print(f\"{model.__class__.__name__}: {scores.mean():.4f}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "93PJbbhQwebO" + }, + "source": [ + "Вы можете заметить, что ансамбль показывает хорошее, но не лучшее качество предсказания, попробуем его улучшить. Как вы знаете, ансамбли работают лучше, когда модели, входящие в них, не скоррелированы друг с другом. Определите корреляцию предсказаний базовых моделей в ансамбле на тренировочном наборе и удалите из ансамбля те модели, чьи предсказания будут сильнее коррелировать с остальными. Можете модифицировать функцию `base_model_pair_correlation` из лекции." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "kCRlENI1webP" + }, + "outputs": [], + "source": [ + "# Your code here" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "i8owETDKwebP" + }, + "source": [ + "Создайте новый ансамбль на исправленном наборе моделей и оцените его качество с помощью кросс-валидации на тренировочном наборе, используя функцию `cross_val_score` и метрику `f1`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "UvNFICpwwebP" + }, + "outputs": [], + "source": [ + "# Your code here\n", + "\n", + "voting_hard_2 =\n", + "voting_soft_2 =\n", + "# ------------\n", + "\n", + "for model in [voting_hard_2, voting_soft_2]:\n", + " scores = cross_val_score(\n", + " model,\n", + " x_train,\n", + " y_train,\n", + " cv=KFold(n_splits=3, shuffle=True, random_state=rng),\n", + " scoring=\"f1\",\n", + " )\n", + " print(f\"{model.__class__.__name__}: {scores.mean():.4f}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nE4lZPMQwebR" + }, + "source": [ + "Обучите все получившиеся модели на тренировочном наборе и испытайте их качество на тестовом наборе. Получилось ли у улучшенных версий ансамблевого классификатора превзойти базовые модели, входящие в него, и свои предыдущие версии?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "yHJ0HaphwebR" + }, + "outputs": [], + "source": [ + "# Your code here" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "plBM3EorwebS" + }, + "source": [ + "Какие ансамбли работают лучше? Всегда ли больше моделей значит лучше?\n", + "\n", + "**Напишите вывод**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bjCCek3DwebS" + }, + "source": [ + "## Формат результата" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_2DU6GQswebS" + }, + "source": [ + "Получить значения качества для ансамблей и моделей." + ] + } + ], + "metadata": { + "colab": { + "provenance": [], + "toc_visible": true + }, + "kernelspec": { + "display_name": "DataSphere Kernel", + "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.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}