Análisis Exploratorio de las Caracteristicas del Vino

A continuación, se presenta un análisis exploratorio para evaluar el comportamiento de cada una de las variables organolépticas y físico-químicas que compone el vino, las cuales inciden de manera directa en su calidad final

##Importamos la base de datos en la variable BD
BD <- read.csv("C:/Users/KEVIN/OneDrive/Desktop/KEVIN/CURSOS/PUCP/Diplomado de Busines Analytics/Ciclo 1/Martes - Analytics and Data Science for Business/Clase 4/winequality-red.csv")

#Vemos la estructura de la base de datos:Se observa que los tados son numericos y la variable calidad es entero.
str(BD)
## 'data.frame':    1599 obs. of  12 variables:
##  $ fixed.acidity       : num  7.4 7.8 7.8 11.2 7.4 7.4 7.9 7.3 7.8 7.5 ...
##  $ volatile.acidity    : num  0.7 0.88 0.76 0.28 0.7 0.66 0.6 0.65 0.58 0.5 ...
##  $ citric.acid         : num  0 0 0.04 0.56 0 0 0.06 0 0.02 0.36 ...
##  $ residual.sugar      : num  1.9 2.6 2.3 1.9 1.9 1.8 1.6 1.2 2 6.1 ...
##  $ chlorides           : num  0.076 0.098 0.092 0.075 0.076 0.075 0.069 0.065 0.073 0.071 ...
##  $ free.sulfur.dioxide : num  11 25 15 17 11 13 15 15 9 17 ...
##  $ total.sulfur.dioxide: num  34 67 54 60 34 40 59 21 18 102 ...
##  $ density             : num  0.998 0.997 0.997 0.998 0.998 ...
##  $ pH                  : num  3.51 3.2 3.26 3.16 3.51 3.51 3.3 3.39 3.36 3.35 ...
##  $ sulphates           : num  0.56 0.68 0.65 0.58 0.56 0.56 0.46 0.47 0.57 0.8 ...
##  $ alcohol             : num  9.4 9.8 9.8 9.8 9.4 9.4 9.4 10 9.5 10.5 ...
##  $ quality             : int  5 5 5 6 5 5 5 7 7 5 ...
#Posteriormente analizaremos cada uno de los atributos
summary(BD)
##  fixed.acidity   volatile.acidity  citric.acid    residual.sugar  
##  Min.   : 4.60   Min.   :0.1200   Min.   :0.000   Min.   : 0.900  
##  1st Qu.: 7.10   1st Qu.:0.3900   1st Qu.:0.090   1st Qu.: 1.900  
##  Median : 7.90   Median :0.5200   Median :0.260   Median : 2.200  
##  Mean   : 8.32   Mean   :0.5278   Mean   :0.271   Mean   : 2.539  
##  3rd Qu.: 9.20   3rd Qu.:0.6400   3rd Qu.:0.420   3rd Qu.: 2.600  
##  Max.   :15.90   Max.   :1.5800   Max.   :1.000   Max.   :15.500  
##    chlorides       free.sulfur.dioxide total.sulfur.dioxide    density      
##  Min.   :0.01200   Min.   : 1.00       Min.   :  6.00       Min.   :0.9901  
##  1st Qu.:0.07000   1st Qu.: 7.00       1st Qu.: 22.00       1st Qu.:0.9956  
##  Median :0.07900   Median :14.00       Median : 38.00       Median :0.9968  
##  Mean   :0.08747   Mean   :15.87       Mean   : 46.47       Mean   :0.9967  
##  3rd Qu.:0.09000   3rd Qu.:21.00       3rd Qu.: 62.00       3rd Qu.:0.9978  
##  Max.   :0.61100   Max.   :72.00       Max.   :289.00       Max.   :1.0037  
##        pH          sulphates         alcohol         quality     
##  Min.   :2.740   Min.   :0.3300   Min.   : 8.40   Min.   :3.000  
##  1st Qu.:3.210   1st Qu.:0.5500   1st Qu.: 9.50   1st Qu.:5.000  
##  Median :3.310   Median :0.6200   Median :10.20   Median :6.000  
##  Mean   :3.311   Mean   :0.6581   Mean   :10.42   Mean   :5.636  
##  3rd Qu.:3.400   3rd Qu.:0.7300   3rd Qu.:11.10   3rd Qu.:6.000  
##  Max.   :4.010   Max.   :2.0000   Max.   :14.90   Max.   :8.000

Análisis visual del comportamiento de cada atributo

Se uso el FOR como bucle operativo para leer cada columna -atributo de la base datos y poder asi automatizar su lectura y graficas, se realizo graficas de histogramas y boxplot.

