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.
1087 lines
43 KiB
1087 lines
43 KiB
{
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2,
|
|
"metadata": {
|
|
"colab": {
|
|
"name": "lesson_3-R.ipynb",
|
|
"provenance": [],
|
|
"collapsed_sections": [],
|
|
"toc_visible": true
|
|
},
|
|
"kernelspec": {
|
|
"name": "ir",
|
|
"display_name": "R"
|
|
},
|
|
"language_info": {
|
|
"name": "R"
|
|
},
|
|
"coopTranslator": {
|
|
"original_hash": "5015d65d61ba75a223bfc56c273aa174",
|
|
"translation_date": "2025-09-03T19:24:43+00:00",
|
|
"source_file": "2-Regression/3-Linear/solution/R/lesson_3-R.ipynb",
|
|
"language_code": "pt"
|
|
}
|
|
},
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [],
|
|
"metadata": {
|
|
"id": "EgQw8osnsUV-"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## Regressão Linear e Polinomial para Preços de Abóboras - Aula 3\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/linear-polynomial.png\"\n",
|
|
" width=\"800\"/>\n",
|
|
" <figcaption>Infográfico por Dasani Madipalli</figcaption>\n",
|
|
"\n",
|
|
"\n",
|
|
"#### Introdução\n",
|
|
"\n",
|
|
"Até agora, exploraste o que é regressão com dados de exemplo recolhidos do conjunto de dados sobre preços de abóboras que utilizaremos ao longo desta aula. Também já os visualizaste usando `ggplot2`. 💪\n",
|
|
"\n",
|
|
"Agora estás pronto para aprofundar o tema da regressão para ML. Nesta aula, vais aprender mais sobre dois tipos de regressão: *regressão linear básica* e *regressão polinomial*, juntamente com alguns dos conceitos matemáticos subjacentes a estas técnicas.\n",
|
|
"\n",
|
|
"> Ao longo deste currículo, assumimos um conhecimento mínimo de matemática e procuramos torná-la acessível para estudantes de outras áreas. Por isso, presta atenção às notas, 🧮 destaques, diagramas e outras ferramentas de aprendizagem que ajudam na compreensão.\n",
|
|
"\n",
|
|
"#### Preparação\n",
|
|
"\n",
|
|
"Como lembrete, estás a carregar estes dados para fazer perguntas sobre eles.\n",
|
|
"\n",
|
|
"- Qual é a melhor altura para comprar abóboras?\n",
|
|
"\n",
|
|
"- Qual o preço que posso esperar por uma caixa de abóboras miniatura?\n",
|
|
"\n",
|
|
"- Devo comprá-las em cestos de meio alqueire ou em caixas de 1 1/9 alqueire? Vamos continuar a explorar estes dados.\n",
|
|
"\n",
|
|
"Na aula anterior, criaste um `tibble` (uma reinterpretação moderna do data frame) e preencheste-o com parte do conjunto de dados original, padronizando os preços por alqueire. Ao fazer isso, no entanto, só conseguiste recolher cerca de 400 pontos de dados e apenas para os meses de outono. Talvez possamos obter um pouco mais de detalhe sobre a natureza dos dados ao limpá-los melhor? Vamos ver... 🕵️♀️\n",
|
|
"\n",
|
|
"Para esta tarefa, vamos precisar dos seguintes pacotes:\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 [estrutura de pacotes](https://www.tidymodels.org/packages/) para modelagem e aprendizagem automática.\n",
|
|
"\n",
|
|
"- `janitor`: O [pacote janitor](https://github.com/sfirke/janitor) oferece ferramentas simples para examinar e limpar dados desorganizados.\n",
|
|
"\n",
|
|
"- `corrplot`: O [pacote corrplot](https://cran.r-project.org/web/packages/corrplot/vignettes/corrplot-intro.html) fornece uma ferramenta visual exploratória para matrizes de correlação que suporta o reordenamento automático de variáveis para ajudar a detectar padrões ocultos entre variáveis.\n",
|
|
"\n",
|
|
"Podes instalá-los da seguinte forma:\n",
|
|
"\n",
|
|
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"corrplot\"))`\n",
|
|
"\n",
|
|
"O script abaixo verifica se tens os pacotes necessários para completar este módulo e instala-os para ti caso estejam em falta.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "WqQPS1OAsg3H"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"suppressWarnings(if (!require(\"pacman\")) install.packages(\"pacman\"))\n",
|
|
"\n",
|
|
"pacman::p_load(tidyverse, tidymodels, janitor, corrplot)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "tA4C2WN3skCf",
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"outputId": "c06cd805-5534-4edc-f72b-d0d1dab96ac0"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Vamos 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 você)\n",
|
|
"\n",
|
|
"## 1. Uma linha de regressão linear\n",
|
|
"\n",
|
|
"Como aprendeste na Lição 1, o objetivo de um exercício de regressão linear é conseguir traçar uma *linha* *de* *melhor ajuste* para:\n",
|
|
"\n",
|
|
"- **Mostrar relações entre variáveis**. Mostrar a relação entre as variáveis.\n",
|
|
"\n",
|
|
"- **Fazer previsões**. Fazer previsões precisas sobre onde um novo ponto de dados se situaria em relação a essa linha.\n",
|
|
"\n",
|
|
"Para desenhar este tipo de linha, usamos uma técnica estatística chamada **Regressão dos Mínimos Quadrados**. O termo `mínimos quadrados` significa que todos os pontos de dados ao redor da linha de regressão são elevados ao quadrado e depois somados. Idealmente, essa soma final é o menor valor possível, porque queremos um número baixo de erros, ou `mínimos quadrados`. Assim, a linha de melhor ajuste é a linha que nos dá o menor valor para a soma dos erros ao quadrado - daí o nome *regressão dos mínimos quadrados*.\n",
|
|
"\n",
|
|
"Fazemos isso porque queremos modelar uma linha que tenha a menor distância acumulada de todos os nossos pontos de dados. Também elevamos os termos ao quadrado antes de somá-los, pois estamos preocupados com a sua magnitude e não com a sua direção.\n",
|
|
"\n",
|
|
"> **🧮 Mostra-me a matemática**\n",
|
|
">\n",
|
|
"> Esta linha, chamada de *linha de melhor ajuste*, pode ser expressa por [uma equação](https://en.wikipedia.org/wiki/Simple_linear_regression):\n",
|
|
">\n",
|
|
"> Y = a + bX\n",
|
|
">\n",
|
|
"> `X` é a '`variável explicativa` ou `preditor`'. `Y` é a '`variável dependente` ou `resultado`'. A inclinação da linha é `b` e `a` é o ponto de interseção no eixo Y, que se refere ao valor de `Y` quando `X = 0`.\n",
|
|
">\n",
|
|
"\n",
|
|
"> \n",
|
|
" Infográfico por Jen Looper\n",
|
|
">\n",
|
|
"> Primeiro, calcula a inclinação `b`.\n",
|
|
">\n",
|
|
"> Em outras palavras, e referindo-nos à pergunta original sobre os dados das abóboras: \"prever o preço de uma abóbora por alqueire ao longo dos meses\", `X` referiria-se ao preço e `Y` ao mês de venda.\n",
|
|
">\n",
|
|
"> \n",
|
|
" Infográfico por Jen Looper\n",
|
|
"> \n",
|
|
"> Calcula o valor de Y. Se estás a pagar cerca de \\$4, deve ser abril!\n",
|
|
">\n",
|
|
"> A matemática que calcula a linha deve demonstrar a inclinação da linha, que também depende do ponto de interseção, ou onde `Y` está situado quando `X = 0`.\n",
|
|
">\n",
|
|
"> Podes observar o método de cálculo destes valores no site [Math is Fun](https://www.mathsisfun.com/data/least-squares-regression.html). Também visita [este calculador de mínimos quadrados](https://www.mathsisfun.com/data/least-squares-calculator.html) para ver como os valores dos números impactam a linha.\n",
|
|
"\n",
|
|
"Não é tão assustador, certo? 🤓\n",
|
|
"\n",
|
|
"#### Correlação\n",
|
|
"\n",
|
|
"Outro termo importante para entender é o **Coeficiente de Correlação** entre as variáveis X e Y fornecidas. Usando um gráfico de dispersão, podes visualizar rapidamente este coeficiente. Um gráfico com pontos de dados alinhados de forma ordenada tem alta correlação, mas um gráfico com pontos de dados espalhados aleatoriamente entre X e Y tem baixa correlação.\n",
|
|
"\n",
|
|
"Um bom modelo de regressão linear será aquele que tem um Coeficiente de Correlação alto (mais próximo de 1 do que de 0) usando o método de Regressão dos Mínimos Quadrados com uma linha de regressão.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "cdX5FRpvsoP5"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## **2. Uma dança com dados: criar um data frame que será usado para modelação**\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/janitor.jpg\"\n",
|
|
" width=\"700\"/>\n",
|
|
" <figcaption>Ilustração por @allison_horst</figcaption>\n",
|
|
"\n",
|
|
"\n",
|
|
"<!--{width=\"700\"}-->\n"
|
|
],
|
|
"metadata": {
|
|
"id": "WdUKXk7Bs8-V"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Carregue as bibliotecas necessárias e o conjunto de dados. Converta os dados para um data frame contendo um subconjunto dos dados:\n",
|
|
"\n",
|
|
"- Obtenha apenas abóboras com preços por alqueire\n",
|
|
"\n",
|
|
"- Converta a data para um mês\n",
|
|
"\n",
|
|
"- Calcule o preço como uma média entre os preços altos e baixos\n",
|
|
"\n",
|
|
"- Converta o preço para refletir a quantidade por alqueire\n",
|
|
"\n",
|
|
"> Abordámos estes passos na [lição anterior](https://github.com/microsoft/ML-For-Beginners/blob/main/2-Regression/2-Data/solution/lesson_2-R.ipynb).\n"
|
|
],
|
|
"metadata": {
|
|
"id": "fMCtu2G2s-p8"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Load the core Tidyverse packages\n",
|
|
"library(tidyverse)\n",
|
|
"library(lubridate)\n",
|
|
"\n",
|
|
"# Import the pumpkins data\n",
|
|
"pumpkins <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/2-Regression/data/US-pumpkins.csv\")\n",
|
|
"\n",
|
|
"\n",
|
|
"# Get a glimpse and dimensions of the data\n",
|
|
"glimpse(pumpkins)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Print the first 50 rows of the data set\n",
|
|
"pumpkins %>% \n",
|
|
" slice_head(n = 5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "ryMVZEEPtERn"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"No espírito de pura aventura, vamos explorar o [`pacote janitor`](../../../../../../2-Regression/3-Linear/solution/R/github.com/sfirke/janitor) que fornece funções simples para examinar e limpar dados desorganizados. Por exemplo, vamos dar uma olhada nos nomes das colunas dos nossos dados:\n"
|
|
],
|
|
"metadata": {
|
|
"id": "xcNxM70EtJjb"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Return column names\n",
|
|
"pumpkins %>% \n",
|
|
" names()"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "5XtpaIigtPfW"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"🤔 Podemos fazer melhor. Vamos tornar estes nomes de colunas `friendR` ao convertê-los para a convenção [snake_case](https://en.wikipedia.org/wiki/Snake_case) usando `janitor::clean_names`. Para saber mais sobre esta função: `?clean_names`\n"
|
|
],
|
|
"metadata": {
|
|
"id": "IbIqrMINtSHe"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Clean names to the snake_case convention\n",
|
|
"pumpkins <- pumpkins %>% \n",
|
|
" clean_names(case = \"snake\")\n",
|
|
"\n",
|
|
"# Return column names\n",
|
|
"pumpkins %>% \n",
|
|
" names()"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "a2uYvclYtWvX"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Muito tidyR 🧹! Agora, uma dança com os dados usando `dplyr`, como na lição anterior! 💃\n"
|
|
],
|
|
"metadata": {
|
|
"id": "HfhnuzDDtaDd"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Select desired columns\n",
|
|
"pumpkins <- pumpkins %>% \n",
|
|
" select(variety, city_name, package, low_price, high_price, date)\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"# Extract the month from the dates to a new column\n",
|
|
"pumpkins <- pumpkins %>%\n",
|
|
" mutate(date = mdy(date),\n",
|
|
" month = month(date)) %>% \n",
|
|
" select(-date)\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"# Create a new column for average Price\n",
|
|
"pumpkins <- pumpkins %>% \n",
|
|
" mutate(price = (low_price + high_price)/2)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Retain only pumpkins with the string \"bushel\"\n",
|
|
"new_pumpkins <- pumpkins %>% \n",
|
|
" filter(str_detect(string = package, pattern = \"bushel\"))\n",
|
|
"\n",
|
|
"\n",
|
|
"# Normalize the pricing so that you show the pricing per bushel, not per 1 1/9 or 1/2 bushel\n",
|
|
"new_pumpkins <- new_pumpkins %>% \n",
|
|
" mutate(price = case_when(\n",
|
|
" str_detect(package, \"1 1/9\") ~ price/(1.1),\n",
|
|
" str_detect(package, \"1/2\") ~ price*2,\n",
|
|
" TRUE ~ price))\n",
|
|
"\n",
|
|
"# Relocate column positions\n",
|
|
"new_pumpkins <- new_pumpkins %>% \n",
|
|
" relocate(month, .before = variety)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Display the first 5 rows\n",
|
|
"new_pumpkins %>% \n",
|
|
" slice_head(n = 5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "X0wU3gQvtd9f"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Bom trabalho!👌 Agora tens um conjunto de dados limpo e organizado sobre o qual podes construir o teu novo modelo de regressão!\n",
|
|
"\n",
|
|
"Que tal um gráfico de dispersão?\n"
|
|
],
|
|
"metadata": {
|
|
"id": "UpaIwaxqth82"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Set theme\n",
|
|
"theme_set(theme_light())\n",
|
|
"\n",
|
|
"# Make a scatter plot of month and price\n",
|
|
"new_pumpkins %>% \n",
|
|
" ggplot(mapping = aes(x = month, y = price)) +\n",
|
|
" geom_point(size = 1.6)\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "DXgU-j37tl5K"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Um gráfico de dispersão lembra-nos que só temos dados mensais de agosto a dezembro. Provavelmente precisamos de mais dados para conseguir tirar conclusões de forma linear.\n",
|
|
"\n",
|
|
"Vamos analisar novamente os nossos dados de modelação:\n"
|
|
],
|
|
"metadata": {
|
|
"id": "Ve64wVbwtobI"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Display first 5 rows\n",
|
|
"new_pumpkins %>% \n",
|
|
" slice_head(n = 5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "HFQX2ng1tuSJ"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"E se quiséssemos prever o `price` de uma abóbora com base nas colunas `city` ou `package`, que são do tipo carácter? Ou, ainda mais simples, como poderíamos encontrar a correlação (que exige que ambos os seus inputs sejam numéricos) entre, por exemplo, `package` e `price`? 🤷🤷\n",
|
|
"\n",
|
|
"Os modelos de aprendizagem automática funcionam melhor com características numéricas em vez de valores de texto, por isso, geralmente é necessário converter características categóricas em representações numéricas.\n",
|
|
"\n",
|
|
"Isto significa que temos de encontrar uma forma de reformular os nossos preditores para os tornar mais fáceis de usar por um modelo de forma eficaz, um processo conhecido como `feature engineering`.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "7hsHoxsStyjJ"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 3. Pré-processamento de dados para modelação com recipes 👩🍳👨🍳\n",
|
|
"\n",
|
|
"Atividades que reformulam os valores dos preditores para torná-los mais fáceis de usar de forma eficaz por um modelo são chamadas de `engenharia de características`.\n",
|
|
"\n",
|
|
"Modelos diferentes têm requisitos de pré-processamento distintos. Por exemplo, mínimos quadrados requerem `codificação de variáveis categóricas`, como mês, variedade e city_name. Isso envolve simplesmente `traduzir` uma coluna com `valores categóricos` em uma ou mais `colunas numéricas` que substituem a original.\n",
|
|
"\n",
|
|
"Por exemplo, suponha que os seus dados incluam a seguinte característica categórica:\n",
|
|
"\n",
|
|
"| cidade |\n",
|
|
"|:---------:|\n",
|
|
"| Denver |\n",
|
|
"| Nairobi |\n",
|
|
"| Tóquio |\n",
|
|
"\n",
|
|
"Pode aplicar *codificação ordinal* para substituir cada categoria por um valor inteiro único, assim:\n",
|
|
"\n",
|
|
"| cidade |\n",
|
|
"|:------:|\n",
|
|
"| 0 |\n",
|
|
"| 1 |\n",
|
|
"| 2 |\n",
|
|
"\n",
|
|
"E é isso que vamos fazer com os nossos dados!\n",
|
|
"\n",
|
|
"Nesta secção, vamos explorar outro pacote incrível do Tidymodels: [recipes](https://tidymodels.github.io/recipes/) - que foi criado para ajudar a pré-processar os seus dados **antes** de treinar o modelo. No seu núcleo, uma receita é um objeto que define quais passos devem ser aplicados a um conjunto de dados para prepará-lo para a modelação.\n",
|
|
"\n",
|
|
"Agora, vamos criar uma receita que prepara os nossos dados para modelação, substituindo um número inteiro único por todas as observações nas colunas de preditores:\n"
|
|
],
|
|
"metadata": {
|
|
"id": "AD5kQbcvt3Xl"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Specify a recipe\n",
|
|
"pumpkins_recipe <- recipe(price ~ ., data = new_pumpkins) %>% \n",
|
|
" step_integer(all_predictors(), zero_based = TRUE)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Print out the recipe\n",
|
|
"pumpkins_recipe"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "BNaFKXfRt9TU"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Incrível! 👏 Acabámos de criar a nossa primeira receita que especifica um resultado (preço) e os seus respetivos preditores, e que todas as colunas de preditores devem ser codificadas como um conjunto de números inteiros 🙌! Vamos analisar rapidamente:\n",
|
|
"\n",
|
|
"- A chamada para `recipe()` com uma fórmula indica à receita os *papéis* das variáveis, utilizando os dados de `new_pumpkins` como referência. Por exemplo, a coluna `price` foi atribuída ao papel de `outcome`, enquanto o resto das colunas foram atribuídas ao papel de `predictor`.\n",
|
|
"\n",
|
|
"- `step_integer(all_predictors(), zero_based = TRUE)` especifica que todos os preditores devem ser convertidos num conjunto de números inteiros, começando a numeração em 0.\n",
|
|
"\n",
|
|
"Temos a certeza de que pode estar a pensar algo como: \"Isto é tão fixe!! Mas e se eu precisar de confirmar que as receitas estão a fazer exatamente o que espero? 🤔\"\n",
|
|
"\n",
|
|
"Essa é uma ótima ideia! Veja, uma vez que a sua receita está definida, pode estimar os parâmetros necessários para realmente pré-processar os dados e, em seguida, extrair os dados processados. Normalmente, não precisa de fazer isto quando utiliza Tidymodels (vamos ver a convenção normal daqui a pouco-\\> `workflows`), mas pode ser útil quando quiser fazer algum tipo de verificação para confirmar que as receitas estão a funcionar como esperado.\n",
|
|
"\n",
|
|
"Para isso, vai precisar de mais dois verbos: `prep()` e `bake()`. E, como sempre, os nossos pequenos amigos do R criados por [`Allison Horst`](https://github.com/allisonhorst/stats-illustrations) ajudam a compreender isto melhor!\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/recipes.png\"\n",
|
|
" width=\"550\"/>\n",
|
|
" <figcaption>Arte por @allison_horst</figcaption>\n",
|
|
"\n",
|
|
"\n",
|
|
"<!--{width=\"550\"}-->\n"
|
|
],
|
|
"metadata": {
|
|
"id": "KEiO0v7kuC9O"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"[`prep()`](https://recipes.tidymodels.org/reference/prep.html): estima os parâmetros necessários a partir de um conjunto de treino que podem ser posteriormente aplicados a outros conjuntos de dados. Por exemplo, para uma determinada coluna preditora, qual observação será atribuída ao número inteiro 0, 1, 2, etc.\n",
|
|
"\n",
|
|
"[`bake()`](https://recipes.tidymodels.org/reference/bake.html): utiliza uma receita preparada e aplica as operações a qualquer conjunto de dados.\n",
|
|
"\n",
|
|
"Dito isto, vamos preparar e aplicar as nossas receitas para realmente confirmar que, nos bastidores, as colunas preditoras serão primeiro codificadas antes de ajustar um modelo.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "Q1xtzebuuTCP"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Prep the recipe\n",
|
|
"pumpkins_prep <- prep(pumpkins_recipe)\n",
|
|
"\n",
|
|
"# Bake the recipe to extract a preprocessed new_pumpkins data\n",
|
|
"baked_pumpkins <- bake(pumpkins_prep, new_data = NULL)\n",
|
|
"\n",
|
|
"# Print out the baked data set\n",
|
|
"baked_pumpkins %>% \n",
|
|
" slice_head(n = 10)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "FGBbJbP_uUUn"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Woo-hoo!🥳 Os dados processados `baked_pumpkins` têm todos os seus preditores codificados, confirmando que, de facto, os passos de pré-processamento definidos como a nossa receita funcionarão conforme esperado. Isto torna mais difícil para ti ler, mas muito mais inteligível para o Tidymodels! Dedica algum tempo a descobrir que observação foi mapeada para um número inteiro correspondente.\n",
|
|
"\n",
|
|
"Também vale a pena mencionar que `baked_pumpkins` é um data frame no qual podemos realizar cálculos.\n",
|
|
"\n",
|
|
"Por exemplo, vamos tentar encontrar uma boa correlação entre dois pontos dos teus dados para, potencialmente, construir um bom modelo preditivo. Vamos usar a função `cor()` para fazer isto. Escreve `?cor()` para saberes mais sobre a função.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "1dvP0LBUueAW"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Find the correlation between the city_name and the price\n",
|
|
"cor(baked_pumpkins$city_name, baked_pumpkins$price)\n",
|
|
"\n",
|
|
"# Find the correlation between the package and the price\n",
|
|
"cor(baked_pumpkins$package, baked_pumpkins$price)\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "3bQzXCjFuiSV"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Afinal, há apenas uma correlação fraca entre a Cidade e o Preço. No entanto, há uma correlação um pouco melhor entre o Pacote e o seu Preço. Faz sentido, certo? Normalmente, quanto maior a caixa de produtos, maior o preço.\n",
|
|
"\n",
|
|
"Já que estamos nisso, vamos também tentar visualizar uma matriz de correlação de todas as colunas usando o pacote `corrplot`.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "BToPWbgjuoZw"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Load the corrplot package\n",
|
|
"library(corrplot)\n",
|
|
"\n",
|
|
"# Obtain correlation matrix\n",
|
|
"corr_mat <- cor(baked_pumpkins %>% \n",
|
|
" # Drop columns that are not really informative\n",
|
|
" select(-c(low_price, high_price)))\n",
|
|
"\n",
|
|
"# Make a correlation plot between the variables\n",
|
|
"corrplot(corr_mat, method = \"shade\", shade.col = NA, tl.col = \"black\", tl.srt = 45, addCoef.col = \"black\", cl.pos = \"n\", order = \"original\")"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "ZwAL3ksmutVR"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"🤩🤩 Muito melhor.\n",
|
|
"\n",
|
|
"Uma boa pergunta a fazer agora com estes dados seria: '`Que preço posso esperar de um determinado pacote de abóboras?`' Vamos começar!\n",
|
|
"\n",
|
|
"> Nota: Quando **`bake()`** a receita preparada **`pumpkins_prep`** com **`new_data = NULL`**, extrai os dados de treino processados (ou seja, codificados). Se tiver outro conjunto de dados, por exemplo, um conjunto de teste, e quiser ver como uma receita o pré-processaria, basta fazer o bake de **`pumpkins_prep`** com **`new_data = test_set`**.\n",
|
|
"\n",
|
|
"## 4. Construir um modelo de regressão linear\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/linear-polynomial.png\"\n",
|
|
" width=\"800\"/>\n",
|
|
" <figcaption>Infográfico por Dasani Madipalli</figcaption>\n",
|
|
"\n",
|
|
"\n",
|
|
"<!--{width=\"800\"}-->\n"
|
|
],
|
|
"metadata": {
|
|
"id": "YqXjLuWavNxW"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Agora que criámos uma receita e confirmámos que os dados serão pré-processados de forma adequada, vamos agora construir um modelo de regressão para responder à pergunta: `Qual o preço que posso esperar de um determinado pacote de abóbora?`\n",
|
|
"\n",
|
|
"#### Treinar um modelo de regressão linear utilizando o conjunto de treino\n",
|
|
"\n",
|
|
"Como já deve ter percebido, a coluna *price* é a variável `resultado`, enquanto a coluna *package* é a variável `preditor`.\n",
|
|
"\n",
|
|
"Para isso, primeiro vamos dividir os dados de forma que 80% sejam usados para treino e 20% para teste, depois definiremos uma receita que codificará a coluna preditora num conjunto de inteiros e, em seguida, construiremos uma especificação de modelo. Não vamos preparar e aplicar a nossa receita, pois já sabemos que ela irá pré-processar os dados conforme esperado.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "Pq0bSzCevW-h"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"set.seed(2056)\n",
|
|
"# Split the data into training and test sets\n",
|
|
"pumpkins_split <- new_pumpkins %>% \n",
|
|
" initial_split(prop = 0.8)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Extract training and test data\n",
|
|
"pumpkins_train <- training(pumpkins_split)\n",
|
|
"pumpkins_test <- testing(pumpkins_split)\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"# Create a recipe for preprocessing the data\n",
|
|
"lm_pumpkins_recipe <- recipe(price ~ package, data = pumpkins_train) %>% \n",
|
|
" step_integer(all_predictors(), zero_based = TRUE)\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"# Create a linear model specification\n",
|
|
"lm_spec <- linear_reg() %>% \n",
|
|
" set_engine(\"lm\") %>% \n",
|
|
" set_mode(\"regression\")"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "CyoEh_wuvcLv"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Bom trabalho! Agora que temos uma receita e uma especificação de modelo, precisamos encontrar uma forma de agrupá-los num objeto que primeiro pré-processa os dados (prep+bake nos bastidores), ajusta o modelo nos dados pré-processados e também permite possíveis atividades de pós-processamento. Que tal para a tua tranquilidade!🤩\n",
|
|
"\n",
|
|
"No Tidymodels, este objeto prático chama-se [`workflow`](https://workflows.tidymodels.org/) e guarda convenientemente os teus componentes de modelação! Isto é o que chamaríamos de *pipelines* em *Python*.\n",
|
|
"\n",
|
|
"Então, vamos agrupar tudo num workflow!📦\n"
|
|
],
|
|
"metadata": {
|
|
"id": "G3zF_3DqviFJ"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Hold modelling components in a workflow\n",
|
|
"lm_wf <- workflow() %>% \n",
|
|
" add_recipe(lm_pumpkins_recipe) %>% \n",
|
|
" add_model(lm_spec)\n",
|
|
"\n",
|
|
"# Print out the workflow\n",
|
|
"lm_wf"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "T3olroU3v-WX"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Além disso, um fluxo de trabalho pode ser ajustado/treinado de forma muito semelhante a um modelo.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "zd1A5tgOwEPX"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Train the model\n",
|
|
"lm_wf_fit <- lm_wf %>% \n",
|
|
" fit(data = pumpkins_train)\n",
|
|
"\n",
|
|
"# Print the model coefficients learned \n",
|
|
"lm_wf_fit"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "NhJagFumwFHf"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"A partir dos resultados do modelo, podemos observar os coeficientes aprendidos durante o treino. Eles representam os coeficientes da linha de melhor ajuste que nos proporciona o menor erro geral entre a variável real e a prevista.\n",
|
|
"\n",
|
|
"#### Avaliar o desempenho do modelo utilizando o conjunto de teste\n",
|
|
"\n",
|
|
"É hora de ver como o modelo se saiu 📏! Como fazemos isso?\n",
|
|
"\n",
|
|
"Agora que treinámos o modelo, podemos utilizá-lo para fazer previsões no test_set usando `parsnip::predict()`. Depois, podemos comparar estas previsões com os valores reais das etiquetas para avaliar quão bem (ou não!) o modelo está a funcionar.\n",
|
|
"\n",
|
|
"Vamos começar por fazer previsões para o conjunto de teste e, em seguida, ligar as colunas ao conjunto de teste.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "_4QkGtBTwItF"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Make predictions for the test set\n",
|
|
"predictions <- lm_wf_fit %>% \n",
|
|
" predict(new_data = pumpkins_test)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Bind predictions to the test set\n",
|
|
"lm_results <- pumpkins_test %>% \n",
|
|
" select(c(package, price)) %>% \n",
|
|
" bind_cols(predictions)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Print the first ten rows of the tibble\n",
|
|
"lm_results %>% \n",
|
|
" slice_head(n = 10)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "UFZzTG0gwTs9"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Sim, acabou de treinar um modelo e utilizou-o para fazer previsões! 🔮 Será que é bom? Vamos avaliar o desempenho do modelo!\n",
|
|
"\n",
|
|
"No Tidymodels, fazemos isso utilizando `yardstick::metrics()`! Para regressão linear, vamos focar nas seguintes métricas:\n",
|
|
"\n",
|
|
"- `Root Mean Square Error (RMSE)`: A raiz quadrada do [MSE](https://en.wikipedia.org/wiki/Mean_squared_error). Esta métrica fornece um valor absoluto na mesma unidade que o rótulo (neste caso, o preço de uma abóbora). Quanto menor o valor, melhor o modelo (de forma simplista, representa o preço médio pelo qual as previsões estão erradas!).\n",
|
|
"\n",
|
|
"- `Coefficient of Determination (geralmente conhecido como R-quadrado ou R2)`: Uma métrica relativa em que, quanto maior o valor, melhor o ajuste do modelo. Essencialmente, esta métrica representa o quanto da variância entre os valores previstos e os valores reais o modelo consegue explicar.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "0A5MjzM7wW9M"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Evaluate performance of linear regression\n",
|
|
"metrics(data = lm_results,\n",
|
|
" truth = price,\n",
|
|
" estimate = .pred)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "reJ0UIhQwcEH"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Lá se vai o desempenho do modelo. Vamos ver se conseguimos obter uma indicação melhor ao visualizar um gráfico de dispersão do pacote e do preço, e depois usar as previsões feitas para sobrepor uma linha de melhor ajuste.\n",
|
|
"\n",
|
|
"Isto significa que teremos de preparar e processar o conjunto de teste para codificar a coluna do pacote e, em seguida, associar isso às previsões feitas pelo nosso modelo.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "fdgjzjkBwfWt"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Encode package column\n",
|
|
"package_encode <- lm_pumpkins_recipe %>% \n",
|
|
" prep() %>% \n",
|
|
" bake(new_data = pumpkins_test) %>% \n",
|
|
" select(package)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Bind encoded package column to the results\n",
|
|
"lm_results <- lm_results %>% \n",
|
|
" bind_cols(package_encode %>% \n",
|
|
" rename(package_integer = package)) %>% \n",
|
|
" relocate(package_integer, .after = package)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Print new results data frame\n",
|
|
"lm_results %>% \n",
|
|
" slice_head(n = 5)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Make a scatter plot\n",
|
|
"lm_results %>% \n",
|
|
" ggplot(mapping = aes(x = package_integer, y = price)) +\n",
|
|
" geom_point(size = 1.6) +\n",
|
|
" # Overlay a line of best fit\n",
|
|
" geom_line(aes(y = .pred), color = \"orange\", size = 1.2) +\n",
|
|
" xlab(\"package\")\n",
|
|
" \n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "R0nw719lwkHE"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Ótimo! Como pode ver, o modelo de regressão linear não generaliza muito bem a relação entre um pacote e o seu preço correspondente.\n",
|
|
"\n",
|
|
"🎃 Parabéns, acabou de criar um modelo que pode ajudar a prever o preço de algumas variedades de abóboras. O seu campo de abóboras para o feriado será lindo. Mas provavelmente pode criar um modelo ainda melhor!\n",
|
|
"\n",
|
|
"## 5. Construir um modelo de regressão polinomial\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/linear-polynomial.png\"\n",
|
|
" width=\"800\"/>\n",
|
|
" <figcaption>Infográfico por Dasani Madipalli</figcaption>\n",
|
|
"\n",
|
|
"\n",
|
|
"<!--{width=\"800\"}-->\n"
|
|
],
|
|
"metadata": {
|
|
"id": "HOCqJXLTwtWI"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Às vezes, os nossos dados podem não ter uma relação linear, mas ainda assim queremos prever um resultado. A regressão polinomial pode ajudar-nos a fazer previsões para relações não lineares mais complexas.\n",
|
|
"\n",
|
|
"Por exemplo, considere a relação entre o tamanho e o preço no nosso conjunto de dados de abóboras. Embora, por vezes, exista uma relação linear entre as variáveis - quanto maior o volume da abóbora, maior o preço - outras vezes estas relações não podem ser representadas como um plano ou uma linha reta.\n",
|
|
"\n",
|
|
"> ✅ Aqui estão [alguns exemplos adicionais](https://online.stat.psu.edu/stat501/lesson/9/9.8) de dados que poderiam usar regressão polinomial\n",
|
|
">\n",
|
|
"> Observe novamente a relação entre Variedade e Preço no gráfico anterior. Este diagrama de dispersão parece que deveria ser necessariamente analisado por uma linha reta? Talvez não. Neste caso, pode experimentar a regressão polinomial.\n",
|
|
">\n",
|
|
"> ✅ Polinómios são expressões matemáticas que podem consistir em uma ou mais variáveis e coeficientes\n",
|
|
"\n",
|
|
"#### Treinar um modelo de regressão polinomial usando o conjunto de treino\n",
|
|
"\n",
|
|
"A regressão polinomial cria uma *linha curva* para ajustar melhor os dados não lineares.\n",
|
|
"\n",
|
|
"Vamos ver se um modelo polinomial terá um desempenho melhor ao fazer previsões. Seguiremos um procedimento algo semelhante ao que fizemos anteriormente:\n",
|
|
"\n",
|
|
"- Criar uma receita que especifique os passos de pré-processamento que devem ser realizados nos nossos dados para os preparar para modelação, ou seja: codificar preditores e calcular polinómios de grau *n*\n",
|
|
"\n",
|
|
"- Construir uma especificação de modelo\n",
|
|
"\n",
|
|
"- Agrupar a receita e a especificação de modelo num fluxo de trabalho\n",
|
|
"\n",
|
|
"- Criar um modelo ajustando o fluxo de trabalho\n",
|
|
"\n",
|
|
"- Avaliar o desempenho do modelo nos dados de teste\n",
|
|
"\n",
|
|
"Vamos começar!\n"
|
|
],
|
|
"metadata": {
|
|
"id": "VcEIpRV9wzYr"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Specify a recipe\r\n",
|
|
"poly_pumpkins_recipe <-\r\n",
|
|
" recipe(price ~ package, data = pumpkins_train) %>%\r\n",
|
|
" step_integer(all_predictors(), zero_based = TRUE) %>% \r\n",
|
|
" step_poly(all_predictors(), degree = 4)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Create a model specification\r\n",
|
|
"poly_spec <- linear_reg() %>% \r\n",
|
|
" set_engine(\"lm\") %>% \r\n",
|
|
" set_mode(\"regression\")\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Bundle recipe and model spec into a workflow\r\n",
|
|
"poly_wf <- workflow() %>% \r\n",
|
|
" add_recipe(poly_pumpkins_recipe) %>% \r\n",
|
|
" add_model(poly_spec)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Create a model\r\n",
|
|
"poly_wf_fit <- poly_wf %>% \r\n",
|
|
" fit(data = pumpkins_train)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Print learned model coefficients\r\n",
|
|
"poly_wf_fit\r\n",
|
|
"\r\n",
|
|
" "
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "63n_YyRXw3CC"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"#### Avaliar o desempenho do modelo\n",
|
|
"\n",
|
|
"👏👏Construíste um modelo polinomial, vamos fazer previsões no conjunto de teste!\n"
|
|
],
|
|
"metadata": {
|
|
"id": "-LHZtztSxDP0"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Make price predictions on test data\r\n",
|
|
"poly_results <- poly_wf_fit %>% predict(new_data = pumpkins_test) %>% \r\n",
|
|
" bind_cols(pumpkins_test %>% select(c(package, price))) %>% \r\n",
|
|
" relocate(.pred, .after = last_col())\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Print the results\r\n",
|
|
"poly_results %>% \r\n",
|
|
" slice_head(n = 10)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "YUFpQ_dKxJGx"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Woo-hoo, vamos avaliar como o modelo se saiu no test_set usando `yardstick::metrics()`.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "qxdyj86bxNGZ"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"metrics(data = poly_results, truth = price, estimate = .pred)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "8AW5ltkBxXDm"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"🤩🤩 Desempenho muito melhor.\n",
|
|
"\n",
|
|
"O `rmse` diminuiu de cerca de 7 para cerca de 3, uma indicação de um erro reduzido entre o preço real e o preço previsto. Pode-se *interpretar de forma aproximada* que, em média, as previsões incorretas erram por cerca de 3€. O `rsq` aumentou de cerca de 0.4 para 0.8.\n",
|
|
"\n",
|
|
"Todos estes indicadores mostram que o modelo polinomial tem um desempenho muito superior ao modelo linear. Bom trabalho!\n",
|
|
"\n",
|
|
"Vamos ver se conseguimos visualizar isto!\n"
|
|
],
|
|
"metadata": {
|
|
"id": "6gLHNZDwxYaS"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Bind encoded package column to the results\r\n",
|
|
"poly_results <- poly_results %>% \r\n",
|
|
" bind_cols(package_encode %>% \r\n",
|
|
" rename(package_integer = package)) %>% \r\n",
|
|
" relocate(package_integer, .after = package)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Print new results data frame\r\n",
|
|
"poly_results %>% \r\n",
|
|
" slice_head(n = 5)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Make a scatter plot\r\n",
|
|
"poly_results %>% \r\n",
|
|
" ggplot(mapping = aes(x = package_integer, y = price)) +\r\n",
|
|
" geom_point(size = 1.6) +\r\n",
|
|
" # Overlay a line of best fit\r\n",
|
|
" geom_line(aes(y = .pred), color = \"midnightblue\", size = 1.2) +\r\n",
|
|
" xlab(\"package\")\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "A83U16frxdF1"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Pode ver uma linha curva que se ajusta melhor aos seus dados! 🤩\n",
|
|
"\n",
|
|
"Pode torná-la mais suave ao passar uma fórmula polinomial para `geom_smooth` assim:\n"
|
|
],
|
|
"metadata": {
|
|
"id": "4U-7aHOVxlGU"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Make a scatter plot\r\n",
|
|
"poly_results %>% \r\n",
|
|
" ggplot(mapping = aes(x = package_integer, y = price)) +\r\n",
|
|
" geom_point(size = 1.6) +\r\n",
|
|
" # Overlay a line of best fit\r\n",
|
|
" geom_smooth(method = lm, formula = y ~ poly(x, degree = 4), color = \"midnightblue\", size = 1.2, se = FALSE) +\r\n",
|
|
" xlab(\"package\")"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "5vzNT0Uexm-w"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Muito parecido com uma curva suave!🤩\n",
|
|
"\n",
|
|
"Aqui está como fazer uma nova previsão:\n"
|
|
],
|
|
"metadata": {
|
|
"id": "v9u-wwyLxq4G"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Make a hypothetical data frame\r\n",
|
|
"hypo_tibble <- tibble(package = \"bushel baskets\")\r\n",
|
|
"\r\n",
|
|
"# Make predictions using linear model\r\n",
|
|
"lm_pred <- lm_wf_fit %>% predict(new_data = hypo_tibble)\r\n",
|
|
"\r\n",
|
|
"# Make predictions using polynomial model\r\n",
|
|
"poly_pred <- poly_wf_fit %>% predict(new_data = hypo_tibble)\r\n",
|
|
"\r\n",
|
|
"# Return predictions in a list\r\n",
|
|
"list(\"linear model prediction\" = lm_pred, \r\n",
|
|
" \"polynomial model prediction\" = poly_pred)\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "jRPSyfQGxuQv"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"A previsão do `polynomial model` faz sentido, considerando os gráficos de dispersão de `price` e `package`! E, se este modelo for melhor do que o anterior, olhando para os mesmos dados, será necessário prever um orçamento para estas abóboras mais caras!\n",
|
|
"\n",
|
|
"🏆 Muito bem! Você criou dois modelos de regressão em uma única lição. Na seção final sobre regressão, aprenderá sobre regressão logística para determinar categorias.\n",
|
|
"\n",
|
|
"## **🚀Desafio**\n",
|
|
"\n",
|
|
"Teste várias variáveis diferentes neste notebook para ver como a correlação corresponde à precisão do modelo.\n",
|
|
"\n",
|
|
"## [**Questionário pós-aula**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/14/)\n",
|
|
"\n",
|
|
"## **Revisão & Estudo Autônomo**\n",
|
|
"\n",
|
|
"Nesta lição aprendemos sobre Regressão Linear. Existem outros tipos importantes de Regressão. Leia sobre as técnicas Stepwise, Ridge, Lasso e Elasticnet. Um bom curso para aprender mais é o [curso de Aprendizagem Estatística de Stanford](https://online.stanford.edu/courses/sohs-ystatslearning-statistical-learning).\n",
|
|
"\n",
|
|
"Se quiser aprender mais sobre como usar o incrível framework Tidymodels, consulte os seguintes recursos:\n",
|
|
"\n",
|
|
"- Website do Tidymodels: [Introdução ao Tidymodels](https://www.tidymodels.org/start/)\n",
|
|
"\n",
|
|
"- Max Kuhn e Julia Silge, [*Tidy Modeling with R*](https://www.tmwr.org/)*.*\n",
|
|
"\n",
|
|
"###### **AGRADECIMENTOS A:**\n",
|
|
"\n",
|
|
"[Allison Horst](https://twitter.com/allison_horst?lang=en) 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"
|
|
],
|
|
"metadata": {
|
|
"id": "8zOLOWqMxzk5"
|
|
}
|
|
},
|
|
{
|
|
"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, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original no seu idioma nativo deve ser considerado a fonte oficial. Para informações críticas, recomenda-se uma tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas resultantes do uso desta tradução.\n"
|
|
]
|
|
}
|
|
]
|
|
} |