You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ML-For-Beginners/translations/ru/2-Regression/4-Logistic/solution/R/lesson_4-R.ipynb

685 lines
43 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Построение модели логистической регрессии - Урок 4\n",
"\n",
"![Инфографика: Логистическая vs. линейная регрессия](../../../../../../translated_images/linear-vs-logistic.ba180bf95e7ee66721ba10ebf2dac2666acbd64a88b003c83928712433a13c7d.ru.png)\n",
"\n",
"#### **[Тест перед лекцией](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/15/)**\n",
"\n",
"#### Введение\n",
"\n",
"В этом заключительном уроке по регрессии, одной из базовых *классических* техник машинного обучения, мы рассмотрим логистическую регрессию. Этот метод используется для выявления закономерностей и предсказания бинарных категорий. Это конфета с шоколадом или без? Это заболевание заразное или нет? Выберет ли клиент этот продукт или нет?\n",
"\n",
"В этом уроке вы узнаете:\n",
"\n",
"- Методы логистической регрессии\n",
"\n",
"✅ Углубите свои знания о работе с этим типом регрессии в этом [модуле обучения](https://learn.microsoft.com/training/modules/introduction-classification-models/?WT.mc_id=academic-77952-leestott)\n",
"\n",
"## Предварительные знания\n",
"\n",
"Работая с данными о тыквах, мы уже достаточно с ними знакомы, чтобы понять, что есть одна бинарная категория, с которой мы можем работать: `Color`.\n",
"\n",
"Давайте построим модель логистической регрессии, чтобы предсказать, *какого цвета, скорее всего, будет данная тыква* (оранжевая 🎃 или белая 👻).\n",
"\n",
"> Почему мы говорим о бинарной классификации в уроке, посвященном регрессии? Только для удобства терминологии, так как логистическая регрессия [на самом деле является методом классификации](https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression), хотя и основанным на линейных принципах. Узнайте о других способах классификации данных в следующей группе уроков.\n",
"\n",
"Для этого урока нам понадобятся следующие пакеты:\n",
"\n",
"- `tidyverse`: [tidyverse](https://www.tidyverse.org/) — это [набор пакетов для R](https://www.tidyverse.org/packages), разработанных для того, чтобы сделать работу с данными быстрее, проще и увлекательнее!\n",
"\n",
"- `tidymodels`: [tidymodels](https://www.tidymodels.org/) — это [фреймворк пакетов](https://www.tidymodels.org/packages/) для моделирования и машинного обучения.\n",
"\n",
"- `janitor`: [Пакет janitor](https://github.com/sfirke/janitor) предоставляет простые инструменты для анализа и очистки \"грязных\" данных.\n",
"\n",
"- `ggbeeswarm`: [Пакет ggbeeswarm](https://github.com/eclarke/ggbeeswarm) позволяет создавать диаграммы в стиле \"роя пчел\" с использованием ggplot2.\n",
"\n",
"Вы можете установить их с помощью команды:\n",
"\n",
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"ggbeeswarm\"))`\n",
"\n",
"Или же используйте следующий скрипт, который проверяет наличие необходимых пакетов и устанавливает их, если они отсутствуют.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"suppressWarnings(if (!require(\"pacman\"))install.packages(\"pacman\"))\n",
"\n",
"pacman::p_load(tidyverse, tidymodels, janitor, ggbeeswarm)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **Определение вопроса**\n",
"\n",
"Для наших целей мы будем выражать это как бинарный выбор: «Белый» или «Не белый». В нашем наборе данных также есть категория «полосатый», но случаев с ней очень мало, поэтому мы не будем ее использовать. Она исчезает, как только мы удаляем пустые значения из набора данных.\n",
"\n",
"> 🎃 Забавный факт: иногда мы называем белые тыквы «призрачными» тыквами. Их сложно вырезать, поэтому они не так популярны, как оранжевые, но выглядят они круто! Таким образом, мы могли бы переформулировать наш вопрос как: «Призрачная» или «Не призрачная». 👻\n",
"\n",
"## **О логистической регрессии**\n",
"\n",
"Логистическая регрессия отличается от линейной регрессии, о которой вы узнали ранее, несколькими важными аспектами.\n",
"\n",
"#### **Бинарная классификация**\n",
"\n",
"Логистическая регрессия не предлагает тех же возможностей, что и линейная регрессия. Первая предоставляет прогноз о `бинарной категории` («оранжевая или не оранжевая»), тогда как вторая способна предсказывать `непрерывные значения`, например, исходя из происхождения тыквы и времени сбора урожая, *насколько вырастет ее цена*.\n",
"\n",
"![Инфографика от Dasani Madipalli](../../../../../../translated_images/pumpkin-classifier.562771f104ad5436b87d1c67bca02a42a17841133556559325c0a0e348e5b774.ru.png)\n",
"\n",
"### Другие классификации\n",
"\n",
"Существуют и другие типы логистической регрессии, включая мультиномиальную и порядковую:\n",
"\n",
"- **Мультиномиальная**, которая включает более одной категории — «Оранжевая, Белая и Полосатая».\n",
"\n",
"- **Порядковая**, которая включает упорядоченные категории, полезные, если мы хотим логически упорядочить наши результаты, например, тыквы, которые упорядочены по конечному числу размеров (мини, маленький, средний, большой, очень большой, гигантский).\n",
"\n",
"![Мультиномиальная vs порядковая регрессия](../../../../../../translated_images/multinomial-vs-ordinal.36701b4850e37d86c9dd49f7bef93a2f94dbdb8fe03443eb68f0542f97f28f29.ru.png)\n",
"\n",
"#### **Переменные НЕ обязаны коррелировать**\n",
"\n",
"Помните, как линейная регрессия работала лучше с более коррелированными переменными? Логистическая регрессия — противоположность: переменные не обязаны совпадать. Это подходит для наших данных, которые имеют довольно слабую корреляцию.\n",
"\n",
"#### **Нужно много чистых данных**\n",
"\n",
"Логистическая регрессия даст более точные результаты, если использовать больше данных; наш небольшой набор данных не является оптимальным для этой задачи, так что имейте это в виду.\n",
"\n",
"✅ Подумайте о типах данных, которые хорошо подходят для логистической регрессии.\n",
"\n",
"## Упражнение — приведение данных в порядок\n",
"\n",
"Сначала немного очистите данные, удалив пустые значения и выбрав только некоторые столбцы:\n",
"\n",
"1. Добавьте следующий код:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Load the core tidyverse packages\n",
"library(tidyverse)\n",
"\n",
"# Import the data and clean column names\n",
"pumpkins <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/2-Regression/data/US-pumpkins.csv\") %>% \n",
" clean_names()\n",
"\n",
"# Select desired columns\n",
"pumpkins_select <- pumpkins %>% \n",
" select(c(city_name, package, variety, origin, item_size, color)) \n",
"\n",
"# Drop rows containing missing values and encode color as factor (category)\n",
"pumpkins_select <- pumpkins_select %>% \n",
" drop_na() %>% \n",
" mutate(color = factor(color))\n",
"\n",
"# View the first few rows\n",
"pumpkins_select %>% \n",
" slice_head(n = 5)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Вы всегда можете взглянуть на ваш новый датафрейм, используя функцию [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html), как показано ниже:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"pumpkins_select %>% \n",
" glimpse()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Давайте подтвердим, что мы действительно будем решать задачу бинарной классификации:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Subset distinct observations in outcome column\n",
"pumpkins_select %>% \n",
" distinct(color)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Визуализация - категориальный график\n",
"На данный момент вы снова загрузили данные о тыквах и очистили их, чтобы сохранить набор данных, содержащий несколько переменных, включая Color. Давайте визуализируем этот датафрейм в ноутбуке, используя библиотеку ggplot.\n",
"\n",
"Библиотека ggplot предлагает удобные способы визуализации данных. Например, вы можете сравнить распределения данных для каждого Variety и Color на категориальном графике.\n",
"\n",
"1. Создайте такой график, используя функцию geombar, наши данные о тыквах и указав цветовую схему для каждой категории тыкв (оранжевые или белые):\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "python"
}
},
"outputs": [],
"source": [
"# Specify colors for each value of the hue variable\n",
"palette <- c(ORANGE = \"orange\", WHITE = \"wheat\")\n",
"\n",
"# Create the bar plot\n",
"ggplot(pumpkins_select, aes(y = variety, fill = color)) +\n",
" geom_bar(position = \"dodge\") +\n",
" scale_fill_manual(values = palette) +\n",
" labs(y = \"Variety\", fill = \"Color\") +\n",
" theme_minimal()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"По данным видно, как информация о Цвете соотносится с Разновидностью.\n",
"\n",
"✅ Учитывая этот категориальный график, какие интересные исследования вы можете представить?\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Предобработка данных: кодирование признаков\n",
"\n",
"Наш набор данных о тыквах содержит строковые значения во всех своих столбцах. Работа с категориальными данными интуитивно понятна для людей, но не для машин. Алгоритмы машинного обучения лучше работают с числами. Именно поэтому кодирование является очень важным этапом на этапе предобработки данных, так как оно позволяет преобразовать категориальные данные в числовые, не теряя при этом информации. Хорошее кодирование способствует созданию качественной модели.\n",
"\n",
"Для кодирования признаков существуют два основных типа кодировщиков:\n",
"\n",
"1. Ordinal encoder: хорошо подходит для порядковых переменных, то есть категориальных переменных, данные которых имеют логическую последовательность, как, например, столбец `item_size` в нашем наборе данных. Он создает отображение, где каждая категория представлена числом, соответствующим порядку категории в столбце.\n",
"\n",
"2. Categorical encoder: хорошо подходит для номинальных переменных, то есть категориальных переменных, данные которых не имеют логической последовательности, как, например, все признаки, кроме `item_size`, в нашем наборе данных. Это кодирование с использованием метода \"one-hot\", что означает, что каждая категория представлена бинарным столбцом: закодированная переменная равна 1, если тыква принадлежит данной разновидности, и 0 в противном случае.\n",
"\n",
"Tidymodels предоставляет еще один удобный пакет: [recipes](https://recipes.tidymodels.org/) — пакет для предобработки данных. Мы определим `recipe`, который указывает, что все столбцы предикторов должны быть закодированы в набор целых чисел, затем `prep`, чтобы оценить необходимые величины и статистики для любых операций, и, наконец, `bake`, чтобы применить вычисления к новым данным.\n",
"\n",
"> Обычно recipes используется как инструмент предобработки для моделирования, где он определяет, какие шаги должны быть применены к набору данных, чтобы подготовить его к моделированию. В этом случае **настоятельно рекомендуется** использовать `workflow()` вместо ручной оценки рецепта с помощью prep и bake. Мы рассмотрим это чуть позже.\n",
">\n",
"> Однако сейчас мы используем recipes + prep + bake, чтобы указать, какие шаги должны быть применены к набору данных для его подготовки к анализу данных, а затем извлечь предобработанные данные с примененными шагами.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Preprocess and extract data to allow some data analysis\n",
"baked_pumpkins <- recipe(color ~ ., data = pumpkins_select) %>%\n",
" # Define ordering for item_size column\n",
" step_mutate(item_size = ordered(item_size, levels = c('sml', 'med', 'med-lge', 'lge', 'xlge', 'jbo', 'exjbo'))) %>%\n",
" # Convert factors to numbers using the order defined above (Ordinal encoding)\n",
" step_integer(item_size, zero_based = F) %>%\n",
" # Encode all other predictors using one hot encoding\n",
" step_dummy(all_nominal(), -all_outcomes(), one_hot = TRUE) %>%\n",
" prep(data = pumpkin_select) %>%\n",
" bake(new_data = NULL)\n",
"\n",
"# Display the first few rows of preprocessed data\n",
"baked_pumpkins %>% \n",
" slice_head(n = 5)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"✅ Каковы преимущества использования порядкового кодировщика для столбца Item Size?\n",
"\n",
"### Анализ взаимосвязей между переменными\n",
"\n",
"Теперь, когда мы предварительно обработали данные, мы можем проанализировать взаимосвязи между признаками и меткой, чтобы понять, насколько хорошо модель сможет предсказывать метку на основе признаков. Лучший способ провести такой анализ — это визуализация данных. \n",
"Мы снова будем использовать функцию ggplot geom_boxplot_, чтобы визуализировать взаимосвязи между Item Size, Variety и Color в категориальном графике. Для более наглядного отображения данных мы будем использовать закодированный столбец Item Size и некодированный столбец Variety.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Define the color palette\n",
"palette <- c(ORANGE = \"orange\", WHITE = \"wheat\")\n",
"\n",
"# We need the encoded Item Size column to use it as the x-axis values in the plot\n",
"pumpkins_select_plot<-pumpkins_select\n",
"pumpkins_select_plot$item_size <- baked_pumpkins$item_size\n",
"\n",
"# Create the grouped box plot\n",
"ggplot(pumpkins_select_plot, aes(x = `item_size`, y = color, fill = color)) +\n",
" geom_boxplot() +\n",
" facet_grid(variety ~ ., scales = \"free_x\") +\n",
" scale_fill_manual(values = palette) +\n",
" labs(x = \"Item Size\", y = \"\") +\n",
" theme_minimal() +\n",
" theme(strip.text = element_text(size = 12)) +\n",
" theme(axis.text.x = element_text(size = 10)) +\n",
" theme(axis.title.x = element_text(size = 12)) +\n",
" theme(axis.title.y = element_blank()) +\n",
" theme(legend.position = \"bottom\") +\n",
" guides(fill = guide_legend(title = \"Color\")) +\n",
" theme(panel.spacing = unit(0.5, \"lines\"))+\n",
" theme(strip.text.y = element_text(size = 4, hjust = 0)) \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Используйте график роя\n",
"\n",
"Поскольку Color — это бинарная категория (Белый или Не белый), для её визуализации требуется '[специализированный подход](https://github.com/rstudio/cheatsheets/blob/main/data-visualization.pdf)'.\n",
"\n",
"Попробуйте использовать `график роя`, чтобы показать распределение цвета в зависимости от item_size.\n",
"\n",
"Мы будем использовать [пакет ggbeeswarm](https://github.com/eclarke/ggbeeswarm), который предоставляет методы для создания графиков в стиле \"роя\" с использованием ggplot2. Графики роя позволяют отображать точки, которые обычно накладывались бы друг на друга, так, чтобы они располагались рядом друг с другом.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Create beeswarm plots of color and item_size\n",
"baked_pumpkins %>% \n",
" mutate(color = factor(color)) %>% \n",
" ggplot(mapping = aes(x = color, y = item_size, color = color)) +\n",
" geom_quasirandom() +\n",
" scale_color_brewer(palette = \"Dark2\", direction = -1) +\n",
" theme(legend.position = \"none\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Теперь, когда мы понимаем связь между бинарными категориями цвета и более крупной группой размеров, давайте изучим логистическую регрессию, чтобы определить вероятный цвет тыквы.\n",
"\n",
"## Создайте свою модель\n",
"\n",
"Выберите переменные, которые вы хотите использовать в своей классификационной модели, и разделите данные на обучающую и тестовую выборки. [rsample](https://rsample.tidymodels.org/), пакет из Tidymodels, предоставляет инфраструктуру для эффективного разделения данных и повторного выборочного анализа:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Split data into 80% for training and 20% for testing\n",
"set.seed(2056)\n",
"pumpkins_split <- pumpkins_select %>% \n",
" initial_split(prop = 0.8)\n",
"\n",
"# Extract the data in each split\n",
"pumpkins_train <- training(pumpkins_split)\n",
"pumpkins_test <- testing(pumpkins_split)\n",
"\n",
"# Print out the first 5 rows of the training set\n",
"pumpkins_train %>% \n",
" slice_head(n = 5)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"🙌 Теперь мы готовы обучить модель, сопоставив обучающие признаки с обучающей меткой (цветом).\n",
"\n",
"Начнем с создания рецепта, который определяет шаги предварительной обработки данных, чтобы подготовить их для моделирования, например: кодирование категориальных переменных в набор целых чисел. Подобно `baked_pumpkins`, мы создаем `pumpkins_recipe`, но не используем `prep` и `bake`, так как это будет включено в рабочий процесс, который вы увидите через несколько шагов.\n",
"\n",
"Существует довольно много способов задать модель логистической регрессии в Tidymodels. См. `?logistic_reg()`. На данный момент мы зададим модель логистической регрессии через стандартный движок `stats::glm()`.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Create a recipe that specifies preprocessing steps for modelling\n",
"pumpkins_recipe <- recipe(color ~ ., data = pumpkins_train) %>% \n",
" step_mutate(item_size = ordered(item_size, levels = c('sml', 'med', 'med-lge', 'lge', 'xlge', 'jbo', 'exjbo'))) %>%\n",
" step_integer(item_size, zero_based = F) %>% \n",
" step_dummy(all_nominal(), -all_outcomes(), one_hot = TRUE)\n",
"\n",
"# Create a logistic model specification\n",
"log_reg <- logistic_reg() %>% \n",
" set_engine(\"glm\") %>% \n",
" set_mode(\"classification\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Теперь, когда у нас есть рецепт и спецификация модели, нам нужно найти способ объединить их в один объект, который сначала будет предварительно обрабатывать данные (prep+bake за кулисами), обучать модель на предварительно обработанных данных, а также предоставлять возможность для потенциальных действий по постобработке.\n",
"\n",
"В Tidymodels этот удобный объект называется [`workflow`](https://workflows.tidymodels.org/) и удобно хранит ваши компоненты моделирования.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Bundle modelling components in a workflow\n",
"log_reg_wf <- workflow() %>% \n",
" add_recipe(pumpkins_recipe) %>% \n",
" add_model(log_reg)\n",
"\n",
"# Print out the workflow\n",
"log_reg_wf\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"После того как рабочий процесс *задан*, модель можно `обучить` с помощью функции [`fit()`](https://tidymodels.github.io/parsnip/reference/fit.html). Рабочий процесс оценит рецепт и предварительно обработает данные перед обучением, поэтому нам не придется делать это вручную с использованием prep и bake.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Train the model\n",
"wf_fit <- log_reg_wf %>% \n",
" fit(data = pumpkins_train)\n",
"\n",
"# Print the trained workflow\n",
"wf_fit\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Модель выводит коэффициенты, полученные в процессе обучения.\n",
"\n",
"Теперь, когда мы обучили модель на тренировочных данных, мы можем делать прогнозы на тестовых данных, используя [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html). Давайте начнем с использования модели для предсказания меток для нашего тестового набора и вероятностей для каждой метки. Если вероятность больше 0.5, предсказанный класс — `WHITE`, в противном случае — `ORANGE`.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Make predictions for color and corresponding probabilities\n",
"results <- pumpkins_test %>% select(color) %>% \n",
" bind_cols(wf_fit %>% \n",
" predict(new_data = pumpkins_test)) %>%\n",
" bind_cols(wf_fit %>%\n",
" predict(new_data = pumpkins_test, type = \"prob\"))\n",
"\n",
"# Compare predictions\n",
"results %>% \n",
" slice_head(n = 10)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Очень интересно! Это дает больше понимания того, как работает логистическая регрессия.\n",
"\n",
"### Лучшее понимание через матрицу ошибок\n",
"\n",
"Сравнение каждого предсказания с соответствующим \"истинным\" значением — не самый эффективный способ определить, насколько хорошо модель делает прогнозы. К счастью, у Tidymodels есть еще несколько полезных инструментов: [`yardstick`](https://yardstick.tidymodels.org/) — пакет, который используется для оценки эффективности моделей с помощью метрик производительности.\n",
"\n",
"Одна из метрик производительности, связанная с задачами классификации, — это [`матрица ошибок`](https://wikipedia.org/wiki/Confusion_matrix). Матрица ошибок описывает, насколько хорошо справляется модель классификации. Она показывает, сколько примеров из каждого класса были правильно классифицированы моделью. В нашем случае она покажет, сколько оранжевых тыкв были классифицированы как оранжевые, а сколько белых тыкв — как белые; матрица ошибок также покажет, сколько объектов были отнесены к **неверным** категориям.\n",
"\n",
"Функция [**`conf_mat()`**](https://tidymodels.github.io/yardstick/reference/conf_mat.html) из пакета yardstick вычисляет эту перекрестную таблицу наблюдаемых и предсказанных классов.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Confusion matrix for prediction results\n",
"conf_mat(data = results, truth = color, estimate = .pred_class)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Давайте разберем матрицу ошибок. Наша модель должна классифицировать тыквы на две бинарные категории: категория `белая` и категория `не-белая`.\n",
"\n",
"- Если ваша модель предсказывает, что тыква белая, и она действительно относится к категории \"белая\", это называется `истинно положительное` (true positive), что отображается в верхнем левом углу.\n",
"\n",
"- Если ваша модель предсказывает, что тыква не белая, но на самом деле она относится к категории \"белая\", это называется `ложно отрицательное` (false negative), что отображается в нижнем левом углу.\n",
"\n",
"- Если ваша модель предсказывает, что тыква белая, но на самом деле она относится к категории \"не-белая\", это называется `ложно положительное` (false positive), что отображается в верхнем правом углу.\n",
"\n",
"- Если ваша модель предсказывает, что тыква не белая, и она действительно относится к категории \"не-белая\", это называется `истинно отрицательное` (true negative), что отображается в нижнем правом углу.\n",
"\n",
"| Истина |\n",
"|:-----:|\n",
"\n",
"| | | |\n",
"|---------------|--------|-------|\n",
"| **Предсказано** | БЕЛАЯ | ОРАНЖЕВАЯ |\n",
"| БЕЛАЯ | TP | FP |\n",
"| ОРАНЖЕВАЯ | FN | TN |\n",
"\n",
"Как вы могли догадаться, желательно иметь больше истинно положительных и истинно отрицательных значений, а также меньше ложно положительных и ложно отрицательных значений, что указывает на лучшее качество работы модели.\n",
"\n",
"Матрица ошибок полезна, так как она позволяет вычислить другие метрики, которые помогают лучше оценить производительность классификационной модели. Давайте рассмотрим некоторые из них:\n",
"\n",
"🎓 Точность (Precision): `TP/(TP + FP)` — доля предсказанных положительных случаев, которые действительно являются положительными. Также называется [положительное прогностическое значение](https://en.wikipedia.org/wiki/Positive_predictive_value \"Positive predictive value\").\n",
"\n",
"🎓 Полнота (Recall): `TP/(TP + FN)` — доля положительных результатов из общего числа образцов, которые действительно являются положительными. Также известна как `чувствительность`.\n",
"\n",
"🎓 Специфичность (Specificity): `TN/(TN + FP)` — доля отрицательных результатов из общего числа образцов, которые действительно являются отрицательными.\n",
"\n",
"🎓 Точность классификации (Accuracy): `TP + TN/(TP + TN + FP + FN)` — процент меток, предсказанных правильно для выборки.\n",
"\n",
"🎓 F-мера (F Measure): Взвешенное среднее между точностью и полнотой, где лучший результат равен 1, а худший — 0.\n",
"\n",
"Давайте рассчитаем эти метрики!\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Combine metric functions and calculate them all at once\n",
"eval_metrics <- metric_set(ppv, recall, spec, f_meas, accuracy)\n",
"eval_metrics(data = results, truth = color, estimate = .pred_class)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Визуализация ROC-кривой этой модели\n",
"\n",
"Давайте сделаем еще одну визуализацию, чтобы увидеть так называемую [`ROC-кривую`](https://en.wikipedia.org/wiki/Receiver_operating_characteristic):\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Make a roc_curve\n",
"results %>% \n",
" roc_curve(color, .pred_ORANGE) %>% \n",
" autoplot()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"ROC-кривые часто используются для визуализации работы классификатора в терминах истинных и ложных срабатываний. ROC-кривые обычно отображают `True Positive Rate`/чувствительность по оси Y и `False Positive Rate`/1-специфичность по оси X. Таким образом, важны крутизна кривой и расстояние между диагональной линией и кривой: вам нужна кривая, которая быстро поднимается вверх и уходит за линию. В нашем случае сначала есть ложные срабатывания, а затем линия поднимается вверх и уходит за пределы диагонали.\n",
"\n",
"Наконец, давайте используем `yardstick::roc_auc()`, чтобы вычислить фактическую площадь под кривой (Area Under the Curve). Один из способов интерпретации AUC — это вероятность того, что модель оценит случайный положительный пример выше, чем случайный отрицательный пример.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Calculate area under curve\n",
"results %>% \n",
" roc_auc(color, .pred_ORANGE)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Результат составляет около `0.975`. Учитывая, что AUC варьируется от 0 до 1, вы хотите получить высокий показатель, так как модель, которая на 100% точна в своих предсказаниях, будет иметь AUC, равный 1; в данном случае модель *довольно хорошая*.\n",
"\n",
"В будущих уроках по классификации вы узнаете, как улучшить показатели вашей модели (например, как справляться с несбалансированными данными в данном случае).\n",
"\n",
"## 🚀Задание\n",
"\n",
"Логистическая регрессия — это обширная тема! Но лучший способ учиться — это экспериментировать. Найдите набор данных, который подходит для такого типа анализа, и создайте с ним модель. Что вы узнаете? совет: попробуйте [Kaggle](https://www.kaggle.com/search?q=logistic+regression+datasets) для поиска интересных наборов данных.\n",
"\n",
"## Обзор и самостоятельное изучение\n",
"\n",
"Прочитайте первые несколько страниц [этой статьи из Стэнфорда](https://web.stanford.edu/~jurafsky/slp3/5.pdf) о практическом применении логистической регрессии. Подумайте о задачах, которые лучше подходят для одного или другого типа регрессии, которые мы изучали до этого момента. Что будет работать лучше?\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Отказ от ответственности**: \nЭтот документ был переведен с использованием сервиса автоматического перевода [Co-op Translator](https://github.com/Azure/co-op-translator). Хотя мы стремимся к точности, пожалуйста, учитывайте, что автоматические переводы могут содержать ошибки или неточности. Оригинальный документ на его родном языке следует считать авторитетным источником. Для получения критически важной информации рекомендуется профессиональный перевод человеком. Мы не несем ответственности за любые недоразумения или неправильные интерпретации, возникающие в результате использования данного перевода.\n"
]
}
],
"metadata": {
"anaconda-cloud": "",
"kernelspec": {
"display_name": "R",
"langauge": "R",
"name": "ir"
},
"language_info": {
"codemirror_mode": "r",
"file_extension": ".r",
"mimetype": "text/x-r-source",
"name": "R",
"pygments_lexer": "r",
"version": "3.4.1"
},
"coopTranslator": {
"original_hash": "feaf125f481a89c468fa115bf2aed580",
"translation_date": "2025-08-29T23:01:34+00:00",
"source_file": "2-Regression/4-Logistic/solution/R/lesson_4-R.ipynb",
"language_code": "ru"
}
},
"nbformat": 4,
"nbformat_minor": 1
}