BDN <- NULL
BDC <- NULL

columnas <- dim(BD)[2]
par(mfrow = c(2,columnas/2))

for (i in 1:columnas) {
  if(is.numeric(BD[ ,i])== TRUE)
  {
    texto = paste("   ",colnames(BD)[i])
    hist(BD[ ,i],
         main=texto,
         xlab = colnames(BD)[i],
         col=i)
    boxplot(BD[[i]], 
            horizontal = TRUE, 
            col = i, 
            xlab = colnames(BD)[i])
    BDN <- c(BDN,i)
  }else {
    texto = paste("   ",colnames(BD)[i])
    pie(table(BD[ ,i]),
        main=texto)
    BDC <- c(BDC,i)
  }
}

Creación de funciones para analizar variables numéricas

analizar_variable <- function(x, nombre_var) {
Q1  <- quantile(x, 0.25, na.rm = TRUE)
  Q3  <- quantile(x, 0.75, na.rm = TRUE)
  RIC <- Q3 - Q1
LI <- Q1 - 1.5 * RIC   # Límite de Control Inferior
  LS <- Q3 + 1.5 * RIC   # Límite de Control Superior
outliers   <- x[x < LI | x > LS]
  n_outliers <- length(outliers)
  if (n_outliers > 0) {
    cat("Valores de los outliers:\n")
    print(round(sort(outliers), 2))
  }
  cat("========================================\n\n")
par(mfrow = c(1, 2))
  
  boxplot(x,
          horizontal = TRUE,
          col = "lightblue",
          main = paste("Boxplot -", nombre_var),
          xlab = nombre_var)
  abline(v = LI, col = "red", lty = 2, lwd = 2)  # línea límite inferior
  abline(v = LS, col = "red", lty = 2, lwd = 2)  # línea límite superior
hist(x,
       col = "lightblue",
       main = paste("Histograma -", nombre_var),
       xlab = nombre_var)
  abline(v = LI, col = "red", lty = 2, lwd = 2)
  abline(v = LS, col = "red", lty = 2, lwd = 2)
  par(mfrow = c(1, 1))
  
  resultado <- list(
    variable          = nombre_var,
    Q1                = Q1,
    Q3                = Q3,
    RIC               = RIC,
    LI               = LI,
    LS               = LS,
    n_outliers        = n_outliers,
    valores_outliers  = outliers
  )
  
  return(invisible(resultado))
}

Creación de funciones para generar comentarios para cada grafico generado con la funcion analizar_variable

generar_comentario <- function(resultado, media, mediana) {
  
  sesgo <- ifelse(media > mediana, "sesgo positivo (hacia la derecha)",
            ifelse(media < mediana, "sesgo negativo (hacia la izquierda)",
                   "distribución aproximadamente simétrica"))
  
  cat("### Análisis del atributo `", resultado$variable, "`\n\n", sep = "")
  cat("La variable presenta una ", sesgo, 
      ", con una media de ", round(media, 2), 
      " y una mediana de ", round(mediana, 2), ".\n\n", sep = "")
  cat("Según los límites de control (LI = ", round(resultado$LI, 2),
      ", LS = ", round(resultado$LS, 2), 
      "), se identificaron **", resultado$n_outliers, " outliers**.\n\n", sep = "")

}

Creación de funciones para generar comentarios para cada grafico generado con la funcion analizar_variable

resultados_lista <- list()  # aquí guardamos el resultado de cada variable

for (i in 1:columnas) {
  if (is.numeric(BD[, i]) == TRUE) {
    nombre_col <- colnames(BD)[i]
    
    # Analiza la variable y guarda el resultado
    resultados_lista[[nombre_col]] <- analizar_variable(BD[, i], nombre_col)
    
    # Calcula media y mediana de esta variable
    media_var   <- mean(BD[, i], na.rm = TRUE)
    mediana_var <- median(BD[, i], na.rm = TRUE)
    
    # Genera el comentario para esta variable
    generar_comentario(resultados_lista[[nombre_col]], media_var, mediana_var)
  }
}
## Valores de los outliers:
##  [1] 12.4 12.4 12.4 12.4 12.5 12.5 12.5 12.5 12.5 12.5 12.5 12.6 12.6 12.6 12.6
## [16] 12.7 12.7 12.7 12.7 12.8 12.8 12.8 12.8 12.8 12.9 12.9 13.0 13.0 13.0 13.2
## [31] 13.2 13.2 13.3 13.3 13.3 13.4 13.5 13.7 13.7 13.8 14.0 14.3 15.0 15.0 15.5
## [46] 15.5 15.6 15.6 15.9
## ========================================

