Calidad de vino tinto y vino blanco

 Erika Blanca Salazar García

Modelo de clasificación de la calidad de vino tinto y vino blanco del norte de Portugal.

Introducción

En este trabajo utilizaremos diferentes algoritmos supervisados, eligiendo el mejor de ellos para predecir el tipo de vino. Nuestro objetivo es construir un modelo de clasificación que prediga con precisión el tipo de vino.

Antecedentes

La historia del vino es tan antigua como la humanidad. El hombre prehistórico ya sabía cómo elaborarlo y los paleontólogos han encontrado fósiles en los que aparecen uvas prensadas. Vinos muy especiales de esta ciudad, han sido comercializados por todo el mundo e incluso han estado presentes en acontecimientos históricos. Cuando hablamos del vino, hablamos de un largo proceso y unas costosas transformaciones que nos llevan a la calidad. El vino es y será un auténtico compañero del hombre a lo largo de los tiempos.

El vino, tal como se conoce hoy en día, es una bebida alcohólica procedente de la fermentación del zumo de uva, la cual se produce gracias a la acción de las levaduras presentes en el hollejo de las uvas. El nombre vino procede del latín vino, que se cree que procede del griego ovinos e incluso del sánscrito vena.

Datos

Los datos provienen del repositorio de “UCI Machine Learning”. Incluyen dos conjuntos de datos, relacionados con muestras de vino tinto y blanco, del norte de Portugal, basándose en pruebas fisicoquímicas.

El conjunto de datos tiene 12 variables de entrada basadas en pruebas fisicoquímicas y una de salida la calidad basada en datos sensoriales, Para este análisis se agrega una nueva variable categórica el “Tipo de Vino”: Blanco y Rojo. El conjunto de datos del vino blanco con 4898 observaciones y vino rojo con 1599 observaciones.

Características

Variables de entrada (basadas en pruebas fisicoquímicas):

  • Acidez fija
  • Acidez volátil
  • Ácido cítrico
  • Azúcar residual
  • Cloruros
  • Dióxido de azufre libre
  • Dióxido de azufre total
  • Densidad
  • pH
  • Sulfatos
  • Alcohol

Variable de salida (basada en datos sensoriales):

  • Calidad (puntuación entre 0 y 10)

Análisis exploratorio

Para visualizar como se distribuyen los datos, se hace un exploración de datos. 

Ilustración 1. Correlación de las variables explicativas

Ilustración 2. Comparación de todas las variables de vino tinto y blanco.



En la ilustración 1 se observa que hay mayor variabilidad de la variable Dióxido de azufre total(DAT) y dióxido de azufre libre(DAL) en vino blanco, así mismo se presentan datos atípicos. 




Ilustración 3. Comparación de acidez de vino tinto con vino blanco.

Se muestra en la ilustración 3 una comparación de acidez fija, acidez volátil y acido cítrico del vino tinto y vino blanco, se observa que el vino tinto tiene mayor variabilidad que el vino blanco. 

Ilustración 4. Comparación de azúcar, cloruros  y dióxidos.

En la ilustración 4, se observa el azúcar residual, dióxido de azufre libre y dióxido de azufre total de vino blanco tienen mayor variabilidad que de vino tinto. Los valores cloruro de vino tinto tiene mayor variabilidad que el vino blanco.

Ilustración 5. Comparación de densidad, pH, sulfatos y alcohol.

Preparación de datos (Dividir datos)

Utilizando k-fold Cross Validation para construir el modelo de clasificación. dividendo la base de datos en dos partes, Se toma el 80% de los datos como conjunto de entrenamiento y el 20% como conjunto de validación.

Tabla 1. Observaciones de entrenamiento y validación en niño blanco y vino rojo.

 

Blanco

Rojo

Entrenamiento

3918

1279

Validación

980

320

 

Se compara seis modelos para ver cuál de ellos tiene  menor error de clasificación.

·         La Regresión Logística es un tipo de modelo de regresión que se emplea para predecir variables categóricas, es decir, relaciones entre variales independientes y una variable dependiente que solo puede tomar un valor entero y finito de clases. 

·         La clasificación por k vecinos cercanos o k-NN es un modelo de clasificación que basa su entrenamiento en el cálculo de las distancias de un nuevo dato o dato al que se desee asignar a una clase, con la mayoría de clases a las que pertenezcan sus k vecinos más cercanos, siendo k un parámetro del algoritmo.

·         Las Máquinas de Vectores de Soporte son modelos capaces de generar clasificaciones o regresiones de datos no lineales a partir de la transformación de los datos de entrada a otros espacios de mayores dimensiones. En el caso de la clasificación, la SVM busca encontrar aquella curva que sea capaz de separar y clasificar los datos de entrenamiento garantizando que la separación entre ésta y ciertas observaciones del conjunto de entrenamiento (los vectores de soporte) sea la mayor posible. 

