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 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
Publicar un comentario