## ### Análisis del atributo `fixed.acidity`
## 
## La variable presenta una sesgo positivo (hacia la derecha), con una media de 8.32 y una mediana de 7.9.
## 
## Según los límites de control (LI = 3.95, LS = 12.35), se identificaron **49 outliers**.
## 
## Valores de los outliers:
##  [1] 1.02 1.02 1.02 1.02 1.02 1.03 1.04 1.04 1.04 1.07 1.09 1.11 1.13 1.18 1.19
## [16] 1.24 1.33 1.33 1.58
## ========================================

## ### Análisis del atributo `volatile.acidity`
## 
## La variable presenta una sesgo positivo (hacia la derecha), con una media de 0.53 y una mediana de 0.52.
## 
## Según los límites de control (LI = 0.02, LS = 1.02), se identificaron **19 outliers**.
## 
## Valores de los outliers:
## [1] 1
## ========================================

## ### Análisis del atributo `citric.acid`
## 
## La variable presenta una sesgo positivo (hacia la derecha), con una media de 0.27 y una mediana de 0.26.
## 
## Según los límites de control (LI = -0.4, LS = 0.91), se identificaron **1 outliers**.
## 
## Valores de los outliers:
##   [1]  3.70  3.70  3.70  3.70  3.75  3.80  3.80  3.80  3.80  3.80  3.80  3.80
##  [13]  3.80  3.90  3.90  3.90  3.90  3.90  3.90  4.00  4.00  4.00  4.00  4.00
##  [25]  4.00  4.00  4.00  4.00  4.00  4.00  4.10  4.10  4.10  4.10  4.10  4.10
##  [37]  4.20  4.20  4.20  4.20  4.20  4.25  4.30  4.30  4.30  4.30  4.30  4.30
##  [49]  4.30  4.30  4.40  4.40  4.40  4.40  4.50  4.50  4.50  4.50  4.60  4.60
##  [61]  4.60  4.60  4.60  4.60  4.65  4.65  4.70  4.80  4.80  4.80  5.00  5.10
##  [73]  5.10  5.10  5.10  5.10  5.15  5.20  5.20  5.20  5.40  5.50  5.50  5.50
##  [85]  5.50  5.50  5.50  5.50  5.50  5.60  5.60  5.60  5.60  5.60  5.60  5.70
##  [97]  5.80  5.80  5.80  5.80  5.90  5.90  5.90  6.00  6.00  6.00  6.00  6.10
## [109]  6.10  6.10  6.10  6.20  6.20  6.20  6.30  6.30  6.40  6.40  6.40  6.55
## [121]  6.55  6.60  6.60  6.70  6.70  7.00  7.20  7.30  7.50  7.80  7.80  7.90
## [133]  7.90  7.90  8.10  8.10  8.30  8.30  8.30  8.60  8.80  8.80  8.90  9.00
## [145] 10.70 11.00 11.00 12.90 13.40 13.80 13.80 13.90 15.40 15.40 15.50
## ========================================

## ### Análisis del atributo `residual.sugar`
## 
## La variable presenta una sesgo positivo (hacia la derecha), con una media de 2.54 y una mediana de 2.2.
## 
## Según los límites de control (LI = 0.85, LS = 3.65), se identificaron **155 outliers**.
## 
## Valores de los outliers:
##   [1] 0.01 0.01 0.03 0.04 0.04 0.04 0.04 0.04 0.04 0.12 0.12 0.12 0.12 0.12 0.12
##  [16] 0.12 0.12 0.12 0.12 0.12 0.12 0.12 0.12 0.12 0.12 0.12 0.12 0.12 0.12 0.12
##  [31] 0.12 0.13 0.13 0.13 0.13 0.13 0.13 0.13 0.14 0.14 0.14 0.14 0.15 0.15 0.15
##  [46] 0.15 0.15 0.15 0.16 0.16 0.16 0.16 0.16 0.16 0.17 0.17 0.17 0.17 0.17 0.17
##  [61] 0.17 0.17 0.17 0.17 0.18 0.18 0.18 0.19 0.19 0.19 0.20 0.20 0.20 0.21 0.21
##  [76] 0.21 0.21 0.22 0.22 0.23 0.23 0.23 0.23 0.24 0.24 0.24 0.25 0.26 0.27 0.27
##  [91] 0.33 0.34 0.34 0.34 0.36 0.36 0.37 0.37 0.39 0.40 0.40 0.41 0.41 0.41 0.42
## [106] 0.42 0.42 0.42 0.46 0.47 0.61 0.61
## ========================================

