{ "nbformat": 4, "nbformat_minor": 2, "metadata": { "colab": { "name": "lesson_10-R.ipynb", "provenance": [], "collapsed_sections": [] }, "kernelspec": { "name": "ir", "display_name": "R" }, "language_info": { "name": "R" }, "coopTranslator": { "original_hash": "2621e24705e8100893c9bf84e0fc8aef", "translation_date": "2025-09-04T09:01:05+00:00", "source_file": "4-Classification/1-Introduction/solution/R/lesson_10-R.ipynb", "language_code": "uk" } }, "cells": [ { "cell_type": "markdown", "source": [], "metadata": { "id": "ItETB4tSFprR" } }, { "cell_type": "markdown", "source": [ "## Вступ до класифікації: Очистіть, підготуйте та візуалізуйте свої дані\n", "\n", "У цих чотирьох уроках ви дослідите основний аспект класичного машинного навчання - *класифікацію*. Ми розглянемо використання різних алгоритмів класифікації з набором даних про всі чудові кухні Азії та Індії. Сподіваємося, ви голодні!\n", "\n", "

\n", " \n", "

Відзначайте паназійські кухні в цих уроках! Зображення Джен Лупер
\n", "\n", "Класифікація є формою [навчання з учителем](https://wikipedia.org/wiki/Supervised_learning), яка має багато спільного з техніками регресії. У класифікації ви навчаєте модель передбачати, до якої `категорії` належить елемент. Якщо машинне навчання полягає у прогнозуванні значень або назв для речей за допомогою наборів даних, то класифікація зазвичай поділяється на дві групи: *бінарна класифікація* та *багатокласова класифікація*.\n", "\n", "Запам'ятайте:\n", "\n", "- **Лінійна регресія** допомогла вам передбачити взаємозв'язки між змінними та зробити точні прогнози щодо того, де нова точка даних потрапить у відношенні до цієї лінії. Наприклад, ви могли передбачити числові значення, такі як *яка ціна гарбуза буде у вересні порівняно з груднем*.\n", "\n", "- **Логістична регресія** допомогла вам виявити \"бінарні категорії\": за цією ціною *чи буде гарбуз помаранчевим чи не помаранчевим*?\n", "\n", "Класифікація використовує різні алгоритми для визначення інших способів визначення мітки або класу точки даних. Давайте попрацюємо з цими даними про кухні, щоб побачити, чи можемо ми, спостерігаючи за групою інгредієнтів, визначити її кухню походження.\n", "\n", "### [**Тест перед лекцією**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/19/)\n", "\n", "### **Вступ**\n", "\n", "Класифікація є однією з основних діяльностей дослідника машинного навчання та дата-сайєнтиста. Від базової класифікації бінарного значення (\"чи є цей електронний лист спамом чи ні?\") до складної класифікації зображень та сегментації за допомогою комп'ютерного зору, завжди корисно мати можливість сортувати дані за класами та ставити їм запитання.\n", "\n", "Якщо висловити процес більш науково, ваш метод класифікації створює прогностичну модель, яка дозволяє вам відобразити взаємозв'язок між вхідними змінними та вихідними змінними.\n", "\n", "

\n", " \n", "

Бінарні та багатокласові задачі для алгоритмів класифікації. Інфографіка Джен Лупер
\n", "\n", "Перш ніж розпочати процес очищення наших даних, їх візуалізації та підготовки до завдань машинного навчання, давайте трохи дізнаємося про різні способи використання машинного навчання для класифікації даних.\n", "\n", "Походячи з [статистики](https://wikipedia.org/wiki/Statistical_classification), класифікація за допомогою класичного машинного навчання використовує ознаки, такі як `курець`, `вага` та `вік`, щоб визначити *ймовірність розвитку X хвороби*. Як техніка навчання з учителем, схожа на вправи з регресії, які ви виконували раніше, ваші дані мають мітки, і алгоритми машинного навчання використовують ці мітки для класифікації та прогнозування класів (або 'ознак') набору даних і призначення їх групі або результату.\n", "\n", "✅ Уявіть собі набір даних про кухні. На які запитання міг би відповісти багатокласовий модель? А бінарний? Що, якщо ви хотіли б визначити, чи ймовірно, що певна кухня використовує пажитник? Або що, якщо ви хотіли б побачити, чи можете ви, отримавши подарунок у вигляді пакета продуктів, що містить зірчастий аніс, артишоки, цвітну капусту та хрін, створити типову індійську страву?\n", "\n", "### **Привіт, 'классифікатор'**\n", "\n", "Запитання, яке ми хочемо поставити до цього набору даних про кухні, насправді є **багатокласовим запитанням**, оскільки у нас є кілька потенційних національних кухонь для роботи. Враховуючи набір інгредієнтів, до якого з цих багатьох класів належатимуть дані?\n", "\n", "Tidymodels пропонує кілька різних алгоритмів для класифікації даних, залежно від типу задачі, яку ви хочете вирішити. У наступних двох уроках ви дізнаєтеся про кілька з цих алгоритмів.\n", "\n", "#### **Передумови**\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", "- `DataExplorer`: [Пакет DataExplorer](https://cran.r-project.org/web/packages/DataExplorer/vignettes/dataexplorer-intro.html) призначений для спрощення та автоматизації процесу EDA та генерації звітів.\n", "\n", "- `themis`: [Пакет themis](https://themis.tidymodels.org/) надає додаткові кроки для роботи з незбалансованими даними.\n", "\n", "Ви можете встановити їх за допомогою:\n", "\n", "`install.packages(c(\"tidyverse\", \"tidymodels\", \"DataExplorer\", \"here\"))`\n", "\n", "Або ж скрипт нижче перевірить, чи є у вас необхідні пакети для завершення цього модуля, і встановить їх у разі відсутності.\n" ], "metadata": { "id": "ri5bQxZ-Fz_0" } }, { "cell_type": "code", "execution_count": null, "source": [ "suppressWarnings(if (!require(\"pacman\"))install.packages(\"pacman\"))\r\n", "\r\n", "pacman::p_load(tidyverse, tidymodels, DataExplorer, themis, here)" ], "outputs": [], "metadata": { "id": "KIPxa4elGAPI" } }, { "cell_type": "markdown", "source": [ "Ми пізніше завантажимо ці чудові пакети та зробимо їх доступними в нашій поточній сесії R. (Це лише для ілюстрації, `pacman::p_load()` вже зробив це за вас)\n" ], "metadata": { "id": "YkKAxOJvGD4C" } }, { "cell_type": "markdown", "source": [ "## Вправа - очистіть і збалансуйте ваші дані\n", "\n", "Першим завданням перед початком цього проєкту є очистити та **збалансувати** ваші дані, щоб отримати кращі результати.\n", "\n", "Давайте познайомимося з даними!🕵️\n" ], "metadata": { "id": "PFkQDlk0GN5O" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Import data\r\n", "df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/4-Classification/data/cuisines.csv\")\r\n", "\r\n", "# View the first 5 rows\r\n", "df %>% \r\n", " slice_head(n = 5)\r\n" ], "outputs": [], "metadata": { "id": "Qccw7okxGT0S" } }, { "cell_type": "markdown", "source": [ "Цікаво! Судячи з усього, перший стовпець є своєрідним стовпцем `id`. Давайте дізнаємося трохи більше про ці дані.\n" ], "metadata": { "id": "XrWnlgSrGVmR" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Basic information about the data\r\n", "df %>%\r\n", " introduce()\r\n", "\r\n", "# Visualize basic information above\r\n", "df %>% \r\n", " plot_intro(ggtheme = theme_light())" ], "outputs": [], "metadata": { "id": "4UcGmxRxGieA" } }, { "cell_type": "markdown", "source": [ "З отриманих даних ми бачимо, що у нас є `2448` рядків і `385` стовпців, а також `0` пропущених значень. Крім того, у нас є 1 дискретний стовпець, *cuisine*.\n", "\n", "## Вправа - вивчення кухонь\n", "\n", "Тепер робота стає більш цікавою. Давайте дослідимо розподіл даних за типами кухонь.\n" ], "metadata": { "id": "AaPubl__GmH5" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Count observations per cuisine\r\n", "df %>% \r\n", " count(cuisine) %>% \r\n", " arrange(n)\r\n", "\r\n", "# Plot the distribution\r\n", "theme_set(theme_light())\r\n", "df %>% \r\n", " count(cuisine) %>% \r\n", " ggplot(mapping = aes(x = n, y = reorder(cuisine, -n))) +\r\n", " geom_col(fill = \"midnightblue\", alpha = 0.7) +\r\n", " ylab(\"cuisine\")" ], "outputs": [], "metadata": { "id": "FRsBVy5eGrrv" } }, { "cell_type": "markdown", "source": [ "Існує обмежена кількість кухонь, але розподіл даних є нерівномірним. Ви можете це виправити! Перед тим як це зробити, дослідіть трохи більше.\n", "\n", "Далі, давайте призначимо кожну кухню до її окремого tibble і дізнаємося, скільки даних доступно (рядків, стовпців) для кожної кухні.\n", "\n", "> [Tibble](https://tibble.tidyverse.org/) — це сучасна форма таблиці даних.\n", "\n", "

\n", " \n", "

Ілюстрація від @allison_horst
\n" ], "metadata": { "id": "vVvyDb1kG2in" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Create individual tibble for the cuisines\r\n", "thai_df <- df %>% \r\n", " filter(cuisine == \"thai\")\r\n", "japanese_df <- df %>% \r\n", " filter(cuisine == \"japanese\")\r\n", "chinese_df <- df %>% \r\n", " filter(cuisine == \"chinese\")\r\n", "indian_df <- df %>% \r\n", " filter(cuisine == \"indian\")\r\n", "korean_df <- df %>% \r\n", " filter(cuisine == \"korean\")\r\n", "\r\n", "\r\n", "# Find out how much data is available per cuisine\r\n", "cat(\" thai df:\", dim(thai_df), \"\\n\",\r\n", " \"japanese df:\", dim(japanese_df), \"\\n\",\r\n", " \"chinese_df:\", dim(chinese_df), \"\\n\",\r\n", " \"indian_df:\", dim(indian_df), \"\\n\",\r\n", " \"korean_df:\", dim(korean_df))" ], "outputs": [], "metadata": { "id": "0TvXUxD3G8Bk" } }, { "cell_type": "markdown", "source": [ "## **Вправа - Виявлення найпопулярніших інгредієнтів за кухнею за допомогою dplyr**\n", "\n", "Тепер ви можете глибше зануритися в дані та дізнатися, які інгредієнти є типовими для кожної кухні. Вам слід очистити повторювані дані, які створюють плутанину між кухнями, тож давайте розберемося з цією проблемою.\n", "\n", "Створіть функцію `create_ingredient()` в R, яка повертає датафрейм інгредієнтів. Ця функція почне з видалення непотрібного стовпця та сортування інгредієнтів за їх кількістю.\n", "\n", "Базова структура функції в R виглядає так:\n", "\n", "`myFunction <- function(arglist){`\n", "\n", "**`...`**\n", "\n", "**`return`**`(value)`\n", "\n", "`}`\n", "\n", "Ознайомитися з введенням у функції R можна [тут](https://skirmer.github.io/presentations/functions_with_r.html#1).\n", "\n", "Давайте приступимо до роботи! Ми будемо використовувати [дієслова dplyr](https://dplyr.tidyverse.org/), які ми вивчали на попередніх уроках. Для повторення:\n", "\n", "- `dplyr::select()`: допомагає вибрати, які **стовпці** залишити або виключити.\n", "\n", "- `dplyr::pivot_longer()`: допомагає \"розширити\" дані, збільшуючи кількість рядків і зменшуючи кількість стовпців.\n", "\n", "- `dplyr::group_by()` та `dplyr::summarise()`: допомагають знайти статистичні дані для різних груп і представити їх у зручній таблиці.\n", "\n", "- `dplyr::filter()`: створює підмножину даних, яка містить лише рядки, що відповідають вашим умовам.\n", "\n", "- `dplyr::mutate()`: допомагає створювати або змінювати стовпці.\n", "\n", "Ознайомтеся з цим [навчальним посібником](https://allisonhorst.shinyapps.io/dplyr-learnr/#section-welcome) від Еллісон Хорст, який вводить у корисні функції для обробки даних у dplyr *(частина Tidyverse)*.\n" ], "metadata": { "id": "K3RF5bSCHC76" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Creates a functions that returns the top ingredients by class\r\n", "\r\n", "create_ingredient <- function(df){\r\n", " \r\n", " # Drop the id column which is the first colum\r\n", " ingredient_df = df %>% select(-1) %>% \r\n", " # Transpose data to a long format\r\n", " pivot_longer(!cuisine, names_to = \"ingredients\", values_to = \"count\") %>% \r\n", " # Find the top most ingredients for a particular cuisine\r\n", " group_by(ingredients) %>% \r\n", " summarise(n_instances = sum(count)) %>% \r\n", " filter(n_instances != 0) %>% \r\n", " # Arrange by descending order\r\n", " arrange(desc(n_instances)) %>% \r\n", " mutate(ingredients = factor(ingredients) %>% fct_inorder())\r\n", " \r\n", " \r\n", " return(ingredient_df)\r\n", "} # End of function" ], "outputs": [], "metadata": { "id": "uB_0JR82HTPa" } }, { "cell_type": "markdown", "source": [ "Тепер ми можемо використати функцію, щоб отримати уявлення про десять найпопулярніших інгредієнтів за кухнею. Давайте перевіримо це на прикладі `thai_df`.\n" ], "metadata": { "id": "h9794WF8HWmc" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Call create_ingredient and display popular ingredients\r\n", "thai_ingredient_df <- create_ingredient(df = thai_df)\r\n", "\r\n", "thai_ingredient_df %>% \r\n", " slice_head(n = 10)" ], "outputs": [], "metadata": { "id": "agQ-1HrcHaEA" } }, { "cell_type": "markdown", "source": [ "У попередньому розділі ми використовували `geom_col()`, давайте подивимося, як ви можете використовувати `geom_bar` також, щоб створювати стовпчикові діаграми. Використовуйте `?geom_bar` для додаткового читання.\n" ], "metadata": { "id": "kHu9ffGjHdcX" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Make a bar chart for popular thai cuisines\r\n", "thai_ingredient_df %>% \r\n", " slice_head(n = 10) %>% \r\n", " ggplot(aes(x = n_instances, y = ingredients)) +\r\n", " geom_bar(stat = \"identity\", width = 0.5, fill = \"steelblue\") +\r\n", " xlab(\"\") + ylab(\"\")" ], "outputs": [], "metadata": { "id": "fb3Bx_3DHj6e" } }, { "cell_type": "markdown", "source": [], "metadata": { "id": "RHP_xgdkHnvM" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Get popular ingredients for Japanese cuisines and make bar chart\r\n", "create_ingredient(df = japanese_df) %>% \r\n", " slice_head(n = 10) %>%\r\n", " ggplot(aes(x = n_instances, y = ingredients)) +\r\n", " geom_bar(stat = \"identity\", width = 0.5, fill = \"darkorange\", alpha = 0.8) +\r\n", " xlab(\"\") + ylab(\"\")\r\n" ], "outputs": [], "metadata": { "id": "019v8F0XHrRU" } }, { "cell_type": "markdown", "source": [ "А як щодо китайської кухні?\n" ], "metadata": { "id": "iIGM7vO8Hu3v" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Get popular ingredients for Chinese cuisines and make bar chart\r\n", "create_ingredient(df = chinese_df) %>% \r\n", " slice_head(n = 10) %>%\r\n", " ggplot(aes(x = n_instances, y = ingredients)) +\r\n", " geom_bar(stat = \"identity\", width = 0.5, fill = \"cyan4\", alpha = 0.8) +\r\n", " xlab(\"\") + ylab(\"\")" ], "outputs": [], "metadata": { "id": "lHd9_gd2HyzU" } }, { "cell_type": "markdown", "source": [], "metadata": { "id": "ir8qyQbNH1c7" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Get popular ingredients for Indian cuisines and make bar chart\r\n", "create_ingredient(df = indian_df) %>% \r\n", " slice_head(n = 10) %>%\r\n", " ggplot(aes(x = n_instances, y = ingredients)) +\r\n", " geom_bar(stat = \"identity\", width = 0.5, fill = \"#041E42FF\", alpha = 0.8) +\r\n", " xlab(\"\") + ylab(\"\")" ], "outputs": [], "metadata": { "id": "ApukQtKjH5FO" } }, { "cell_type": "markdown", "source": [], "metadata": { "id": "qv30cwY1H-FM" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Get popular ingredients for Korean cuisines and make bar chart\r\n", "create_ingredient(df = korean_df) %>% \r\n", " slice_head(n = 10) %>%\r\n", " ggplot(aes(x = n_instances, y = ingredients)) +\r\n", " geom_bar(stat = \"identity\", width = 0.5, fill = \"#852419FF\", alpha = 0.8) +\r\n", " xlab(\"\") + ylab(\"\")" ], "outputs": [], "metadata": { "id": "lumgk9cHIBie" } }, { "cell_type": "markdown", "source": [ "З аналізу візуалізацій даних ми тепер можемо виключити найпоширеніші інгредієнти, які створюють плутанину між різними кухнями, використовуючи `dplyr::select()`.\n", "\n", "Усі обожнюють рис, часник і імбир!\n" ], "metadata": { "id": "iO4veMXuIEta" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Drop id column, rice, garlic and ginger from our original data set\r\n", "df_select <- df %>% \r\n", " select(-c(1, rice, garlic, ginger))\r\n", "\r\n", "# Display new data set\r\n", "df_select %>% \r\n", " slice_head(n = 5)" ], "outputs": [], "metadata": { "id": "iHJPiG6rIUcK" } }, { "cell_type": "markdown", "source": [ "## Попередня обробка даних за допомогою рецептів 👩‍🍳👨‍🍳 - Робота з незбалансованими даними ⚖️\n", "\n", "

\n", " \n", "

Ілюстрація від @allison_horst
\n", "\n", "Оскільки цей урок стосується кухонь, нам потрібно поставити `recipes` у контекст.\n", "\n", "Tidymodels пропонує ще один чудовий пакет: `recipes` - пакет для попередньої обробки даних.\n" ], "metadata": { "id": "kkFd-JxdIaL6" } }, { "cell_type": "markdown", "source": [ "Давайте ще раз поглянемо на розподіл наших кухонь.\n" ], "metadata": { "id": "6l2ubtTPJAhY" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Distribution of cuisines\r\n", "old_label_count <- df_select %>% \r\n", " count(cuisine) %>% \r\n", " arrange(desc(n))\r\n", "\r\n", "old_label_count" ], "outputs": [], "metadata": { "id": "1e-E9cb7JDVi" } }, { "cell_type": "markdown", "source": [ "Як ви можете побачити, існує досить нерівномірний розподіл кількості кухонь. Корейські кухні майже втричі перевищують тайські кухні. Незбалансовані дані часто негативно впливають на продуктивність моделі. Подумайте про бінарну класифікацію. Якщо більшість ваших даних належить до одного класу, модель машинного навчання буде частіше передбачати цей клас просто тому, що для нього є більше даних. Балансування даних усуває будь-яку нерівномірність і допомагає позбутися цього дисбалансу. Багато моделей працюють найкраще, коли кількість спостережень є рівною, і тому їм важко працювати з незбалансованими даними.\n", "\n", "Існує два основних способи роботи з незбалансованими наборами даних:\n", "\n", "- додавання спостережень до меншості класу: `Over-sampling`, наприклад, використання алгоритму SMOTE\n", "\n", "- видалення спостережень із більшості класу: `Under-sampling`\n", "\n", "Давайте тепер продемонструємо, як працювати з незбалансованими наборами даних, використовуючи `recipe`. Рецепт можна уявити як план, який описує, які кроки слід застосувати до набору даних, щоб підготувати його до аналізу.\n" ], "metadata": { "id": "soAw6826JKx9" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Load themis package for dealing with imbalanced data\r\n", "library(themis)\r\n", "\r\n", "# Create a recipe for preprocessing data\r\n", "cuisines_recipe <- recipe(cuisine ~ ., data = df_select) %>% \r\n", " step_smote(cuisine)\r\n", "\r\n", "cuisines_recipe" ], "outputs": [], "metadata": { "id": "HS41brUIJVJy" } }, { "cell_type": "markdown", "source": [ "Давайте розглянемо наші кроки попередньої обробки.\n", "\n", "- Виклик `recipe()` із формулою вказує рецепту *ролі* змінних, використовуючи дані `df_select` як еталон. Наприклад, стовпцю `cuisine` було призначено роль `outcome`, тоді як решті стовпців було призначено роль `predictor`.\n", "\n", "- [`step_smote(cuisine)`](https://themis.tidymodels.org/reference/step_smote.html) створює *специфікацію* кроку рецепту, який синтетично генерує нові приклади для меншості класу, використовуючи найближчих сусідів цих випадків.\n", "\n", "Тепер, якщо ми хочемо побачити попередньо оброблені дані, нам потрібно [**`prep()`**](https://recipes.tidymodels.org/reference/prep.html) і [**`bake()`**](https://recipes.tidymodels.org/reference/bake.html) наш рецепт.\n", "\n", "`prep()`: оцінює необхідні параметри на основі навчального набору, які згодом можуть бути застосовані до інших наборів даних.\n", "\n", "`bake()`: бере підготовлений рецепт і застосовує операції до будь-якого набору даних.\n" ], "metadata": { "id": "Yb-7t7XcJaC8" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Prep and bake the recipe\r\n", "preprocessed_df <- cuisines_recipe %>% \r\n", " prep() %>% \r\n", " bake(new_data = NULL) %>% \r\n", " relocate(cuisine)\r\n", "\r\n", "# Display data\r\n", "preprocessed_df %>% \r\n", " slice_head(n = 5)\r\n", "\r\n", "# Quick summary stats\r\n", "preprocessed_df %>% \r\n", " introduce()" ], "outputs": [], "metadata": { "id": "9QhSgdpxJl44" } }, { "cell_type": "markdown", "source": [ "Давайте тепер перевіримо розподіл наших кухонь і порівняємо їх із незбалансованими даними.\n" ], "metadata": { "id": "dmidELh_LdV7" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Distribution of cuisines\r\n", "new_label_count <- preprocessed_df %>% \r\n", " count(cuisine) %>% \r\n", " arrange(desc(n))\r\n", "\r\n", "list(new_label_count = new_label_count,\r\n", " old_label_count = old_label_count)" ], "outputs": [], "metadata": { "id": "aSh23klBLwDz" } }, { "cell_type": "markdown", "source": [ "Ммм! Дані чисті, збалансовані та дуже смачні 😋!\n", "\n", "> Зазвичай рецепт використовується як препроцесор для моделювання, де визначається, які кроки потрібно застосувати до набору даних, щоб підготувати його до моделювання. У такому випадку зазвичай використовується `workflow()` (як ми вже бачили в попередніх уроках), замість того, щоб вручну оцінювати рецепт.\n", ">\n", "> Таким чином, вам зазвичай не потрібно використовувати **`prep()`** і **`bake()`** рецепти, коли ви працюєте з tidymodels, але ці функції корисно мати у своєму арсеналі для перевірки того, що рецепти працюють так, як ви очікуєте, як у нашому випадку.\n", ">\n", "> Коли ви використовуєте **`bake()`** для підготовленого рецепта з **`new_data = NULL`**, ви отримуєте дані, які ви надали при визначенні рецепта, але вже після виконання кроків препроцесингу.\n", "\n", "Давайте тепер збережемо копію цих даних для використання в майбутніх уроках:\n" ], "metadata": { "id": "HEu80HZ8L7ae" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Save preprocessed data\r\n", "write_csv(preprocessed_df, \"../../../data/cleaned_cuisines_R.csv\")" ], "outputs": [], "metadata": { "id": "cBmCbIgrMOI6" } }, { "cell_type": "markdown", "source": [ "Цей новий CSV тепер знаходиться в кореневій папці даних.\n", "\n", "**🚀Виклик**\n", "\n", "Ця навчальна програма містить кілька цікавих наборів даних. Перегляньте папки `data` і подивіться, чи є там набори даних, які підходять для бінарної або багатокласової класифікації? Які питання ви могли б поставити до цього набору даних?\n", "\n", "## [**Тест після лекції**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/20/)\n", "\n", "## **Огляд і самостійне навчання**\n", "\n", "- Ознайомтеся з [пакетом themis](https://github.com/tidymodels/themis). Які інші методи ми могли б використати для роботи з незбалансованими даними?\n", "\n", "- Вебсайт [довідника Tidy models](https://www.tidymodels.org/start/).\n", "\n", "- Г. Вікхем і Г. Гролемунд, [*R для науки про дані: візуалізація, моделювання, трансформація, впорядкування та імпорт даних*](https://r4ds.had.co.nz/).\n", "\n", "#### ДЯКУЄМО:\n", "\n", "[`Елісон Хорст`](https://twitter.com/allison_horst/) за створення чудових ілюстрацій, які роблять R більш доступним і цікавим. Більше ілюстрацій можна знайти в її [галереї](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n", "\n", "[Кассі Бревіу](https://www.twitter.com/cassieview) і [Джен Лупер](https://www.twitter.com/jenlooper) за створення оригінальної версії цього модуля на Python ♥️\n", "\n", "

\n", " \n", "

Ілюстрація від @allison_horst
\n" ], "metadata": { "id": "WQs5621pMGwf" } }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n---\n\n**Відмова від відповідальності**: \nЦей документ було перекладено за допомогою сервісу автоматичного перекладу [Co-op Translator](https://github.com/Azure/co-op-translator). Хоча ми прагнемо до точності, зверніть увагу, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ мовою оригіналу слід вважати авторитетним джерелом. Для критично важливої інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникли внаслідок використання цього перекладу.\n" ] } ] }