Definição dos Pacotes, Python e Ambiente Virtual

Nesta etapa, vamos definir os pacotes que utilizaremos no R e Python, além de criar um ambiente virtual para o Python. O ambiente virtual é uma prática recomendada para evitar conflitos entre pacotes e versões.

if (!requireNamespace("pacman", quietly = TRUE)) install.packages("pacman")
pacman::p_load(
  tidyverse, # Para manipulação de dados
  tidymodels, # Para machine learning
  ranger, # Para Random Forest
  janitor, # Para limpeza de dados
  dplyr, # Para manipulação de dados
  reticulate, # Para integração com Python
  knitr, # Para gerar documentos dinâmicos
  ggplot2, # Para visualização de dados
  readr, # Para leitura de dados
  rmarkdown, # Para gerar documentos dinâmicos
  corrplot, # Para visualização de matrizes de correlação
  prettydoc, # Para formatação de documentos
  shiny, # Para criar aplicativos interativos
  packrat, # Para publicar o site
  rsconnect) # Para publicar o site

if (!virtualenv_exists(env_name)) {
  virtualenv_create(env_name, python = python_path)
}
use_virtualenv(env_name, required = TRUE)

py_install(c(
  "pandas", # Para manipulação de dataframes
  "numpy", # Para manipulação de dados
  "matplotlib", # Para visualização de dados
  "seaborn", # Para visualização de dados
  "scipy" # Para estatísticas
), pip = TRUE)
## Using virtual environment "C:/Users/pedro.munizc/Documents/.virtualenvs/mineracao" ...

Importação dos Dataframes

Nesta estepa, vamos importar os dataframes de vinhos tintos e brancos do repositório UCI Machine Learning. Os dados estão disponíveis em formato CSV e serão lidos diretamente do link.

import pandas as pd

wine_white = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-white.csv", sep=";")
wine_red = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv", sep=";")

wine_white.to_csv("wine_white.csv", index=False)
wine_red.to_csv("wine_red.csv", index=False)

Análise Exploratória

Nesta etapa, vamos realizar uma análise exploratória dos dados. Vamos verificar a forma dos dataframes, as colunas, os tipos de dados e a presença de valores ausentes.