## ### Análisis del atributo `chlorides`
## 
## La variable presenta una sesgo positivo (hacia la derecha), con una media de 0.09 y una mediana de 0.08.
## 
## Según los límites de control (LI = 0.04, LS = 0.12), se identificaron **112 outliers**.
## 
## Valores de los outliers:
##  [1] 43 43 43 45 45 45 46 47 48 48 48 48 50 50 51 51 51 51 52 52 52 53 54 55 55
## [26] 57 66 68 68 72
## ========================================

## ### Análisis del atributo `free.sulfur.dioxide`
## 
## La variable presenta una sesgo positivo (hacia la derecha), con una media de 15.87 y una mediana de 14.
## 
## Según los límites de control (LI = -14, LS = 42), se identificaron **30 outliers**.
## 
## Valores de los outliers:
##  [1] 124 124 124 125 125 126 127 127 128 128 129 129 129 130 131 131 131 133 133
## [20] 133 134 134 135 135 136 136 139 140 141 141 141 142 143 143 144 144 144 145
## [39] 145 145 147 147 147 148 148 149 151 151 152 153 155 160 165 278 289
## ========================================

## ### Análisis del atributo `total.sulfur.dioxide`
## 
## La variable presenta una sesgo positivo (hacia la derecha), con una media de 46.47 y una mediana de 38.
## 
## Según los límites de control (LI = -38, LS = 122), se identificaron **55 outliers**.
## 
## Valores de los outliers:
##  [1] 0.99 0.99 0.99 0.99 0.99 0.99 0.99 0.99 0.99 0.99 0.99 0.99 0.99 0.99 0.99
## [16] 0.99 0.99 0.99 0.99 0.99 0.99 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00
## [31] 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00
## ========================================

## ### Análisis del atributo `density`
## 
## La variable presenta una sesgo negativo (hacia la izquierda), con una media de 1 y una mediana de 1.
## 
## Según los límites de control (LI = 0.99, LS = 1), se identificaron **45 outliers**.
## 
## Valores de los outliers:
##  [1] 2.74 2.86 2.87 2.88 2.88 2.89 2.89 2.89 2.89 2.90 2.92 2.92 2.92 2.92 3.69
## [16] 3.69 3.69 3.69 3.70 3.71 3.71 3.71 3.71 3.72 3.72 3.72 3.74 3.75 3.78 3.78
## [31] 3.85 3.90 3.90 4.01 4.01
## ========================================

## ### Análisis del atributo `pH`
## 
## La variable presenta una sesgo positivo (hacia la derecha), con una media de 3.31 y una mediana de 3.31.
## 
## Según los límites de control (LI = 2.92, LS = 3.68), se identificaron **35 outliers**.
## 
## Valores de los outliers:
##  [1] 1.00 1.01 1.02 1.02 1.02 1.03 1.03 1.04 1.04 1.05 1.05 1.05 1.06 1.06 1.06
## [16] 1.06 1.07 1.07 1.08 1.08 1.08 1.09 1.10 1.10 1.11 1.12 1.13 1.13 1.14 1.14
## [31] 1.15 1.16 1.17 1.17 1.17 1.17 1.17 1.18 1.18 1.18 1.20 1.22 1.26 1.28 1.28
## [46] 1.31 1.33 1.34 1.36 1.36 1.36 1.56 1.59 1.61 1.62 1.95 1.95 1.98 2.00
## ========================================

## ### Análisis del atributo `sulphates`
## 
## La variable presenta una sesgo positivo (hacia la derecha), con una media de 0.66 y una mediana de 0.62.
## 
## Según los límites de control (LI = 0.28, LS = 1), se identificaron **59 outliers**.
## 
## Valores de los outliers:
##  [1] 13.57 13.60 13.60 13.60 13.60 14.00 14.00 14.00 14.00 14.00 14.00 14.00
## [13] 14.90
## ========================================

## ### Análisis del atributo `alcohol`
## 
## La variable presenta una sesgo positivo (hacia la derecha), con una media de 10.42 y una mediana de 10.2.
## 
## Según los límites de control (LI = 7.1, LS = 13.5), se identificaron **13 outliers**.
## 
## Valores de los outliers:
##  [1] 3 3 3 3 3 3 3 3 3 3 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
## ========================================

## ### Análisis del atributo `quality`
## 
## La variable presenta una sesgo negativo (hacia la izquierda), con una media de 5.64 y una mediana de 6.
## 
## Según los límites de control (LI = 3.5, LS = 7.5), se identificaron **28 outliers**.