{ "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-03T20:39:15+00:00", "source_file": "4-Classification/1-Introduction/solution/R/lesson_10-R.ipynb", "language_code": "pt" } }, "cells": [ { "cell_type": "markdown", "source": [ "# Construir um modelo de classificação: Deliciosas Cozinhas Asiáticas e Indianas\n" ], "metadata": { "id": "ItETB4tSFprR" } }, { "cell_type": "markdown", "source": [ "## Introdução à classificação: Limpar, preparar e visualizar os seus dados\n", "\n", "Nestes quatro módulos, irá explorar um dos focos fundamentais do machine learning clássico - *classificação*. Vamos percorrer o uso de vários algoritmos de classificação com um conjunto de dados sobre as brilhantes culinárias da Ásia e da Índia. Esperamos que esteja com fome!\n", "\n", "

\n", " \n", "

Celebre as culinárias pan-asiáticas nestas lições! Imagem por Jen Looper
\n", "\n", "\n", "\n", "\n", "Classificação é uma forma de [aprendizagem supervisionada](https://wikipedia.org/wiki/Supervised_learning) que tem muito em comum com técnicas de regressão. Na classificação, treina-se um modelo para prever a que `categoria` um item pertence. Se o machine learning trata de prever valores ou nomes para coisas usando conjuntos de dados, então a classificação geralmente se divide em dois grupos: *classificação binária* e *classificação multicategorias*.\n", "\n", "Lembre-se:\n", "\n", "- **Regressão linear** ajudou-o a prever relações entre variáveis e fazer previsões precisas sobre onde um novo ponto de dados se encaixaria em relação àquela linha. Por exemplo, poderia prever valores numéricos como *qual seria o preço de uma abóbora em setembro vs. dezembro*.\n", "\n", "- **Regressão logística** ajudou-o a descobrir \"categorias binárias\": a este preço, *esta abóbora é laranja ou não-laranja*?\n", "\n", "A classificação utiliza vários algoritmos para determinar outras formas de identificar o rótulo ou classe de um ponto de dados. Vamos trabalhar com estes dados de culinária para ver se, ao observar um grupo de ingredientes, conseguimos determinar a sua origem culinária.\n", "\n", "### [**Questionário pré-aula**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/19/)\n", "\n", "### **Introdução**\n", "\n", "A classificação é uma das atividades fundamentais do investigador de machine learning e do cientista de dados. Desde a classificação básica de um valor binário (\"este email é spam ou não?\"), até à classificação e segmentação complexa de imagens usando visão computacional, é sempre útil poder organizar dados em classes e fazer perguntas sobre eles.\n", "\n", "Para expressar o processo de forma mais científica, o seu método de classificação cria um modelo preditivo que permite mapear a relação entre variáveis de entrada e variáveis de saída.\n", "\n", "

\n", " \n", "

Problemas binários vs. multicategorias para algoritmos de classificação. Infográfico por Jen Looper
\n", "\n", "\n", "\n", "Antes de começar o processo de limpar os nossos dados, visualizá-los e prepará-los para as nossas tarefas de ML, vamos aprender um pouco sobre as várias formas como o machine learning pode ser utilizado para classificar dados.\n", "\n", "Derivada da [estatística](https://wikipedia.org/wiki/Statistical_classification), a classificação usando machine learning clássico utiliza características, como `fumador`, `peso` e `idade`, para determinar *probabilidade de desenvolver X doença*. Como uma técnica de aprendizagem supervisionada semelhante aos exercícios de regressão que realizou anteriormente, os seus dados são rotulados e os algoritmos de ML utilizam esses rótulos para classificar e prever classes (ou 'características') de um conjunto de dados e atribuí-los a um grupo ou resultado.\n", "\n", "✅ Tire um momento para imaginar um conjunto de dados sobre culinárias. O que um modelo multicategorias seria capaz de responder? O que um modelo binário seria capaz de responder? E se quisesse determinar se uma determinada culinária provavelmente utiliza feno-grego? E se quisesse ver se, dado um saco de compras cheio de anis-estrelado, alcachofras, couve-flor e rábano, conseguiria criar um prato típico indiano?\n", "\n", "### **Olá 'classificador'**\n", "\n", "A pergunta que queremos fazer a este conjunto de dados de culinária é, na verdade, uma questão **multicategorias**, já que temos várias possíveis culinárias nacionais com que trabalhar. Dado um lote de ingredientes, a qual destas muitas classes os dados se encaixam?\n", "\n", "O Tidymodels oferece vários algoritmos diferentes para classificar dados, dependendo do tipo de problema que deseja resolver. Nas próximas duas lições, aprenderá sobre alguns desses algoritmos.\n", "\n", "#### **Pré-requisitos**\n", "\n", "Para esta lição, precisaremos dos seguintes pacotes para limpar, preparar e visualizar os nossos dados:\n", "\n", "- `tidyverse`: O [tidyverse](https://www.tidyverse.org/) é uma [coleção de pacotes R](https://www.tidyverse.org/packages) projetada para tornar a ciência de dados mais rápida, fácil e divertida!\n", "\n", "- `tidymodels`: O [tidymodels](https://www.tidymodels.org/) é uma [coleção de pacotes](https://www.tidymodels.org/packages/) para modelagem e machine learning.\n", "\n", "- `DataExplorer`: O [pacote DataExplorer](https://cran.r-project.org/web/packages/DataExplorer/vignettes/dataexplorer-intro.html) foi criado para simplificar e automatizar o processo de EDA e geração de relatórios.\n", "\n", "- `themis`: O [pacote themis](https://themis.tidymodels.org/) fornece passos extras de receitas para lidar com dados desequilibrados.\n", "\n", "Pode instalá-los como:\n", "\n", "`install.packages(c(\"tidyverse\", \"tidymodels\", \"DataExplorer\", \"here\"))`\n", "\n", "Alternativamente, o script abaixo verifica se tem os pacotes necessários para completar este módulo e instala-os caso estejam em falta.\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": [ "Mais tarde, iremos carregar estes pacotes incríveis e torná-los disponíveis na nossa sessão atual de R. (Isto é apenas para ilustração, `pacman::p_load()` já fez isso por si)\n" ], "metadata": { "id": "YkKAxOJvGD4C" } }, { "cell_type": "markdown", "source": [ "## Exercício - limpar e equilibrar os seus dados\n", "\n", "A primeira tarefa, antes de começar este projeto, é limpar e **equilibrar** os seus dados para obter melhores resultados.\n", "\n", "Vamos conhecer os dados! 🕵️\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": [ "Interessante! Pelo que parece, a primeira coluna é uma espécie de coluna `id`. Vamos obter um pouco mais de informações sobre os dados.\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": [ "A partir dos resultados, podemos ver imediatamente que temos `2448` linhas e `385` colunas e `0` valores em falta. Também temos 1 coluna discreta, *cuisine*.\n", "\n", "## Exercício - aprender sobre cozinhas\n", "\n", "Agora o trabalho começa a tornar-se mais interessante. Vamos descobrir a distribuição dos dados, por cozinha.\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": [ "Existem um número finito de cozinhas, mas a distribuição dos dados é desigual. Pode resolver isso! Antes de o fazer, explore um pouco mais.\n", "\n", "De seguida, vamos atribuir cada cozinha ao seu próprio tibble e descobrir quantos dados estão disponíveis (linhas, colunas) por cozinha.\n", "\n", "> Um [tibble](https://tibble.tidyverse.org/) é uma versão moderna de um data frame.\n", "\n", "

\n", " \n", "

Ilustração por @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": [ "## **Exercício - Descobrir os principais ingredientes por cozinha usando dplyr**\n", "\n", "Agora pode explorar mais profundamente os dados e descobrir quais são os ingredientes típicos de cada cozinha. Deve limpar os dados recorrentes que criam confusão entre as cozinhas, então vamos aprender sobre este problema.\n", "\n", "Crie uma função `create_ingredient()` em R que devolva um dataframe de ingredientes. Esta função começará por remover uma coluna pouco útil e organizar os ingredientes pelo seu número de ocorrências.\n", "\n", "A estrutura básica de uma função em R é:\n", "\n", "`myFunction <- function(arglist){`\n", "\n", "**`...`**\n", "\n", "**`return`**`(value)`\n", "\n", "`}`\n", "\n", "Uma introdução prática às funções em R pode ser encontrada [aqui](https://skirmer.github.io/presentations/functions_with_r.html#1).\n", "\n", "Vamos direto ao assunto! Vamos utilizar os [verbos dplyr](https://dplyr.tidyverse.org/) que temos vindo a aprender nas nossas lições anteriores. Como resumo:\n", "\n", "- `dplyr::select()`: ajuda a escolher quais **colunas** manter ou excluir.\n", "\n", "- `dplyr::pivot_longer()`: ajuda a \"alongar\" os dados, aumentando o número de linhas e diminuindo o número de colunas.\n", "\n", "- `dplyr::group_by()` e `dplyr::summarise()`: ajudam a encontrar estatísticas resumidas para diferentes grupos e colocá-las numa tabela organizada.\n", "\n", "- `dplyr::filter()`: cria um subconjunto dos dados contendo apenas as linhas que satisfazem as suas condições.\n", "\n", "- `dplyr::mutate()`: ajuda a criar ou modificar colunas.\n", "\n", "Confira este [tutorial *artístico* learnr](https://allisonhorst.shinyapps.io/dplyr-learnr/#section-welcome) de Allison Horst, que introduz algumas funções úteis de manipulação de dados no dplyr *(parte do 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": [ "Agora podemos usar a função para obter uma ideia dos dez ingredientes mais populares por cozinha. Vamos testá-la com `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": [ "Na seção anterior, utilizámos `geom_col()`, vamos ver como pode usar `geom_bar` também, para criar gráficos de barras. Use `?geom_bar` para leitura adicional.\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": [ "E quanto às cozinhas chinesas?\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": [ "A partir das visualizações de dados, podemos agora eliminar os ingredientes mais comuns que geram confusão entre diferentes cozinhas, utilizando `dplyr::select()`.\n", "\n", "Toda a gente adora arroz, alho e gengibre!\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": [ "## Pré-processamento de dados usando receitas 👩‍🍳👨‍🍳 - Lidando com dados desequilibrados ⚖️\n", "\n", "

\n", " \n", "

Ilustração por @allison_horst
\n", "\n", "Dado que esta lição é sobre culinárias, temos de colocar `recipes` em contexto.\n", "\n", "O Tidymodels oferece mais um pacote interessante: `recipes` - um pacote para pré-processamento de dados.\n" ], "metadata": { "id": "kkFd-JxdIaL6" } }, { "cell_type": "markdown", "source": [ "Vamos dar uma olhada novamente na distribuição das nossas culinárias.\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": [ "Como pode ver, há uma distribuição bastante desigual no número de cozinhas. As cozinhas coreanas são quase 3 vezes mais numerosas do que as tailandesas. Dados desequilibrados frequentemente têm efeitos negativos no desempenho do modelo. Pense numa classificação binária. Se a maior parte dos seus dados pertence a uma classe, um modelo de ML vai prever essa classe com mais frequência, simplesmente porque há mais dados disponíveis para ela. Equilibrar os dados corrige qualquer desvio e ajuda a eliminar esse desequilíbrio. Muitos modelos têm o melhor desempenho quando o número de observações é igual e, por isso, tendem a ter dificuldades com dados desequilibrados.\n", "\n", "Existem principalmente duas formas de lidar com conjuntos de dados desequilibrados:\n", "\n", "- adicionar observações à classe minoritária: `Over-sampling`, por exemplo, utilizando um algoritmo SMOTE\n", "\n", "- remover observações da classe maioritária: `Under-sampling`\n", "\n", "Vamos agora demonstrar como lidar com conjuntos de dados desequilibrados utilizando uma `recipe`. Uma recipe pode ser vista como um plano que descreve quais passos devem ser aplicados a um conjunto de dados para prepará-lo para análise de dados.\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": [ "Vamos analisar os nossos passos de pré-processamento.\n", "\n", "- A chamada para `recipe()` com uma fórmula indica à receita os *papéis* das variáveis usando os dados de `df_select` como referência. Por exemplo, a coluna `cuisine` foi atribuída ao papel de `outcome`, enquanto as restantes colunas foram atribuídas ao papel de `predictor`.\n", "\n", "- [`step_smote(cuisine)`](https://themis.tidymodels.org/reference/step_smote.html) cria uma *especificação* de um passo da receita que gera sinteticamente novos exemplos da classe minoritária utilizando os vizinhos mais próximos desses casos.\n", "\n", "Agora, se quisermos ver os dados pré-processados, teremos de [**`prep()`**](https://recipes.tidymodels.org/reference/prep.html) e [**`bake()`**](https://recipes.tidymodels.org/reference/bake.html) a nossa receita.\n", "\n", "`prep()`: estima os parâmetros necessários a partir de um conjunto de treino que podem ser posteriormente aplicados a outros conjuntos de dados.\n", "\n", "`bake()`: aplica uma receita preparada às operações em qualquer conjunto de dados.\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": [ "Vamos agora verificar a distribuição das nossas culinárias e compará-las com os dados desequilibrados.\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": [ "Yum! Os dados estão limpos, equilibrados e muito deliciosos 😋!\n", "\n", "> Normalmente, uma receita é usada como um pré-processador para modelagem, onde define quais passos devem ser aplicados a um conjunto de dados para prepará-lo para a modelagem. Nesse caso, um `workflow()` é geralmente utilizado (como já vimos nas nossas lições anteriores) em vez de estimar manualmente uma receita.\n", ">\n", "> Assim, normalmente não é necessário **`prep()`** e **`bake()`** receitas quando se utiliza tidymodels, mas estas são funções úteis para ter na sua caixa de ferramentas para confirmar que as receitas estão a fazer o que espera, como no nosso caso.\n", ">\n", "> Quando se **`bake()`** uma receita preparada com **`new_data = NULL`**, obtém-se de volta os dados que foram fornecidos ao definir a receita, mas que passaram pelos passos de pré-processamento.\n", "\n", "Vamos agora guardar uma cópia destes dados para usar em lições futuras:\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": [ "Este novo CSV pode agora ser encontrado na pasta raiz de dados.\n", "\n", "**🚀Desafio**\n", "\n", "Este currículo contém vários conjuntos de dados interessantes. Explore as pastas `data` e veja se alguma contém conjuntos de dados que seriam apropriados para classificação binária ou multi-classe. Que perguntas faria sobre este conjunto de dados?\n", "\n", "## [**Questionário pós-aula**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/20/)\n", "\n", "## **Revisão & Estudo Individual**\n", "\n", "- Veja o [pacote themis](https://github.com/tidymodels/themis). Que outras técnicas poderíamos usar para lidar com dados desbalanceados?\n", "\n", "- Site de referência dos [modelos tidy](https://www.tidymodels.org/start/).\n", "\n", "- H. Wickham e G. Grolemund, [*R for Data Science: Visualize, Model, Transform, Tidy, and Import Data*](https://r4ds.had.co.nz/).\n", "\n", "#### OBRIGADO A:\n", "\n", "[`Allison Horst`](https://twitter.com/allison_horst/) por criar as ilustrações incríveis que tornam o R mais acolhedor e envolvente. Encontre mais ilustrações na sua [galeria](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n", "\n", "[Cassie Breviu](https://www.twitter.com/cassieview) e [Jen Looper](https://www.twitter.com/jenlooper) por criarem a versão original em Python deste módulo ♥️\n", "\n", "

\n", " \n", "

Arte por @allison_horst
\n" ], "metadata": { "id": "WQs5621pMGwf" } }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n---\n\n**Aviso Legal**: \nEste documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução.\n" ] } ] }