## (1599, 12)
##        fixed acidity  volatile acidity  citric acid  residual sugar  \
## count    1599.000000       1599.000000  1599.000000     1599.000000   
## mean        8.319637          0.527821     0.270976        2.538806   
## std         1.741096          0.179060     0.194801        1.409928   
## min         4.600000          0.120000     0.000000        0.900000   
## 25%         7.100000          0.390000     0.090000        1.900000   
## 50%         7.900000          0.520000     0.260000        2.200000   
## 75%         9.200000          0.640000     0.420000        2.600000   
## max        15.900000          1.580000     1.000000       15.500000   
## 
##          chlorides  free sulfur dioxide  total sulfur dioxide      density  \
## count  1599.000000          1599.000000           1599.000000  1599.000000   
## mean      0.087467            15.874922             46.467792     0.996747   
## std       0.047065            10.460157             32.895324     0.001887   
## min       0.012000             1.000000              6.000000     0.990070   
## 25%       0.070000             7.000000             22.000000     0.995600   
## 50%       0.079000            14.000000             38.000000     0.996750   
## 75%       0.090000            21.000000             62.000000     0.997835   
## max       0.611000            72.000000            289.000000     1.003690   
## 
##                 pH    sulphates      alcohol      quality  
## count  1599.000000  1599.000000  1599.000000  1599.000000  
## mean      3.311113     0.658149    10.422983     5.636023  
## std       0.154386     0.169507     1.065668     0.807569  
## min       2.740000     0.330000     8.400000     3.000000  
## 25%       3.210000     0.550000     9.500000     5.000000  
## 50%       3.310000     0.620000    10.200000     6.000000  
## 75%       3.400000     0.730000    11.100000     6.000000  
## max       4.010000     2.000000    14.900000     8.000000
## fixed acidity           float64
## volatile acidity        float64
## citric acid             float64
## residual sugar          float64
## chlorides               float64
## free sulfur dioxide     float64
## total sulfur dioxide    float64
## density                 float64
## pH                      float64
## sulphates               float64
## alcohol                 float64
## quality                   int64
## dtype: object
## fixed acidity           0
## volatile acidity        0
## citric acid             0
## residual sugar          0
## chlorides               0
## free sulfur dioxide     0
## total sulfur dioxide    0
## density                 0
## pH                      0
## sulphates               0
## alcohol                 0
## quality                 0
## dtype: int64
## Moda por coluna:
##  fixed acidity            7.2000
## volatile acidity         0.6000
## citric acid              0.0000
## residual sugar           2.0000
## chlorides                0.0800
## free sulfur dioxide      6.0000
## total sulfur dioxide    28.0000
## density                  0.9972
## pH                       3.3000
## sulphates                0.6000
## alcohol                  9.5000
## quality                  5.0000
## Name: 0, dtype: float64
## (4898, 12)
##        fixed acidity  volatile acidity  citric acid  residual sugar  \
## count    4898.000000       4898.000000  4898.000000     4898.000000   
## mean        6.854788          0.278241     0.334192        6.391415   
## std         0.843868          0.100795     0.121020        5.072058   
## min         3.800000          0.080000     0.000000        0.600000   
## 25%         6.300000          0.210000     0.270000        1.700000   
## 50%         6.800000          0.260000     0.320000        5.200000   
## 75%         7.300000          0.320000     0.390000        9.900000   
## max        14.200000          1.100000     1.660000       65.800000   
## 
##          chlorides  free sulfur dioxide  total sulfur dioxide      density  \
## count  4898.000000          4898.000000           4898.000000  4898.000000   
## mean      0.045772            35.308085            138.360657     0.994027   
## std       0.021848            17.007137             42.498065     0.002991   
## min       0.009000             2.000000              9.000000     0.987110   
## 25%       0.036000            23.000000            108.000000     0.991723   
## 50%       0.043000            34.000000            134.000000     0.993740   
## 75%       0.050000            46.000000            167.000000     0.996100   
## max       0.346000           289.000000            440.000000     1.038980   
## 
##                 pH    sulphates      alcohol      quality  
## count  4898.000000  4898.000000  4898.000000  4898.000000  
## mean      3.188267     0.489847    10.514267     5.877909  
## std       0.151001     0.114126     1.230621     0.885639  
## min       2.720000     0.220000     8.000000     3.000000  
## 25%       3.090000     0.410000     9.500000     5.000000  
## 50%       3.180000     0.470000    10.400000     6.000000  
## 75%       3.280000     0.550000    11.400000     6.000000  
## max       3.820000     1.080000    14.200000     9.000000
## fixed acidity           float64
## volatile acidity        float64
## citric acid             float64
## residual sugar          float64
## chlorides               float64
## free sulfur dioxide     float64
## total sulfur dioxide    float64
## density                 float64
## pH                      float64
## sulphates               float64
## alcohol                 float64
## quality                   int64
## dtype: object
## fixed acidity           0
## volatile acidity        0
## citric acid             0
## residual sugar          0
## chlorides               0
## free sulfur dioxide     0
## total sulfur dioxide    0
## density                 0
## pH                      0
## sulphates               0
## alcohol                 0
## quality                 0
## dtype: int64
## Moda por coluna:
##  fixed acidity             6.800
## volatile acidity          0.280
## citric acid               0.300
## residual sugar            1.200
## chlorides                 0.044
## free sulfur dioxide      29.000
## total sulfur dioxide    111.000
## density                   0.992
## pH                        3.140
## sulphates                 0.500
## alcohol                   9.400
## quality                   6.000
## Name: 0, dtype: float64

Conclusão Análise Exploratória