·         Este modelo es un clasificador fundamentalmente probabilístico y basado en el Teorema de Bayes. Se le dice ingenuo porque parte de la presunción de que todas las variables predictoras del modelo tienen total independencia lineal, cosa que de entrada puede no ser siempre cierto.

·         Los Árboles de Decisión son modelos de predicción que pueden usarse tanto para clasificación como para regresión, y cuyo funcionamiento se basa en la construcción de reglas lógicas (divisiones de los datos entre rangos o condiciones) a partir de los datos de entrada. El entrenamiento de los árboles de decisión se centra principalmente en la maximización de la ganancia de información al momento de realizar las reglas lógicas que forman el árbol.

·         La clasificación con Bosques Aleatorios o Random Forests, implica la construcción al azar de una gran cantidad de árboles de decisión sobre un mismo conjunto de datos, y la decisión final de la clasificación es tomada a partir de calcular el voto de la mayoría de las predicciones ofrecidas por cada uno de los árboles que conforman el bosque.

sd           Comparación de modelos

     En la tabla 1 se muestra los resultados obtenidos de cada modelo. Siendo el modelo Kernel-SvM el de mejor precisión.

Regresión Logística

k-NN

Kernel-SVM

Naive Bayes

Decision Tree

Random Forests

Precisión

99.36

93.80

99.53

97.38

97.69

99.38

Error

0.64

6.2

0.47

2.62

2.31

0.62

A partir de estos resultados teniendo que el modelo de Kernel-SVM es el que mejor precisión ofrece, y por lo tanto se usa este modelo sobre el conjunto de validación inicial:

          

 

Blanco

Rojo

Blanco

979

1

Rojo

1

319

 Teniendo una precisión de 99.76% sobre los datos de validación, clasifico correctamente 979 observaciones de vino blanco, mientras 1 predicciones incorrecta, del vino rojo 1 lo clasifico incorrectamente y 319 predicciones correctamente.

Para este clasificador, obtenemos también no solo altos valores en la precisión de la predicción, sino una curva ROC que se acerca más al caso ideal según lo conocido de las curvas ROC. como el la Ilustración 6.

Ilustración 6. curvas ROC

Codigo

# Calidad de Vino tinto

#================================================================

vino <- read.csv(header=TRUE,"C:/Users/Erika/Desktop/6 Semestre Feb-Jun(2021)/Big Data/vinos.csv")

vino

str(vino)

vino$TipoVino <- as.factor(vino$TipoVino)

vino[, c(2:13)] <- scale(vino[, c(2:13)])

summary(vino)

#=================================================================

#Analisis Exploratorio

plot(vino)

vb <- vino[1:4898,13]

tb <- table(vb) ; tb

vr <- vino[4899:6497,13]

tr <- table(vr) ; tr


par(mfrow=c(2,1))

boxplot(vino[1:4898,-1], main="Vino Blanco",col = rainbow(14))

boxplot(vino[4899:6497,-1], main="Vinos Rojo",col = rainbow(14))


library(ggplot2)

vb <- vino[1:4898,]

tb <- table(vb) ; tb

vr <- vino[4899:6497,]

tr <- table(vr) ; tr

#=================================================

#Preparacción de Datos

install.packages("caTools")

install.packages("lattice")

install.packages("caret")

install.packages("e1071")

install.packages("stats")

install.packages("randomForest")


library(stats)

library("caTools")

#Divicion de DAtos de Entrenamiento y de prueba

set.seed(1234)

split <- sample.split(vino$TipoVino, SplitRatio = 0.80)

training_set <- subset(vino, split == TRUE)

test_set <- subset(vino, split == FALSE)


table(training_set$TipoVino)

table(test_set$TipoVino)


library(caret)

folds <- createFolds(training_set$TipoVino, k = 10)


# Regresion Logistica

cvRegresionLogistica <- lapply(folds, function(x){

  training_fold <- training_set[-x, ]

  test_fold <- training_set[x, ]

  clasificador <- glm(TipoVino ~ ., family = binomial, data = training_fold)

  y_pred <- predict(clasificador, type = 'response', newdata = test_fold)

  y_pred <- ifelse(y_pred > 0.5, 1, 0)

  

  cm <- table(test_fold$TipoVino, y_pred)

  precision <- (cm[1,1] + cm[2,2]) / (cm[1,1] + cm[2,2] +cm[1,2] + cm[2,1])

  return(precision)

})

precisionRegresionLogistica <- mean(as.numeric(cvRegresionLogistica))

precisionRegresionLogistica

clasificadorrl <- glm(TipoVino ~ ., family = binomial, data = training_set)

summary(clasificadorrl)

library(MASS)

