{ "nbformat": 4, "nbformat_minor": 2, "metadata": { "colab": { "name": "lesson_2-R.ipynb", "provenance": [], "collapsed_sections": [], "toc_visible": true }, "kernelspec": { "name": "ir", "display_name": "R" }, "language_info": { "name": "R" }, "coopTranslator": { "original_hash": "f3c335f9940cfd76528b3ef918b9b342", "translation_date": "2025-09-03T19:48:56+00:00", "source_file": "2-Regression/2-Data/solution/R/lesson_2-R.ipynb", "language_code": "pt" } }, "cells": [ { "cell_type": "markdown", "source": [ "# Construir um modelo de regressão: preparar e visualizar dados\n", "\n", "## **Regressão Linear para Abóboras - Aula 2**\n", "#### Introdução\n", "\n", "Agora que já tem as ferramentas necessárias para começar a construir modelos de machine learning com Tidymodels e Tidyverse, está pronto para começar a fazer perguntas aos seus dados. Ao trabalhar com dados e aplicar soluções de ML, é muito importante saber como formular a pergunta certa para desbloquear adequadamente o potencial do seu conjunto de dados.\n", "\n", "Nesta aula, irá aprender:\n", "\n", "- Como preparar os seus dados para a construção de modelos.\n", "\n", "- Como usar `ggplot2` para visualização de dados.\n", "\n", "A pergunta que precisa de responder determinará o tipo de algoritmos de ML que irá utilizar. E a qualidade da resposta que obtém dependerá fortemente da natureza dos seus dados.\n", "\n", "Vamos ver isso através de um exercício prático.\n", "\n", "
\n",
" \n",
"
\n",
"\n",
"> Um lembrete: O operador pipe (`%>%`) realiza operações numa sequência lógica ao passar um objeto para uma função ou expressão. Pode pensar no operador pipe como dizendo \"e depois\" no seu código.\n"
],
"metadata": {
"id": "REWcIv9yX29v"
}
},
{
"cell_type": "markdown",
"source": [
"## 2. Verificar dados em falta\n",
"\n",
"Um dos problemas mais comuns que os cientistas de dados enfrentam é lidar com dados incompletos ou em falta. O R representa valores em falta, ou desconhecidos, com um valor especial chamado `NA` (Not Available).\n",
"\n",
"Então, como podemos saber se o data frame contém valores em falta?\n",
"
\n",
"- Uma forma direta seria usar a função base do R `anyNA`, que retorna os objetos lógicos `TRUE` ou `FALSE`.\n"
],
"metadata": {
"id": "Zxfb3AM5YbUe"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" anyNA()"
],
"outputs": [],
"metadata": {
"id": "G--DQutAYltj"
}
},
{
"cell_type": "markdown",
"source": [
"Ótimo, parece que há alguns dados em falta! Esse é um bom ponto de partida.\n",
"\n",
"- Outra forma seria usar a função `is.na()` que indica quais elementos individuais das colunas estão em falta com um valor lógico `TRUE`.\n"
],
"metadata": {
"id": "mU-7-SB6YokF"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" is.na() %>% \n",
" head(n = 7)"
],
"outputs": [],
"metadata": {
"id": "W-DxDOR4YxSW"
}
},
{
"cell_type": "markdown",
"source": [
"Ok, trabalho concluído, mas com um conjunto de dados tão grande como este, seria ineficiente e praticamente impossível rever todas as linhas e colunas individualmente😴.\n",
"\n",
"- Uma forma mais intuitiva seria calcular a soma dos valores em falta para cada coluna:\n"
],
"metadata": {
"id": "xUWxipKYY0o7"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" is.na() %>% \n",
" colSums()"
],
"outputs": [],
"metadata": {
"id": "ZRBWV6P9ZArL"
}
},
{
"cell_type": "markdown",
"source": [
"Muito melhor! Faltam alguns dados, mas talvez isso não seja relevante para a tarefa em questão. Vamos ver que tipo de análise adicional pode surgir.\n",
"\n",
"> Além dos conjuntos incríveis de pacotes e funções, o R possui uma documentação muito boa. Por exemplo, use `help(colSums)` ou `?colSums` para saber mais sobre a função.\n"
],
"metadata": {
"id": "9gv-crB6ZD1Y"
}
},
{
"cell_type": "markdown",
"source": [
"## 3. Dplyr: Uma Gramática para Manipulação de Dados\n",
"\n",
"
\n",
" \n",
"
\n"
],
"metadata": {
"id": "nIgLjNMCZ-6Y"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Create a new column Price\n",
"pumpkins <- pumpkins %>% \n",
" mutate(Price = (`Low Price` + `High Price`)/2)\n",
"\n",
"# View the first few rows of the data\n",
"pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "Zo0BsqqtaJw2"
}
},
{
"cell_type": "markdown",
"source": [
"Sim!💪\n",
"\n",
"\"Mas espera aí!\", dirás depois de examinar todo o conjunto de dados com `View(pumpkins)`, \"Há algo estranho aqui!\"🤔\n",
"\n",
"Se olhares para a coluna `Package`, as abóboras são vendidas em várias configurações diferentes. Algumas são vendidas em medidas de `1 1/9 bushel`, outras em medidas de `1/2 bushel`, algumas por abóbora, outras por peso, e algumas em grandes caixas com larguras variadas.\n",
"\n",
"Vamos verificar isto:\n"
],
"metadata": {
"id": "p77WZr-9aQAR"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Verify the distinct observations in Package column\n",
"pumpkins %>% \n",
" distinct(Package)"
],
"outputs": [],
"metadata": {
"id": "XISGfh0IaUy6"
}
},
{
"cell_type": "markdown",
"source": [
"Incrível!👏\n",
"\n",
"As abóboras parecem ser muito difíceis de pesar de forma consistente, por isso vamos filtrá-las selecionando apenas as abóboras com a palavra *bushel* na coluna `Package` e colocar isso num novo quadro de dados `new_pumpkins`.\n"
],
"metadata": {
"id": "7sMjiVujaZxY"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::filter() e stringr::str_detect()\n",
"\n",
"[`dplyr::filter()`](https://dplyr.tidyverse.org/reference/filter.html): cria um subconjunto dos dados contendo apenas as **linhas** que satisfazem as suas condições, neste caso, abóboras com a string *bushel* na coluna `Package`.\n",
"\n",
"[stringr::str_detect()](https://stringr.tidyverse.org/reference/str_detect.html): deteta a presença ou ausência de um padrão numa string.\n",
"\n",
"O pacote [`stringr`](https://github.com/tidyverse/stringr) fornece funções simples para operações comuns com strings.\n"
],
"metadata": {
"id": "L8Qfcs92ageF"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Retain only pumpkins with \"bushel\"\n",
"new_pumpkins <- pumpkins %>% \n",
" filter(str_detect(Package, \"bushel\"))\n",
"\n",
"# Get the dimensions of the new data\n",
"dim(new_pumpkins)\n",
"\n",
"# View a few rows of the new data\n",
"new_pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "hy_SGYREampd"
}
},
{
"cell_type": "markdown",
"source": [
"Pode ver que reduzimos para cerca de 415 linhas de dados contendo abóboras por alqueire.🤩 \n"
],
"metadata": {
"id": "VrDwF031avlR"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::case_when()\n",
"\n",
"**Mas espera! Ainda há algo mais a fazer**\n",
"\n",
"Reparaste que a quantidade por alqueire varia por linha? É necessário normalizar os preços para que sejam apresentados por alqueire, e não por 1 1/9 ou 1/2 alqueire. Está na hora de fazer alguns cálculos para os padronizar.\n",
"\n",
"Vamos usar a função [`case_when()`](https://dplyr.tidyverse.org/reference/case_when.html) para *alterar* a coluna Price com base em algumas condições. `case_when` permite vectorizar múltiplas instruções `if_else()`.\n"
],
"metadata": {
"id": "mLpw2jH4a0tx"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Convert the price if the Package contains fractional bushel values\n",
"new_pumpkins <- new_pumpkins %>% \n",
" mutate(Price = case_when(\n",
" str_detect(Package, \"1 1/9\") ~ Price/(1 + 1/9),\n",
" str_detect(Package, \"1/2\") ~ Price/(1/2),\n",
" TRUE ~ Price))\n",
"\n",
"# View the first few rows of the data\n",
"new_pumpkins %>% \n",
" slice_head(n = 30)"
],
"outputs": [],
"metadata": {
"id": "P68kLVQmbM6I"
}
},
{
"cell_type": "markdown",
"source": [
"Agora podemos analisar o preço por unidade com base na sua medida em alqueires. Todo este estudo sobre alqueires de abóboras, no entanto, mostra como é `importante` `compreender a natureza dos seus dados`!\n",
"\n",
"> ✅ De acordo com [The Spruce Eats](https://www.thespruceeats.com/how-much-is-a-bushel-1389308), o peso de um alqueire depende do tipo de produto, já que é uma medida de volume. \"Um alqueire de tomates, por exemplo, deve pesar 56 libras... Folhas e verduras ocupam mais espaço com menos peso, então um alqueire de espinafre pesa apenas 20 libras.\" É tudo bastante complicado! Não vamos nos preocupar em fazer uma conversão de alqueires para libras e, em vez disso, vamos precificar por alqueire. Todo este estudo sobre alqueires de abóboras, no entanto, mostra como é muito importante compreender a natureza dos seus dados!\n",
">\n",
"> ✅ Reparaste que as abóboras vendidas por meio alqueire são muito caras? Consegues descobrir porquê? Dica: abóboras pequenas são muito mais caras do que as grandes, provavelmente porque há muito mais delas por alqueire, considerando o espaço não utilizado ocupado por uma grande abóbora oca para tartes.\n"
],
"metadata": {
"id": "pS2GNPagbSdb"
}
},
{
"cell_type": "markdown",
"source": [
"Agora, por pura diversão 💁♀️, vamos também mover a coluna Mês para a primeira posição, ou seja, `antes` da coluna `Pacote`.\n",
"\n",
"`dplyr::relocate()` é usado para alterar as posições das colunas.\n"
],
"metadata": {
"id": "qql1SowfbdnP"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Create a new data frame new_pumpkins\n",
"new_pumpkins <- new_pumpkins %>% \n",
" relocate(Month, .before = Package)\n",
"\n",
"new_pumpkins %>% \n",
" slice_head(n = 7)"
],
"outputs": [],
"metadata": {
"id": "JJ1x6kw8bixF"
}
},
{
"cell_type": "markdown",
"source": [
"Bom trabalho!👌 Agora tens um conjunto de dados limpo e organizado para construir o teu novo modelo de regressão!\n"
],
"metadata": {
"id": "y8TJ0Za_bn5Y"
}
},
{
"cell_type": "markdown",
"source": [
"## 4. Visualização de dados com ggplot2\n",
"\n",
"
\n",
" \n",
"
\n"
],
"metadata": {
"id": "Ml7SDCLQcPvE"
}
},
{
"cell_type": "markdown",
"source": [
"### **Como torná-lo útil?**\n",
"\n",
"Para que os gráficos exibam dados úteis, normalmente é necessário agrupar os dados de alguma forma. Por exemplo, no nosso caso, calcular o preço médio das abóboras para cada mês proporcionaria mais insights sobre os padrões subjacentes nos nossos dados. Isso leva-nos a mais uma abordagem rápida do **dplyr**:\n",
"\n",
"#### `dplyr::group_by() %>% summarize()`\n",
"\n",
"A agregação agrupada em R pode ser facilmente calculada usando\n",
"\n",
"`dplyr::group_by() %>% summarize()`\n",
"\n",
"- `dplyr::group_by()` altera a unidade de análise do conjunto de dados completo para grupos individuais, como por mês.\n",
"\n",
"- `dplyr::summarize()` cria um novo data frame com uma coluna para cada variável de agrupamento e uma coluna para cada estatística resumida que especificares.\n",
"\n",
"Por exemplo, podemos usar `dplyr::group_by() %>% summarize()` para agrupar as abóboras com base na coluna **Month** e, em seguida, calcular o **preço médio** para cada mês.\n"
],
"metadata": {
"id": "jMakvJZIcVkh"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Find the average price of pumpkins per month\r\n",
"new_pumpkins %>%\r\n",
" group_by(Month) %>% \r\n",
" summarise(mean_price = mean(Price))"
],
"outputs": [],
"metadata": {
"id": "6kVSUa2Bcilf"
}
},
{
"cell_type": "markdown",
"source": [
"Sucinto!✨\n",
"\n",
"Características categóricas, como meses, são melhor representadas utilizando um gráfico de barras 📊. As camadas responsáveis pelos gráficos de barras são `geom_bar()` e `geom_col()`. Consulte `?geom_bar` para saber mais.\n",
"\n",
"Vamos criar um agora!\n"
],
"metadata": {
"id": "Kds48GUBcj3W"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Find the average price of pumpkins per month then plot a bar chart\r\n",
"new_pumpkins %>%\r\n",
" group_by(Month) %>% \r\n",
" summarise(mean_price = mean(Price)) %>% \r\n",
" ggplot(aes(x = Month, y = mean_price)) +\r\n",
" geom_col(fill = \"midnightblue\", alpha = 0.7) +\r\n",
" ylab(\"Pumpkin Price\")"
],
"outputs": [],
"metadata": {
"id": "VNbU1S3BcrxO"
}
},
{
"cell_type": "markdown",
"source": [
"🤩🤩Esta é uma visualização de dados mais útil! Parece indicar que o preço mais alto das abóboras ocorre em setembro e outubro. Isso corresponde às suas expectativas? Porquê ou porquê não?\n",
"\n",
"Parabéns por concluir a segunda lição 👏! Preparou os seus dados para a construção do modelo e, em seguida, descobriu mais informações através de visualizações!\n"
],
"metadata": {
"id": "zDm0VOzzcuzR"
}
},
{
"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 do uso desta tradução.\n"
]
}
]
}