A análise descritiva dos dados dos vinhos tintos (n = 1599) e vinhos brancos (n = 4898) revela diferenças significativas em suas composições químicas, o que influencia diretamente no perfil sensorial e na percepção de qualidade dos consumidores.

1. Álcool

  • Os vinhos brancos apresentam uma média alcoólica ligeiramente superior (10.51%) em comparação aos tintos (10.42%).
  • As modas são 9.4% para os brancos e 9.5% para os tintos, sugerindo concentração parecida nos valores mais frequentes.

2. Açúcar Residual

  • Os brancos contêm muito mais açúcar residual (média de 6.39 g/L) do que os tintos (2.54 g/L).
  • As modas reforçam essa diferença: 1.2 para os brancos e 2.0 para os tintos.

3. Densidade

  • A densidade média dos vinhos brancos (0.9940) é inferior à dos tintos (0.9967), o que pode ser reflexo da composição mais leve.
  • A moda da densidade segue esse padrão: 0.992 nos brancos e 0.9972 nos tintos.

4. Acidez

  • Os tintos apresentam maior acidez, tanto fixa (8.32 vs. 6.85) quanto volátil (0.53 vs. 0.28).
  • Isso pode contribuir para um perfil mais encorpado e intenso nos tintos.

5. Compostos de Enxofre

  • Os brancos utilizam bem mais dióxido de enxofre (livre e total), com média total de 138.36 mg/L contra 46.47 mg/L nos tintos.
  • Isso está ligado à preservação e estabilidade do vinho branco, que é mais sensível à oxidação.

6. Qualidade

  • A qualidade média dos vinhos brancos (5.88) é ligeiramente superior à dos tintos (5.64).
  • As modas de qualidade são 6 para brancos e 5 para tintos, refletindo preferências de avaliação mais elevadas para brancos.

Matrizes de Correlação

Criação de matrizes de correlação para os vinhos tintos e brancos. As matrizes de correlação ajudam a identificar relações entre as variáveis. Vamos usar a função corrplot para visualizar as correlações.

Análise das Matrizes de Correlação

As matrizes de correlação apresentadas permitem observar o grau de associação linear entre as variáveis químicas e a qualidade dos vinhos, tanto brancos quanto tintos. Os coeficientes de correlação variam de -1 (correlação negativa perfeita) a 1 (correlação positiva perfeita), sendo valores próximos de 0 indicativos de correlação fraca ou inexistente.

Vinho Branco

  • Álcool apresenta a maior correlação positiva com a variável quality (r = 0.44), sugerindo que vinhos brancos com maior teor alcoólico tendem a ser melhor avaliados.
  • A densidade tem uma correlação negativa (r = -0.31), o que é consistente com a ideia de que vinhos menos densos (ou seja, com mais álcool e menos açúcares residuais) podem ser de melhor qualidade.
  • Outras variáveis, como volatile acidity, residual sugar, e total sulfur dioxide, têm correlações fracas com a qualidade.
  • De maneira geral, a maioria das variáveis possui correlações fracas, indicando que a qualidade do vinho branco não é determinada por um único fator químico, mas por uma combinação sutil entre eles.

Vinho Tinto

  • Álcool também é o fator com maior correlação positiva com quality (r = 0.48), similar ao observado nos vinhos brancos.
  • A densidade e o pH têm correlações fracas com quality, sugerindo menor relevância direta na avaliação sensorial dos vinhos tintos.
  • Ácido volátil (volatile acidity) apresenta correlação negativa com quality (r = -0.39), indicando que níveis mais altos de acidez volátil estão associados a vinhos de menor qualidade — possivelmente devido a aromas desagradáveis que podem surgir.
  • Sulphates possui uma correlação positiva moderada (r = 0.25), o que pode indicar um leve impacto positivo na preservação e no sabor final do vinho.