confint(clasificadorrl)

plot(precisionRegresionLogistica)

# k-NN

library(class)

cvkNN <- lapply(folds, function(x){

  training_fold <- training_set[-x, ]

  test_fold <- training_set[x, ]

  y_pred <- knn(training_fold[, -1], 

                test_fold[, -1], 

                cl = training_fold[, 1], 

                k = 10)

  cm <- table(test_fold$TipoVino, y_pred)

  precision <- (cm[1,1] + cm[2,2]) / (cm[1,1] + cm[2,2] +cm[1,2] + cm[2,1])

  return(precision)

})

precisionkNN <- mean(as.numeric(cvkNN))

precisionkNN


# Kernel-SVM

library(e1071)

cvKernelSVM <- lapply(folds, function(x){

  training_fold <- training_set[-x, ]

  test_fold <- training_set[x, ]

  clasificador <- svm(TipoVino ~ .,

                      data = training_fold, 

                      type = 'C-classification', 

                      kernel = 'radial')

  y_pred <- predict(clasificador, newdata = test_fold)

  cm <- table(test_fold$TipoVino, y_pred)

  precision <- (cm[1,1] + cm[2,2]) / (cm[1,1] + cm[2,2] +cm[1,2] + cm[2,1])

  return(precision)

})

precisionKernelSVM <- mean(as.numeric(cvKernelSVM))

precisionKernelSVM

clasificador <- svm(TipoVino ~ .,

                    data = training_set, 

                    type = 'C-classification', 

                    kernel = 'radial')

summary(clasificador)


clasificadorKS <- svm(TipoVino ~ .,

                    data = training_set, 

                    type = 'C-classification', 

                    kernel = 'radial')

y_pred <- predict(clasificadorKS, newdata = test_set)

cm <- table(test_set$TipoVino, y_pred)

cm

precision <- (cm[1,1] + cm[2,2]) / (cm[1,1] + cm[2,2] +cm[1,2] + cm[2,1])

precision


# Naive Bayes

cvNaiveBayes <- lapply(folds, function(x){

  training_fold <- training_set[-x, ]

  test_fold <- training_set[x, ]

  clasificador <- naiveBayes(TipoVino ~ ., data = training_fold)

  y_pred <- predict(clasificador, newdata = test_fold)

  cm <- table(test_fold$TipoVino, y_pred)

  precision <- (cm[1,1] + cm[2,2]) / (cm[1,1] + cm[2,2] +cm[1,2] + cm[2,1])

  return(precision)

})

precisionNaiveBayes <- mean(as.numeric(cvNaiveBayes))


# Decision Tree

library(rpart)

cvDecisionTree <- lapply(folds, function(x){

  training_fold <- training_set[-x, ]

  test_fold <- training_set[x, ]

  clasificador <- rpart(TipoVino ~ ., data = training_fold)

  y_pred <- predict(clasificador, newdata = test_fold, type = 'class')

  cm <- table(test_fold$TipoVino, y_pred)

  precision <- (cm[1,1] + cm[2,2]) / (cm[1,1] + cm[2,2] +cm[1,2] + cm[2,1])

  return(precision)

})

precisionDecisionTree <- mean(as.numeric(cvDecisionTree))

clasificador <- rpart(TipoVino ~ ., data = training_set)

summary(clasificador)


# Random Forest

library(randomForest)

cvRandomForest <- lapply(folds, function(x){

  training_fold <- training_set[-x, ]

  test_fold <- training_set[x, ]

  clasificador <- randomForest(TipoVino ~ ., data = training_fold, ntree = 250)

  y_pred <- predict(clasificador, newdata = test_fold)

  cm <- table(test_fold$TipoVino, y_pred)

  precision <- (cm[1,1] + cm[2,2]) / (cm[1,1] + cm[2,2] +cm[1,2] + cm[2,1])

  return(precision)

})

precisionRandomForest <- mean(as.numeric(cvRandomForest))

precisionRandomForest



library(randomForest)

clasificadorRF <- randomForest(TipoVino ~ ., data = training_set, ntree = 250)

y_pred <- predict(clasificadorRF, newdata = test_set)

cm <- table(test_set$TipoVino, y_pred)

cm

precisionRF <- (cm[1,1] + cm[2,2]) / (cm[1,1] + cm[2,2] +cm[1,2] + cm[2,1])

precisionRF


library(stats)

summary(clasificadorRF)

predicted(clasificadorRF)


install.packages("ROCR")

varImpPlot(clasificadorRF)


library(ROCR)

pred1 <- prediction(as.numeric(y_pred), as.numeric(test_set$TipoVino))

perf1 <- performance(pred1, "tpr", "fpr")

plot(perf1)  










Comentarios

Entradas más populares de este blog

Análisis de turismo en México

Google Trend