{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "i4MGAGZSqtd5" }, "source": [ "# Phystech@DataScience\n", "## Домашнее задание 2\n", "\n", "**Правила, прочитайте внимательно:**\n", "\n", "* Выполненную работу нужно отправить телеграм-боту `@thetahat_ds25_bot`. Для начала работы с ботом каждый раз отправляйте `/start`. Дождитесь подтверждения от бота, что он принял файл. Если подтверждения нет, то что-то не так. **Работы, присланные иным способом, не принимаются.**\n", "* Дедлайн см. в боте. После дедлайна работы не принимаются кроме случаев наличия уважительной причины.\n", "* Прислать нужно **ноутбук в формате `ipynb`**. Если вы строите интерактивные графики, их стоит прислать в формате html.\n", "* Следите за размером файлов. **Бот не может принимать файлы весом более 20 Мб.** Если файл получается больше, заранее разделите его на несколько.\n", "* Выполнять задание необходимо полностью самостоятельно. **При обнаружении списывания всем участникам списывания дается штраф -2 балла к итоговой оценке за семестр.**\n", "* Решения, размещенные на каких-либо интернет-ресурсах, не принимаются. Кроме того, публикация решения в открытом доступе может быть приравнена к предоставлении возможности списать.\n", "* Обратите внимание на правила использования ИИ-инструментов при решении домашнего задания.\n", "* **Код из рассказанных на занятиях ноутбуков** можно использовать без ограничений.\n", "* Для выполнения задания используйте этот ноутбук в качестве основы, ничего не удаляя из него. Можно добавлять необходимое количество ячеек.\n", "* Комментарии к решению пишите в markdown-ячейках.\n", "* Выполнение задания (ход решения, выводы и пр.) должно быть осуществлено на русском языке.\n", "* Решение проверяется системой ИИ-проверки **ThetaGrader**. Результат проверки валидируется и исправляется человеком, после чего комментарии отправляются студентам.\n", "* Если код будет не понятен проверяющему, оценка может быть снижена.\n", "* Никакой код из данного задания при проверке запускаться не будет. *Если код студента не выполнен, недописан и т.д., то он не оценивается.*\n", "\n", "Важно!!! Правила заполнения ноутбука:\n", "* Запрещается удалять имеющиеся в ноутбуке ячейки, менять местами положения задач.\n", "* Сохраняйте естественный линейный порядок повествования в ноутбуке сверху-вниз.\n", "* Отвечайте на вопросы, а также добавляйте новые ячейки в предложенных местах, которые обозначены `<...>`.\n", "* В markdown-ячейка, содержащих описание задачи, находятся специальные отметки, которые запрещается модифицировать.\n", "* При нарушении данных правил работа может получить 0 баллов.\n", "\n", "\n", "**Перед выполнением задания посмотрите презентацию по выполнению и оформлению домашних заданий с занятия 2.**\n", "\n", "\n", "**Баллы за задание:**\n", "\n", "\n", "* Задача 1 — 50 баллов\n", "* Задача 2 — 50 баллов\n", "* Задача 3 — 30 баллов\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "-----" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "WmDDSxlDeHco" }, "outputs": [], "source": [ "# Bot check\n", "\n", "# HW_ID: phds_hw2\n", "# Бот проверит этот ID и предупредит, если случайно сдать что-то не то\n", "\n", "# Status: not final\n", "# Перед отправкой в финальном решении удали \"not\" в строчке выше\n", "# Так бот проверит, что ты отправляешь финальную версию, а не промежуточную" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "nab2ZrRjqtd7" }, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.metrics import accuracy_score, mean_squared_error, mean_absolute_error, mean_absolute_percentage_error, r2_score\n", "from sklearn.linear_model import LinearRegression\n", "from sklearn.linear_model import LogisticRegression\n", "from sklearn.preprocessing import OneHotEncoder\n", "from sklearn.preprocessing import StandardScaler\n", "\n", "\n", "import warnings\n", "warnings.filterwarnings(\"ignore\")\n", "import seaborn as sns\n", "sns.set_theme(palette='Set2')" ] }, { "cell_type": "markdown", "metadata": { "id": "LWEjjNYqqtd8" }, "source": [ "### Легкая часть\n", " " ] }, { "cell_type": "markdown", "metadata": { "id": "GP6ZcRKLY3x7" }, "source": [ "---\n", "### Задача 1\n", "\n", "\n", "#### 1. Загрузка данных и предобработка" ] }, { "cell_type": "markdown", "metadata": { "ai_eval_tool": { "snippet_hash": "9c620b5e71dfb8e728703d73d13c9bc3", "snippet_label": "start" }, "id": "092qpasSqtd8" }, "source": [ "\n", "\n", "\n", "#### **Профиль биология**\n", "\n", "Загрузите [данные](https://www.kaggle.com/datasets/marshuu/breast-cancer) по предсказанию рака груди.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "kM9ctbRHqtd8" }, "outputs": [], "source": [ "data = pd.read_csv('breast_cancer_disbalances.csv')\n", "data.head()" ] }, { "cell_type": "markdown", "metadata": { "id": "5WUpYx_dqtd9" }, "source": [ "Проверьте, имеются ли в ваших данных пропуски. Если да, то удалите их.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "-3kv7xUiPprV" }, "outputs": [], "source": [ "..." ] }, { "cell_type": "markdown", "metadata": { "id": "EjG4E_KCqtd-" }, "source": [ "Библиотека `pandas` позволяет строить графики `matplotlib` для своих объектов `DataFrame` ([подробнее](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.plot.html)). Посмотрим, как распределены значения признака `Bare Nuclei` для разных классов:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "0s0RAiLsqtd-" }, "outputs": [], "source": [ "fig, axs = plt.subplots(1, 2, figsize=(10, 5))\n", "data.groupby(\"Class\")['Bare Nuclei'].hist(ax=axs[0], alpha=0.5)\n", "data.groupby(\"Class\")['Bare Nuclei'].plot(kind='kde', ax=axs[1])\n", "axs[0].set_title('Гистограмма для Bare Nuclei', fontsize=20)\n", "axs[1].set_title('KDE для Bare Nuclei', fontsize=20);" ] }, { "cell_type": "markdown", "metadata": { "id": "d3e4EfWJqtd-" }, "source": [ "Чем отличаются способы построения ЯОП и гистограммы? Какую информацию о наших данных можно извлечь из каждого графика?" ] }, { "cell_type": "markdown", "metadata": { "id": "61OjcvsXqtd-" }, "source": [ "**Ответ:**\n" ] }, { "cell_type": "markdown", "metadata": { "id": "A6onkGOGqtd_" }, "source": [ "Постройте гистограммы и ядерные оценки плотности для всех признаков из датасета отдельно для каждого класса. `Class` — целевая переменная. Можно это сделать, опираясь на код выше, а можно воспользоваться параметром `hue` у функции [`sns.histplot`](https://seaborn.pydata.org/generated/seaborn.histplot.html) или другим методом, который вам нравится. Не забывайте подписывать, к чему относится каждый график." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "_CLHMYqvU9Si" }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "id": "3u2Ircukqtd_" }, "source": [ "Какие выводы вы можете сделать из полученных графиков?" ] }, { "cell_type": "markdown", "metadata": { "ai_eval_tool": { "snippet_hash": "9c620b5e71dfb8e728703d73d13c9bc3", "snippet_label": "end" }, "id": "DUjghYGeqtd_" }, "source": [ "**Вывод:** ..." ] }, { "cell_type": "markdown", "metadata": { "id": "PbB9APbKP8Ps" }, "source": [ "\n", "\n", "**Это не конец задачи! Переходите к пункту 2!**" ] }, { "cell_type": "markdown", "metadata": { "ai_eval_tool": { "snippet_hash": "ca9029c0d916da0e69572b206fa25145", "snippet_label": "start" }, "id": "VEtE7q4Dqtd_" }, "source": [ "\n", "\n", "#### **Профиль физика**\n", "\n", "Загрузите данные по бинарной классификации астероидов в зависимости от различных параметров с сайта.\n", "\n", "Вашей целевой переменной будет являться столбец `pha`. Более подробно ознакомить с датасетом вы можете также [здесь](https://www.kaggle.com/datasets/sakhawat18/asteroid-dataset/data). Можно заметить, что наш датасет сильно меньше по размерам, чем оригинал. Это сделано намеренно." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "iT1Wl3F3qtd_" }, "outputs": [], "source": [ "data = pd.read_csv('asteroid_cut.csv')\n", "data.info()" ] }, { "cell_type": "markdown", "metadata": { "id": "Ohh2MuiHqtd_" }, "source": [ "Библиотека `pandas` позволяет строить графики `matplotlib` для своих объектов `DataFrame` ([подробнее](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.plot.html)). Посмотрим, как распределены значения признака `rms` для разных классов:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "mJPdRYQwqteA" }, "outputs": [], "source": [ "fig, axs = plt.subplots(1, 2, figsize=(10, 5))\n", "data.groupby(\"pha\")['rms'].hist(ax=axs[0], density=True)\n", "data.groupby(\"pha\")['rms'].plot(kind='kde', ax=axs[1])\n", "axs[0].set_title('Гистограмма для H', fontsize=20)\n", "axs[1].set_title('KDE для H', fontsize=20);" ] }, { "cell_type": "markdown", "metadata": { "id": "QXwE_hurqteA" }, "source": [ "Чем отличаются способы построения ЯОП и гистограммы? Какую информацию о наших данных можно извлечь из каждого графика?" ] }, { "cell_type": "markdown", "metadata": { "id": "hZlzLtTSqteA" }, "source": [ "**Ответ:** ...\n" ] }, { "cell_type": "markdown", "metadata": { "id": "0B27vJKoqteA" }, "source": [ "Постройте гистограммы и ядерные оценки плотности для указанных ниже признаков отдельно для каждого класса. `pha` — целевая переменная. Можно это сделать, опираясь на код выше, а можно воспользоваться параметром `hue` у функции [`sns.histplot`](https://seaborn.pydata.org/generated/seaborn.histplot.html) или другим методом, который вам нравится. Не забывайте подписывать, к чему относится каждый график.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "_wZcvPyWqteA" }, "outputs": [], "source": [ "features = ['epoch', 'ma', 'tp', 'rms']\n", "\n", "..." ] }, { "cell_type": "markdown", "metadata": { "id": "3zcMmW36qteA" }, "source": [ "Какие выводы вы можете сделать из полученный графиков?" ] }, { "cell_type": "markdown", "metadata": { "ai_eval_tool": { "snippet_hash": "ca9029c0d916da0e69572b206fa25145", "snippet_label": "end" }, "id": "WZ4kcZIiqteA" }, "source": [ "**Вывод:** ..." ] }, { "cell_type": "markdown", "metadata": { "ai_eval_tool": { "snippet_hash": "30a722e795d939966c91ff0a92cf86eb", "snippet_label": "start" }, "id": "w_ovzRYAqteA" }, "source": [ "\n", "\n", "#### 2. Обучение модели\n", "\n", "Продолжайте использовать выбранные вами данные." ] }, { "cell_type": "markdown", "metadata": { "id": "GxLTI2LQqteB" }, "source": [ "Создайте массив признаков и массив таргета. Разбейте ваши данные на обучающую и тестовую выборки в отношении 7:3." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "7ST_FJgVqteB" }, "outputs": [], "source": [ "X = ...\n", "y = ...\n", "X_train, X_test, y_train, y_test = ..." ] }, { "cell_type": "markdown", "metadata": { "id": "itjGzFWCqteB" }, "source": [ "Примените стандартизацию к обучающей и тестовой выборкам, используя класс `StandardScaler`, натренированный на обучающей выборке." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Rpi7SEbpqteB" }, "outputs": [], "source": [ "..." ] }, { "cell_type": "markdown", "metadata": { "id": "vFG3h0zUqteB" }, "source": [ "Объясните, что делает `StanderdScaler` и почему нельзя его нельзя обучать на тестовой выборке?" ] }, { "cell_type": "markdown", "metadata": { "id": "naP590nQqteB" }, "source": [ "**Ответ:**\n", "\n", "..." ] }, { "cell_type": "markdown", "metadata": { "id": "CakSs7aEqteB" }, "source": [ "Обучите модель логистической регрессии." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "TO6JT22zqteB" }, "outputs": [], "source": [ "..." ] }, { "cell_type": "markdown", "metadata": { "id": "vaJl9Yr8qteC" }, "source": [ "Сделайте предсказание для тестовой выборки и оцените качества полученного предсказания, используя метрику `accuracy_score`\n", "\n", "Если названия ваших классов отличаются от 0 и 1, то надо использовать `pos_label`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ai_eval_tool": { "snippet_hash": "30a722e795d939966c91ff0a92cf86eb", "snippet_label": "end" }, "id": "lU4rByMxqteC" }, "outputs": [], "source": [ "..." ] }, { "cell_type": "markdown", "metadata": { "ai_eval_tool": { "snippet_hash": "720b0d3dae956d90fb3ea500b9479d13", "snippet_label": "start" }, "id": "fpzWgAZMqteC" }, "source": [ "\n", "\n", "Можем ли порадоваться таким результатам? Вернемся к гистограммам и сделаем вывод, почему метрика оказалась такой большой.\n", "\n", "Давайте посмотрим на распределение наших данных по целевой переменной по всему датасету, тренировочной и тестовой выборках." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "51rxojIKqteC" }, "outputs": [], "source": [ "original = <...>.value_counts() # Колонка таргета из изначального датасета\n", "train = <...>.value_counts() # Колонка таргета из тренировочного датасета\n", "test = <...>.value_counts() # Колонка таргета из тестового датасета\n", "\n", "fig, axes = plt.subplots(1, 3, figsize=(15, 5))\n", "sns.barplot(x=original.index, y=original, ax=axes[0], palette=['blue'])\n", "axes[0].set_title('Распределение классов в data')\n", "axes[0].set_ylabel('Количество')\n", "\n", "sns.barplot(x=train.index, y=train, ax=axes[1], palette=['green'])\n", "axes[1].set_title('Распределение классов в train')\n", "\n", "sns.barplot(x=test.index, y=test, ax=axes[2], palette=['orange'])\n", "axes[2].set_title('Распределение классов в test')\n", "\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "id": "OadSCTKRqteD" }, "source": [ "Видно, что в данных есть сильный перекос — классы представлены неравномерно. Как и почему это может повлиять на наши результаты?" ] }, { "cell_type": "markdown", "metadata": { "ai_eval_tool": { "snippet_hash": "720b0d3dae956d90fb3ea500b9479d13", "snippet_label": "end" }, "id": "1ERKEkM_qteD" }, "source": [ "**Ответ:** ..." ] }, { "cell_type": "markdown", "metadata": { "ai_eval_tool": { "snippet_hash": "27d23fce3fb2cb6960814deb0a13d80b", "snippet_label": "start" }, "id": "zE_mWlc6qteD" }, "source": [ "\n", "\n", "Есть много способов борьбы с этим. Можно искусственно сгенерировать данные нужного класса или урезать другой класс. Однако сегодня мы воспользуемся ***взвешенной*** логистической регрессией. Суть метода в том, что мы вручную поставим веса для классов, исходя из их предполагаемой природы: важность разных классов, цена ошибки в реальной жизни(например, что лучше, предсказать наличие рака, если он есть или нет?) и представленность данных.\n", "\n", "Кросс-энтропия для взвешенной логистической регресси будет записана как:\n", "\n", "$$\n", "F(\\theta) = \\sum_{i=1}^{n} H(y_i, \\widehat{y}_i) = -\\sum_{i=1}^{n} w_{y_i} \\left[ y_i \\log(\\widehat{y}_i) + (1-y_i) \\log(1-\\widehat{y}_i) \\right]\n", "$$\n", "\n", "где:\n", "\n", "- $ y_i $ - истинный класс для образца $i$\n", "- $ \\widehat{y}_i = \\sigma(\\theta^Tx_i)$ - предсказанный класс для образца $i$\n", "- $ w_{y_i} $ - вес класса\n", "\n", "\n", "\n", "Давайте применим этот подход на практике. Воспользуемся параметром `class_weight`. Для начала определим количество примеров каждого класса в обучающей выборке и вычислим их соотношение." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "TkXw6-AZo7kI" }, "outputs": [], "source": [ "..." ] }, { "cell_type": "markdown", "metadata": { "id": "_Fwpza1YpmE9" }, "source": [ "Применим рассчитанное соотношение классов в качестве весов:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "witXjZQnqteD" }, "outputs": [], "source": [ "threshold = ...\n", "class_weights = {<класс_1>: threshold, <класс_2>: 1 - threshold}\n", "# если использовать class_weights = 'balanced' модель сама подсчитает веса\n", "\n", "weighted_model = LogisticRegression(class_weight=class_weights, random_state=0)\n", "..." ] }, { "cell_type": "markdown", "metadata": { "id": "z7jLyCj7SFUy" }, "source": [ "Посчитаем метрику `accuracy_score`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "K07hvv4wR7ii" }, "outputs": [], "source": [ "accuracy = ...\n", "print(f\"accuracy = {accuracy}\")" ] }, { "cell_type": "markdown", "metadata": { "id": "QUa7wWjOqteE" }, "source": [ "Как изменилось качество нашей модели?\n", "\n", "Сделайте общий вывод по задаче." ] }, { "cell_type": "markdown", "metadata": { "ai_eval_tool": { "snippet_hash": "27d23fce3fb2cb6960814deb0a13d80b", "snippet_label": "end" }, "id": "KxPjxdMgqteE" }, "source": [ "**Вывод:**" ] }, { "cell_type": "markdown", "metadata": { "ai_eval_tool": { "snippet_hash": "d47d648e3e531cd82a72ebefc5133104", "snippet_label": "start" }, "id": "UPcUqqJHYgGu" }, "source": [ "\n", "\n", "---\n", "### Задача 2\n", "\n", "\n", "#### Датасет penguins\n", "В первой части задания мы познакомимся с новым для нас датасетом" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "KzwbvpTaYGDE" }, "outputs": [], "source": [ "penguins = pd.read_csv('penguins.csv')\n", "penguins.head()" ] }, { "cell_type": "markdown", "metadata": { "id": "Tc1kVcbdZbPp" }, "source": [ "> ⚠️ **Warning:** Лучше не нажимать на пингвинов\n" ] }, { "cell_type": "markdown", "metadata": { "id": "gdyoXgYKZbM8" }, "source": [ "Здесь содержатся данные о морфололгии пингвинов трех различных видов: Adelie, Chinstrap, и Gentoo." ] }, { "cell_type": "markdown", "metadata": { "id": "-_NVK0gdb5Bl" }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "id": "VqCf9EZgb4_I" }, "source": [ "Оставшеися колонки: `bill_length_mm`, `bill_depth_mm`, `flipper_length_mm`, `body_mass_g` описывают морфологию каждого пингвина." ] }, { "cell_type": "markdown", "metadata": { "id": "tq3DaCSRb48o" }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "id": "z9c3uyNRb46T" }, "source": [ "Как мы видим, в данном датасете присутствуют категориальные переменные: `species`, `island` и `sex`, которые не могут быть оценены моделью линейной регресии. Закодируйте их: к переменным, где присутствует более трёх категорий, примените преобразование `OneHotEncoder`. Обратите внимание на аргумент [`drop`](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "vg-v3uqvcMi1" }, "outputs": [], "source": [ "cat_features = [...]\n", "\n", "onehotencoder = ...\n", "encoded = pd.DataFrame(onehotencoder.fit_transform(...), dtype=int)\n", "\n", "penguins_encoded = penguins.drop(cat_features, axis=1).join(...)\n", "penguins_encoded = penguins_encoded.rename(str, axis=\"columns\")\n", "\n", "penguins_encoded.head()" ] }, { "cell_type": "markdown", "metadata": { "id": "vS5U7q37cPlB" }, "source": [ "Выберем в качестве таргета вес пингвинов (`body_mass_g`), и разделим нашу выборку на тренировочную и тестовую:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ai_eval_tool": { "snippet_hash": "d47d648e3e531cd82a72ebefc5133104", "snippet_label": "end" }, "id": "wT-CUn10cPaT" }, "outputs": [], "source": [ "X = penguins_encoded.drop('body_mass_g', axis=1)\n", "y = penguins_encoded['body_mass_g']\n", "X_train, X_test, y_train, y_test = ..." ] }, { "cell_type": "markdown", "metadata": { "ai_eval_tool": { "snippet_hash": "609f7e6bc983c66d5814592a5352a7e0", "snippet_label": "start" }, "id": "a1wOR3nVcS-c" }, "source": [ "\n", "\n", "Реализуйте линейную регрессию самостоятельно, используя формулы с лекции.\n", "Вам нужно только заполнить прочерки в методах `fit` и `predict`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "qBeb_uF9cMfm" }, "outputs": [], "source": [ "class MyLinearRegression:\n", " \"\"\"\n", " Класс, реализующий линейную регрессию c помощью МНК.\n", " \"\"\"\n", "\n", " def __init__(self):\n", " pass\n", "\n", " def fit(self, X, Y):\n", " \"\"\"\n", " Функция обучения модели.\n", "\n", " Предполагается модель Y = X * theta + epsilon.\n", " где X --- регрессор (матрица размера n x d),\n", " Y --- отклик (матрица размера n x 1),\n", " epsilon-ы имеют нормальное распределение\n", "\n", " Обратите внимание, здесь нет intercept_\n", " \"\"\"\n", "\n", " self.n, self.d = X.shape[0], X.shape[1]\n", "\n", " self.theta = МНК-оценка\n", "\n", " return ...\n", "\n", "\n", " def predict(self, X):\n", " \"\"\"\n", " Возвращает предсказание отклика на новых объектах X.\n", "\n", " X --- матрица объектов размера n x d\n", " \"\"\"\n", "\n", " y_pred = ...\n", " return ..." ] }, { "cell_type": "markdown", "metadata": { "id": "sEYv4FQBcYDY" }, "source": [ "Обучите вашу модель на датасете о пингвинах **без** добавления свободного члена.\n", "Распечатайте коэффициенты и сравните их с коэффициентами модели из `sklearn`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "tvgV1eIYcMYq" }, "outputs": [], "source": [ "MyModel = ...\n", "\n", "..." ] }, { "cell_type": "markdown", "metadata": { "id": "kYBcoSaP1HX-" }, "source": [ "Как соотносятся коэффициенты вашей модели и реализации из `sklearn`?\n", "\n", "**Ответ:** ..." ] }, { "cell_type": "markdown", "metadata": { "id": "DfdsFy-Xb44H" }, "source": [ "Теперь обучите собственную модель **c** добавлением свободного члена." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ai_eval_tool": { "snippet_hash": "609f7e6bc983c66d5814592a5352a7e0", "snippet_label": "end" }, "id": "ne1RsKoQYEoq" }, "outputs": [], "source": [ "..." ] }, { "cell_type": "markdown", "metadata": { "ai_eval_tool": { "snippet_hash": "cf209df06ad3ab80411542037954e29d", "snippet_label": "start" }, "id": "VYp3PROLchG3" }, "source": [ "\n", "\n", "Помимо рассмотренных на семенаре метрик, довольно часто рассматривают [коэфициент детерминации](https://en.wikipedia.org/wiki/Coefficient_of_determination) $R^2$, который может быть более интуитивным." ] }, { "cell_type": "markdown", "metadata": { "id": "GeFRusKLchz3" }, "source": [ "Определяется он так:\n", "$$\n", " R^2 = 1 - \\frac{SS_{reg}}{SS_{tot}},\n", "$$\n", "где $SS_{res} = \\sum\\limits_{i=1}^n (y_i - f_i)^2$ отражает точность нашей модели, \n", "a $SS_{tot} = \\sum\\limits_{i=1}^n (y_i - \\overline{y})^2$ отражает дисперсию исходных данных. \n", "Соответсвенно чем результат ближе к еденице тем более точная у нас модель и тем лучше она предсказывает. Отрицательный же результат можем получить в случае, если наша модель предсказывает хуже, чем предсказание средним." ] }, { "cell_type": "markdown", "metadata": { "id": "GZWOkqincnJl" }, "source": [ "В `sklearn` есть готовая [реализация](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.r2_score.html) под названием `r2_score`" ] }, { "cell_type": "markdown", "metadata": { "id": "hnP7xCRVcp81" }, "source": [ "Сравните качество моделей со свободным членом и без него на тестовой выборке, используя метрики RMSE, MAE, MAPE и $R^2$." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "qiJYLO8Tcpch" }, "outputs": [], "source": [ "..." ] }, { "cell_type": "markdown", "metadata": { "id": "MEHQ-Br3dL3a" }, "source": [ "**Сделайте выводы**" ] }, { "cell_type": "markdown", "metadata": { "ai_eval_tool": { "snippet_hash": "cf209df06ad3ab80411542037954e29d", "snippet_label": "end" }, "id": "Se26zaCadLvR" }, "source": [ "**Вывод:** ..." ] }, { "cell_type": "markdown", "metadata": { "id": "8mdmZ1EWoKSt" }, "source": [ "\n", "\n", "---\n", "### Задача 3\n", "\n", "Во взвешенном методе наименьших квадратов каждому наблюдению задается некоторый известный вес $w_i$. Задача имеет вид: $$\\sum\\limits_{i=1}^n w_i\\left(Y_i - x_i^T \\theta\\right)^2 \\to \\min\\limits_\\theta$$ Найдите решение задачи в матричном виде.\n" ] } ], "metadata": { "colab": { "provenance": [], "toc_visible": true }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.9.19" } }, "nbformat": 4, "nbformat_minor": 0 }