Comparativo Geral

  • Em ambos os tipos de vinho, o teor alcoólico é o atributo químico mais diretamente associado à qualidade percebida.
  • A acidez volátil parece impactar negativamente os vinhos tintos de maneira mais significativa do que os vinhos brancos.
  • Os vinhos tintos tendem a apresentar correlações um pouco mais expressivas em comparação aos brancos, o que pode indicar um perfil químico mais influente na definição da qualidade sensorial.

Essas observações servem como base para investigações mais detalhadas com modelos preditivos ou regressões multivariadas, a fim de entender melhor os fatores determinantes da qualidade em diferentes tipos de vinho.

Tratamento de Outliers

Nesta etapa, vamos tratar os outliers dos dataframes de vinhos tintos e brancos. Vamos usar o método do z-score para identificar e remover os outliers.

from scipy import stats

def remove_outliers_zscore(df, threshold=3):
    df_numeric = df.select_dtypes(include=['float64', 'int64'])
    z_scores = stats.zscore(df_numeric)
    return df[(abs(z_scores) < threshold).all(axis=1)]

wine_red_clean = remove_outliers_zscore(wine_red)
wine_white_clean = remove_outliers_zscore(wine_white)

Visualização dos Dados

Vamos criar gráficos de dispersão para visualizar a relação entre o teor alcoólico e da densidade em relação à qualidade..
Os gráficos de dispersão ajudam a identificar padrões e tendências nos dados.

Além disso, vamos criar boxplots para analisar a distribuição do teor alcoólico e da densidade em relação à qualidade..
Os gráficos de boxplot ajudam a identificar outliers e a distribuição dos dados.

Análise dos Gráficos de Dispersão

Dispersão entre Teor Alcoólico e Qualidade

A partir dos gráficos de dispersão entre o teor alcoólico e a qualidade dos vinhos, é possível observar uma tendência clara tanto nos vinhos brancos quanto nos vinhos tintos:

  • Vinhos Brancos: Existe uma correlação positiva entre o teor alcoólico e a qualidade. À medida que o teor alcoólico aumenta, observa-se uma concentração maior de vinhos com qualidade mais alta (principalmente notas 6, 7 e 8). Vinhos com baixos teores de álcool tendem a ter qualidade menor, com predominância de notas entre 4 e 6.

  • Vinhos Tintos: A tendência se repete, embora de forma um pouco mais dispersa. Vinhos tintos com teor alcoólico mais elevado (acima de 11%) tendem a apresentar qualidade mais alta. A concentração de vinhos com notas 7 e 8 é mais evidente nesse intervalo, enquanto notas mais baixas estão associadas a teores alcoólicos menores.

Essa análise sugere que o teor alcoólico é um fator importante para a percepção de qualidade do vinho em ambos os tipos.

Dispersão entre Densidade e Qualidade

Nos gráficos que comparam densidade e qualidade dos vinhos, a relação identificada é oposta à observada com o álcool:

  • Vinhos Brancos: Existe uma leve tendência inversa, ou seja, vinhos de maior qualidade (notas 7 e 8) geralmente estão associados a densidades mais baixas. Já vinhos com densidade mais alta tendem a estar associados a notas entre 4 e 6.

  • Vinhos Tintos: A distribuição é semelhante à dos vinhos brancos. Qualidades mais altas são mais comuns em vinhos com densidade entre 0.994 e 0.996, enquanto densidades mais altas concentram vinhos de qualidade inferior.

Essa relação negativa sugere que a densidade pode estar relacionada à composição do vinho de maneira que influencie negativamente a sua avaliação sensorial quando muito elevada.

Conclusão Geral dos Gráficos de Dispersão

Os gráficos de dispersão confirmam uma relação direta entre teor alcoólico e qualidade, e uma relação inversa entre densidade e qualidade, tanto para vinhos brancos quanto para vinhos tintos. Essas variáveis podem ser consideradas como bons preditores de qualidade em modelos de classificação ou regressão voltados à análise de vinhos.

Teor Alcoólico vs. Qualidade (Vinho Branco e Vinho Tinto)

Os gráficos de boxplot que relacionam o teor alcoólico à qualidade dos vinhos revelam uma correlação positiva:

  • No caso dos vinhos brancos, há um aumento claro no teor alcoólico médio à medida que a qualidade atribuída também aumenta. Os vinhos com nota 8 apresentam os maiores teores alcoólicos.
  • Nos vinhos tintos, observa-se o mesmo padrão: vinhos mais bem avaliados apresentam, em média, maior concentração alcoólica.

Portanto, tanto em vinhos brancos quanto tintos, o teor alcoólico tende a ser maior em rótulos de melhor qualidade. Isso pode ser explicado pelo fato de que o álcool contribui para a percepção de corpo, equilíbrio e complexidade da bebida, características valorizadas na análise sensorial de vinhos.

Densidade vs. Qualidade (Vinho Branco e Vinho Tinto)

Nos gráficos de boxplot que relacionam a densidade com a qualidade dos vinhos brancos e tintos, é possível observar uma tendência inversa entre essas duas variáveis:

  • Para os vinhos brancos, a mediana da densidade tende a diminuir conforme a qualidade aumenta. Vinhos com notas mais altas (7 e 8) apresentam densidades mais baixas, sugerindo que amostras com menor densidade são, em geral, melhor avaliadas.
  • Uma tendência semelhante é observada nos vinhos tintos, nos quais a densidade média também diminui entre os vinhos de maior qualidade.

Essa observação indica que vinhos de menor densidade — possivelmente associados a menor teor de açúcar residual ou maior concentração alcoólica — são, em geral, percebidos como de melhor qualidade, tanto para vinhos brancos quanto tintos.

O Pairplot

Exibe combinações entre quatro variáveis do dataset de vinhos brancos:

  • alcohol (teor alcoólico)
  • density (densidade)
  • residual sugar (açúcar residual)
  • fixed acidity (acidez fixa)

Cada ponto representa um vinho, e as cores indicam a qualidade do vinho, conforme a legenda.

Como interpretar os gráficos

  • Diagonal principal: contém gráficos de densidade estatística, que mostram a distribuição de cada variável individualmente.
    (Atenção: aqui o termo “densidade” não se refere à variável density, mas sim à forma como os dados estão distribuídos estatisticamente.)

  • Fora da diagonal: são gráficos de dispersão (scatter plots) que mostram as relações entre pares de variáveis.
    Exemplo: o gráfico entre alcohol e density revela uma relação inversa — vinhos com mais álcool tendem a apresentar menor densidade.

O que podemos observar?

  • Relação inversa entre alcohol e density.
  • Vinhos com densidade mais baixa tendem a ter qualidade mais alta (representados por cores mais claras ou intensas, dependendo do padrão da legenda).
  • Relação positiva entre residual sugar e density.
  • Vinhos com mais álcool frequentemente são os que têm melhor avaliação de qualidade.

Distribuição de Qualidade

Vamos criar gráficos de barras para visualizar a distribuição de qualidade dos vinhos tintos e brancos. Os gráficos mostram a quantidade de vinhos em cada nível de qualidade.

## (array([0, 1, 2, 3, 4]), [Text(0, 0, '4'), Text(1, 0, '5'), Text(2, 0, '6'), Text(3, 0, '7'), Text(4, 0, '8')])

Reclassificação da Variável-Alvo

Vamos reclassificar a variável de qualidade dos vinhos tintos e brancos para transformar o problema em uma classificação binária.
Atualizaremos a coluna quality para uma variável categórica com dois níveis:

Essa transformação facilita o uso de modelos de classificação e torna o problema mais interpretável.

wine_white_mutate <- wine_white_clean %>% 
  mutate(quality = as.factor(ifelse(quality <= 5, "Desagradável", "Agradável")))

wine_red_mutate <- wine_red_clean %>% 
  mutate(quality = as.factor(ifelse(quality <= 5, "Desagradável", "Agradável")))

py$wine_red_mutate <- wine_red_mutate
py$wine_white_mutate <- wine_white_mutate

Distribuição de Qualidade em Categorias

Vamos criar gráficos de barras empilhadas para visualizar a distribuição de qualidade nas categorias dos vinhos tintos e brancos. Os gráficos mostram a quantidade de vinhos em cada categoria de qualidade.

## (array([0, 1]), [Text(0, 0, 'Agradável'), Text(1, 0, 'Desagradável')])

Modelagem Preditiva

Parte 1: Preparação dos Dados

Define uma semente aleatória para que os resultados possam ser reproduzidos sempre que rodarmos o código. É como garantir que o “embaralhamento” dos dados seja sempre o mesmo.

Divide o conjunto de dados em duas partes: 80% para treinar o modelo, 20% para testar. A função strata = quality garante que as proporções das classes de qualidade sejam mantidas nos dois grupos (balanceamento).

Separa os dados da divisão acima em: treinamento: dados usados para criar e ajustar os modelos; teste: dados reservados para avaliar os modelos ao final.

set.seed(123)

split_red <- initial_split(data = wine_red_mutate, prop = 0.8, strata = quality)
split_white <- initial_split(data = wine_white_mutate, prop = 0.8, strata = quality)

treinamento_red <- training(split_red)
treinamento_white <- training(split_white)
test_red <- testing(split_red)
test_white <- testing(split_white)

preprocess_red <- recipe(quality ~ ., data = treinamento_red) %>%
  step_zv(all_predictors())

preprocess_white <- recipe(quality ~ ., data = treinamento_white) %>%
  step_zv(all_predictors())

Parte 2: Definindo os Modelos

Cria um modelo de regressão logística, que é um modelo simples e muito usado para classificações. Aqui ele usa o motor “glm” (modelo linear generalizado do R).

Cria um modelo de random forest, que combina várias árvores de decisão para prever melhor. Ele usa o motor “ranger”, uma implementação rápida em C++.

regressao_logistica <- logistic_reg() %>% 
  set_engine("glm")

random_forest <- rand_forest() %>% 
  set_engine("ranger") %>% 
  set_mode("classification")

Parte 3: Criando os Workflows (Fluxo de Trabalho)

Aqui você cria dois workflows (um para cada modelo), que unem: A receita de pré-processamento (preprocess) O modelo a ser usado (regressão ou random forest)

Isso deixa o processo organizado e modular.

wf_reg_log <- workflow() %>%
  add_recipe(preprocess_red) %>%
  add_model(regressao_logistica)

wf_reg_log <- workflow() %>%
  add_recipe(preprocess_white) %>%
  add_model(regressao_logistica)

wf_ran_for <- workflow() %>%
  add_recipe(preprocess_red) %>%
  add_model(random_forest)

wf_ran_for <- workflow() %>%
  add_recipe(preprocess_white) %>%
  add_model(random_forest)

Parte 4: Validação Cruzada

Divide os dados de treinamento em 5 partes (validação cruzada) para testar os modelos várias vezes em pedaços diferentes dos dados, evitando que o modelo fique “viciado”.

Apenas mostra as divisões feitas. (opcional, mais para inspeção). (folds$splits)

folds_red <- vfold_cv(treinamento_red, v = 5, strata = quality)
folds_white <- vfold_cv(treinamento_white, v = 5, strata = quality)

folds_red$splits
## [[1]]
## <Analysis/Assess/Total>
## <927/233/1160>
## 
## [[2]]
## <Analysis/Assess/Total>
## <928/232/1160>
## 
## [[3]]
## <Analysis/Assess/Total>
## <928/232/1160>
## 
## [[4]]
## <Analysis/Assess/Total>
## <928/232/1160>
## 
## [[5]]
## <Analysis/Assess/Total>
## <929/231/1160>
folds_white$splits
## [[1]]
## <Analysis/Assess/Total>
## <2870/719/3589>
## 
## [[2]]
## <Analysis/Assess/Total>
## <2871/718/3589>
## 
## [[3]]
## <Analysis/Assess/Total>
## <2871/718/3589>
## 
## [[4]]
## <Analysis/Assess/Total>
## <2872/717/3589>
## 
## [[5]]
## <Analysis/Assess/Total>
## <2872/717/3589>

Parte 5: Treinando e Avaliando com Validação Cruzada

Ajusta o modelo de regressão logística usando a validação cruzada, e mede a acurácia (proporção de acertos).

fit_reg_log_red <- fit_resamples(
  object = wf_reg_log,
  resamples = folds_red,
  metrics = metric_set(accuracy)
)

fit_reg_log_white <- fit_resamples(
  object = wf_reg_log,
  resamples = folds_white,
  metrics = metric_set(accuracy)
)
## # A tibble: 2 × 7
##   .metric  .estimator  mean     n std_err .config              tipo_vinho
##   <chr>    <chr>      <dbl> <int>   <dbl> <chr>                <chr>     
## 1 accuracy binary     0.741     5 0.0124  Preprocessor1_Model1 tinto     
## 2 accuracy binary     0.740     5 0.00657 Preprocessor1_Model1 branco

Faz a mesma coisa acima, mas agora com o random forest.

fit_ran_for_red <- fit_resamples(
  object = wf_ran_for,
  resamples = folds_red,
  metrics = metric_set(accuracy)
)

fit_ran_for_white <- fit_resamples(
  object = wf_ran_for,
  resamples = folds_white,
  metrics = metric_set(accuracy)
)
## # A tibble: 2 × 7
##   .metric  .estimator  mean     n std_err .config              tipo_vinho
##   <chr>    <chr>      <dbl> <int>   <dbl> <chr>                <chr>     
## 1 accuracy binary     0.799     5 0.0202  Preprocessor1_Model1 tinto     
## 2 accuracy binary     0.833     5 0.00730 Preprocessor1_Model1 branco

Parte 6: Treinamento Final e Avaliação no Teste

Treina o modelo de regressão logística em todo o conjunto de treinamento, e avalia no conjunto de teste. Mostra a acurácia final.

fit_final_reg_red <- last_fit(
  object = wf_reg_log,
  split = split_red,
  metrics = metric_set(accuracy)
)

fit_final_reg_white <- last_fit(
  object = wf_reg_log,
  split = split_white,
  metrics = metric_set(accuracy)
)
## # A tibble: 2 × 5
##   .metric  .estimator .estimate .config              tipo_vinho
##   <chr>    <chr>          <dbl> <chr>                <chr>     
## 1 accuracy binary         0.735 Preprocessor1_Model1 tinto     
## 2 accuracy binary         0.756 Preprocessor1_Model1 branco

Mesma coisa acima, mas com o random forest.

fit_final_ran_red <- last_fit(
  object = wf_ran_for,
  split = split_red,
  metrics = metric_set(accuracy)
)

fit_final_ran_white <- last_fit(
  object = wf_ran_for,
  split = split_white,
  metrics = metric_set(accuracy)
)
## # A tibble: 2 × 5
##   .metric  .estimator .estimate .config              tipo_vinho
##   <chr>    <chr>          <dbl> <chr>                <chr>     
## 1 accuracy binary         0.828 Preprocessor1_Model1 tinto     
## 2 accuracy binary         0.856 Preprocessor1_Model1 branco

Parte 7: Matriz de Confusão

Gera uma matriz de confusão para ver quantos vinhos de cada qualidade foram classificados corretamente ou incorretamente. O autoplot(…, type = “heatmap”) mostra isso em forma de gráfico.

cm_red_reg <- conf_mat(
  data = fit_final_reg_red$.predictions[[1]],
  truth = quality,
  estimate = .pred_class
)

cm_white_reg <- conf_mat(
  data = fit_final_reg_white$.predictions[[1]],
  truth = quality,
  estimate = .pred_class
)

autoplot(cm_red_reg, type = "heatmap") +
  ggtitle("Matriz de Confusão (Regressão Linear) - Vinho Tinto")

autoplot(cm_white_reg, type = "heatmap") +
  ggtitle("Matriz de Confusão (Regressão Linear) - Vinho Branco")

cm_red_ran <- conf_mat(
  data = fit_final_ran_red$.predictions[[1]],
  truth = quality,
  estimate = .pred_class
)

cm_white_ran <- conf_mat(
  data = fit_final_ran_white$.predictions[[1]],
  truth = quality,
  estimate = .pred_class
)

autoplot(cm_red_ran, type = "heatmap") +
  ggtitle("Matriz de Confusão (Random Forest) - Vinho Tinto")

autoplot(cm_white_ran, type = "heatmap") +
  ggtitle("Matriz de Confusão (Random Forest) - Vinho Branco")

Conclusão

Diferença entre validação cruzada e avaliação final

Validação cruzada (fit_resamples)
O modelo é treinado e testado várias vezes usando apenas os dados de treinamento.
Em cada “fold”, o modelo é treinado em cerca de 80% dos dados de treino e testado nos 20% restantes.
Os resultados (como acurácia média) são uma estimativa do desempenho, mas tendem a ser um pouco otimistas, pois:
São baseados em médias de várias execuções.
O teste é feito em dados que fazem parte do mesmo conjunto de treino, só que divididos.

Treinamento final (last_fit)

O modelo é treinado com todo o conjunto de treinamento.
A avaliação é feita em um conjunto de teste separado, que nunca foi visto pelo modelo.
Essa é uma avaliação real do desempenho do modelo em novos dados, mais próxima da prática.

Por que a acurácia pode cair no last_fit?

Overfitting leve na regressão logística
Mesmo sendo um modelo simples, a regressão logística pode se ajustar demais aos dados de treino durante a validação cruzada.
Quando o modelo é testado com dados completamente novos, o desempenho real aparece — e costuma ser um pouco mais baixo.

Variação natural nos dados de teste

O conjunto de teste pode conter observações mais difíceis de classificar ou uma leve variação nas proporções das classes, mesmo com o uso do argumento strata = quality. Isso afeta especialmente a regressão logística, que é mais sensível à estrutura linear dos dados.

Comparação com o Random Forest

O Random Forest é mais robusto a ruídos, desequilíbrios e variações nos dados, por isso a acurácia costuma se manter estável ou até melhorar no last_fit.
A regressão logística, por fazer suposições mais rígidas sobre os dados, pode não capturar bem padrões mais complexos presentes no conjunto de teste.

Como interpretar isso?

Essa queda de desempenho indica que:
A regressão logística pode não ser o modelo mais adequado para esse problema específico.
A validação cruzada forneceu uma estimativa teórica de desempenho, enquanto o last_fit mostrou a performance prática.
Esse comportamento é esperado e fornece um aprendizado importante sobre a generalização dos modelos.

Considerações Finais

As diferenças entre os dois tipos de vinho são expressivas e influenciam diretamente na experiência sensorial. Isso também aponta para a importância de tratar modelos preditivos de qualidade de maneira separada para vinhos brancos e tintos, dada a natureza distinta de suas variáveis.

As informações levantadas neste relatório podem embasar não só análises estatísticas mais profundas, como também auxiliar enólogos, sommeliers e cientistas de dados na otimização dos processos de produção e avaliação de qualidade.

Referências e Agradecimentos

Gostaria de expressar minha sincera gratidão ao Prof. MSc. Weslley Rodrigues pelo apoio e dedicação ao longo deste projeto.
Sua orientação foi fundamental para que eu pudesse compreender e aplicar com confiança as ferramentas analíticas utilizadas neste trabalho.

Agradeço não apenas pelo conhecimento compartilhado, mas também pela paciência e incentivo contínuo ao aprendizado.
Dedico este estudo ao senhor como forma de reconhecimento por sua valiosa contribuição na minha formação. Muito obrigado!

Linkedin

Pedro Muniz Cherulli