library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.1 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggplot2)
library(readxl)
require(tibble)
library(readr)
library(dplyr)
library(Amelia)
## Cargando paquete requerido: Rcpp
## ##
## ## Amelia II: Multiple Imputation
## ## (Version 1.8.2, built: 2024-04-10)
## ## Copyright (C) 2005-2024 James Honaker, Gary King and Matthew Blackwell
## ## Refer to http://gking.harvard.edu/amelia/ for more information
## ##
library(Rcpp)
library(knitr)
library(kableExtra)
##
## Adjuntando el paquete: 'kableExtra'
##
## The following object is masked from 'package:dplyr':
##
## group_rows
library(maps)
##
## Adjuntando el paquete: 'maps'
##
## The following object is masked from 'package:purrr':
##
## map
library(psych)
##
## Adjuntando el paquete: 'psych'
##
## The following objects are masked from 'package:ggplot2':
##
## %+%, alpha
library(countrycode)
library(e1071)
library(reshape2)
##
## Adjuntando el paquete: 'reshape2'
##
## The following object is masked from 'package:tidyr':
##
## smiths
library(VIM)
## Cargando paquete requerido: colorspace
## Cargando paquete requerido: grid
## VIM is ready to use.
##
## Suggestions and bug-reports can be submitted at: https://github.com/statistikat/VIM/issues
##
## Adjuntando el paquete: 'VIM'
##
## The following object is masked from 'package:datasets':
##
## sleep
library(mice)
##
## Adjuntando el paquete: 'mice'
##
## The following object is masked from 'package:stats':
##
## filter
##
## The following objects are masked from 'package:base':
##
## cbind, rbind
library(naniar)
library(gridExtra)
##
## Adjuntando el paquete: 'gridExtra'
##
## The following object is masked from 'package:dplyr':
##
## combine
library(lattice)
library(EnvStats)
##
## Adjuntando el paquete: 'EnvStats'
##
## The following objects are masked from 'package:e1071':
##
## kurtosis, skewness
##
## The following objects are masked from 'package:stats':
##
## predict, predict.lm
library(ggcorrplot)
library(psych)
La Inteligencia Artificial (IA) ha revolucionado numerosos campos en los últimos años, convirtiéndose en una herramienta clave para resolver problemas complejos y optimizar procesos en una amplia variedad de industrias. En el núcleo de la IA se encuentran los algoritmos que permiten a las máquinas aprender y tomar decisiones basadas en grandes volúmenes de datos. Estos algoritmos, cuando son entrenados adecuadamente, pueden clasificar datos, hacer predicciones y encontrar patrones en situaciones donde las soluciones tradicionales no son suficientes. Sin embargo, la elección del algoritmo adecuado, el framework de desarrollo y el tipo de problema a abordar juegan un papel crucial en la efectividad y eficiencia de los modelos de IA.
Este trabajo tiene como propósito realizar un Análisis Exploratorio de Datos (EDA) sobre un conjunto de datos sintético relacionado con problemas de Inteligencia Artificial (IA). El dataset fue generado con fines educativos y contiene información sobre diversos algoritmos de IA, frameworks, tipos de problemas abordados, y métricas de desempeño como la precisión y el tiempo de entrenamiento. A través de este análisis, se busca obtener una mejor comprensión del comportamiento de los modelos y su desempeño en diferentes contextos.
El análisis se centrará en investigar el tipo de problema que presenta el menor tiempo de entrenamiento sin comprometer la precisión, utilizando específicamente el algoritmo Random Forest y el framework Scikit-learn. Además, se hará un análisis de la distribución de las variables categóricas, se revisarán los valores faltantes y se identificarán outliers que podrían influir en los resultados del análisis. Este enfoque permitirá explorar las diferencias entre estos tipos de problemas y cómo se comportan en términos de tiempo y precisión, aportando valiosa información para la optimización de los modelos en aplicaciones prácticas de IA.
El objetivo de este Análisis Exploratorio de Datos (EDA) es responder a la pregunta: ¿Qué tipo de problema logra el menor tiempo de entrenamiento sin comprometer la precisión, utilizando el algoritmo Random Forest y el framework Scikit-learn?. Para lograrlo, se analizarán los patrones de comportamiento de los modelos de inteligencia artificial en función de estas variables clave, evaluando el equilibrio entre el tiempo de entrenamiento y la precisión alcanzada por cada tipo de problema.
Además, se llevará a cabo una revisión exhaustiva de los valores faltantes, se detectarán y tratarán outliers, y se aplicarán técnicas de limpieza de datos, todo con el fin de preparar adecuadamente el conjunto de datos, con el fin de asegurar que la calidad del conjunto de datos sea adecuada para futuros análisis.
Inicialmente, los datos estaban almacenados en un archivo Excel (.xlsx), por lo que se intentó leer utilizando la librería readxl, la cual permite manejar archivos en este formato. Sin embargo, parecía vacío al cargarse en R. Debido a esta situación, se decidió convertir el archivo de Excel a formato CSV para garantizar su correcta lectura y manipulación.
# Cargar la base de datos en la variable "datos"
datos <- read.csv(file.choose(),
sep=",",
header=TRUE,
fileEncoding = "UTF-8")
# Inspección de la estructura del dataset
library(kableExtra)
kable(datos[1:20, ], caption= "Tabla 1: DataSet ") %>%
kable_styling(full_width = F) %>%
column_spec(2, width = "20em") %>%
scroll_box(width = "900px", height = "450px")
Algorithm | Framework | Problem_Type | Dataset_Type | Accuracy | Precision | Recall | F1_Score | Training_Time | Date |
---|---|---|---|---|---|---|---|---|---|
SVM | Scikit-learn | Regression | Time Series | 0.6618051 | 0.6929447 | NA | 0.4426950 | 4.9785924 | 2023-03-08 11:26:21 |
K-Means | Keras | Clustering | Time Series | 0.7443216 | 0.4900292 | 0.8766533 | 0.4414046 | NA | 2023-03-09 11:26:21 |
Neural Network | Keras | Clustering | Image | 0.8852037 | 0.5948056 | 0.9685424 | 0.9644707 | 3.2825938 | 2023-03-10 11:26:21 |
SVM | Keras | Clustering | Text | 0.8416477 | 0.8424142 | 0.8748388 | 0.7041523 | 4.0416289 | 2023-03-11 11:26:21 |
SVM | Scikit-learn | Regression | Tabular | 0.7229514 | 0.6856109 | 0.3010956 | 0.6456472 | 3.6039908 | 2023-03-12 11:26:21 |
K-Means | PyTorch | Regression | Image | 0.6368133 | 0.6255330 | 7.4548096 | 0.8865271 | 3.0064753 | 2023-03-13 11:26:21 |
Neural Network | PyTorch | Regression | Text | 0.9985623 | 0.6366858 | 0.3357948 | 0.9014956 | NA | 2023-03-14 11:26:21 |
Neural Network | Scikit-learn | Regression | Image | 0.7130907 | 0.6756681 | 0.4803251 | 0.5993146 | 2.3283453 | 2023-03-15 11:26:21 |
SVM | Keras | Regression | Time Series | NA | 0.8710099 | 0.3416673 | 0.8161708 | 3.4064529 | 2023-03-16 11:26:21 |
Random Forest | Keras | Regression | Text | 0.5818119 | 0.9352508 | NA | 0.8626737 | 3.4199049 | 2023-03-17 11:26:21 |
SVM | PyTorch | Regression | Image | 0.8974048 | 9.7320081 | 0.7806129 | 0.7927904 | 1.9283008 | 2023-03-18 11:26:21 |
SVM | Keras | Clustering | Image | 0.8468411 | 0.8721420 | 0.3801413 | 0.4909570 | 4.7142907 | 2023-03-19 11:26:21 |
SVM | TensorFlow | Clustering | Tabular | 0.6103848 | 0.5892441 | 0.5686872 | 0.9255299 | 0.9200495 | 2023-03-20 11:26:21 |
SVM | PyTorch | Clustering | Image | 0.5411905 | 0.8128808 | 0.6193656 | 0.7234567 | 2.5517613 | 2023-03-21 11:26:21 |
K-Means | Keras | Clustering | Text | 0.8402497 | 0.6625619 | 0.5583371 | 0.5694835 | 3.4853315 | 2023-03-22 11:26:21 |
Neural Network | PyTorch | Regression | Text | NA | 0.5528024 | 0.3847175 | 0.6551369 | 3.5159654 | 2023-03-23 11:26:21 |
K-Means | TensorFlow | Classification | Tabular | 0.6366298 | 0.9045229 | 0.5932635 | 0.4225427 | 3.2783309 | 2023-03-24 11:26:21 |
K-Means | PyTorch | Regression | Text | 0.9754318 | 0.4230558 | 0.8258246 | 0.4767201 | 1.4489122 | 2023-03-25 11:26:21 |
K-Means | PyTorch | Classification | Time Series | 0.5755289 | 0.9410572 | 0.3497054 | 0.8593281 | 0.8654122 | 2023-03-26 11:26:21 |
SVM | PyTorch | Clustering | Text | 0.7161674 | 0.6768865 | 0.3561260 | 0.4000070 | 3.2161076 | 2023-03-27 11:26:21 |
dim(datos)
## [1] 560 10
El resultado muestra un data frame con 560 observaciones(filas) y 10 variables(columnas). Este tamaño de muestra es suficiente para realizar un análisis significativo, ya que permite identificar patrones y relaciones en los datos.
names(datos)
## [1] "Algorithm" "Framework" "Problem_Type" "Dataset_Type"
## [5] "Accuracy" "Precision" "Recall" "F1_Score"
## [9] "Training_Time" "Date"
sapply(datos, class)
## Algorithm Framework Problem_Type Dataset_Type Accuracy
## "character" "character" "character" "character" "numeric"
## Precision Recall F1_Score Training_Time Date
## "numeric" "numeric" "numeric" "numeric" "character"
Cualitativas Categóricas:
Algorithm: Indica el tipo de algoritmo de inteligencia artificial utilizado.
Framework: Indica el framework o biblioteca utilizada para la implementación del modelo.
Problem_Type: Identifica el tipo de problema abordado por el modelo
Dataset_Type: Describe el tipo de datos utilizados en el entrenamiento del modelo.
Date: Representa la fecha en la que se realizó la evaluación del modelo.
Cuantitativas Continuas:
Accuracy: Mide la precisión del modelo.
Precision: Mide la precisión del modelo en términos de la fracción de positivos verdaderos sobre el total de positivos predichos.
Recall: Mide la capacidad del modelo para identificar correctamente los positivos verdaderos.
F1_Score: Mide el balance entre precisión y recall, medida armónica de ambas métricas.
Training_Time: Indica el tiempo de entrenamiento del modelo en horas.
str(datos)
## 'data.frame': 560 obs. of 10 variables:
## $ Algorithm : chr "SVM" "K-Means" "Neural Network" "SVM" ...
## $ Framework : chr "Scikit-learn" "Keras" "Keras" "Keras" ...
## $ Problem_Type : chr "Regression" "Clustering" "Clustering" "Clustering" ...
## $ Dataset_Type : chr "Time Series" "Time Series" "Image" "Text" ...
## $ Accuracy : num 0.662 0.744 0.885 0.842 0.723 ...
## $ Precision : num 0.693 0.49 0.595 0.842 0.686 ...
## $ Recall : num NA 0.877 0.969 0.875 0.301 ...
## $ F1_Score : num 0.443 0.441 0.964 0.704 0.646 ...
## $ Training_Time: num 4.98 NA 3.28 4.04 3.6 ...
## $ Date : chr "2023-03-08 11:26:21" "2023-03-09 11:26:21" "2023-03-10 11:26:21" "2023-03-11 11:26:21" ...
A continuación se presenta la tabala de operacionalización de variables utilizando el paquete knitr, que organiza la clasificación de las variables según su tipo y subtipo:
# Crear un nuevo dataframe para la tabla de operacionalización
operacionalizacion <- data.frame(
Variable = c("Algorithm", "Framework", "Problem_Type", "Dataset_Type", "Accuracy",
"Precision", "Recall", "F1_Score", "Training_Time", "Date"),
Naturaleza = c("Cualitativa/Categórica", "Cualitativa/Categórica", "Cualitativa/Categórica",
"Cualitativa/Categórica", "Cuantitativa/Numerica", "Cuantitativa/Numerica",
"Cuantitativa/Numerica", "Cuantitativa/Numerica", "Cuantitativa/Numerica",
"Cuantitativa/Numerica"),
Nivel_de_Medicion = c("Nominal", "Nominal", "Nominal", "Nominal", "Continua de razón",
"Continua de razón", "Continua de razón", "Continua de razón",
"Continua de razón", "Intervalo (ordinal)"),
Criterio_Clasificacion = c(
"Algoritmo de IA usado (e.g., SVM, K-Means, Neural Network, Random Forest).",
"Framework o biblioteca utilizada (e.g., Scikit-learn, Keras, TensorFlow, PyTorch).",
"Tipo de problema abordado por el algoritmo (Clasificación, Regresión, Clustering).",
"Tipo de datos (Image, Text, Tabular, Time Series).",
"Medida de la precisión del modelo (valor entre 0 y 1).",
"Proporción de positivos verdaderos entre todos los positivos predichos.",
"Proporción de positivos verdaderos correctamente identificados.",
"Medida armónica entre la precisión y el recall del modelo.",
"Tiempo de entrenamiento del modelo en horas.",
"Fecha en la que se realizó la evaluación del modelo."
),
stringsAsFactors = FALSE # Para evitar que se conviertan en factores
)
# Generar la tabla estilizada en RMarkdown
operacionalizacion %>%
kbl(caption = "Tabla de Operacionalización de Variables") %>%
kable_styling(full_width = F, bootstrap_options = c("striped", "hover", "condensed", "responsive"),
font_size = 14, position = "center") %>%
row_spec(0, bold = TRUE, color = "white", background = "#0073C2FF") %>% # Encabezado con estilo
row_spec(1:nrow(operacionalizacion), background = "lightgray") # Alternar color de filas
Variable | Naturaleza | Nivel_de_Medicion | Criterio_Clasificacion |
---|---|---|---|
Algorithm | Cualitativa/Categórica | Nominal | Algoritmo de IA usado (e.g., SVM, K-Means, Neural Network, Random Forest). |
Framework | Cualitativa/Categórica | Nominal | Framework o biblioteca utilizada (e.g., Scikit-learn, Keras, TensorFlow, PyTorch). |
Problem_Type | Cualitativa/Categórica | Nominal | Tipo de problema abordado por el algoritmo (Clasificación, Regresión, Clustering). |
Dataset_Type | Cualitativa/Categórica | Nominal | Tipo de datos (Image, Text, Tabular, Time Series). |
Accuracy | Cuantitativa/Numerica | Continua de razón | Medida de la precisión del modelo (valor entre 0 y 1). |
Precision | Cuantitativa/Numerica | Continua de razón | Proporción de positivos verdaderos entre todos los positivos predichos. |
Recall | Cuantitativa/Numerica | Continua de razón | Proporción de positivos verdaderos correctamente identificados. |
F1_Score | Cuantitativa/Numerica | Continua de razón | Medida armónica entre la precisión y el recall del modelo. |
Training_Time | Cuantitativa/Numerica | Continua de razón | Tiempo de entrenamiento del modelo en horas. |
Date | Cuantitativa/Numerica | Intervalo (ordinal) | Fecha en la que se realizó la evaluación del modelo. |
En esta sección se presenta el Resumen Estadístico del dataset. El análisis de las variables cualitativas se realiza mediante tablas de frecuencia y diagramas de barras, que muestran la distribución de las categorías en cada una. Esto es esencial para identificar cómo se distribuyen las observaciones entre las distintas categorías.
Por otro lado, el análisis de las variables cuantitativas incluye un resumen estadístico que muestra medidas como la media, mediana, mínimo, máximo y los cuartiles. Estas medidas son clave para comprender la dispersión y tendencia central de los datos numéricos.
Es importante destacar que la variable “Date” no fue considerada para este análisis exploratorio, ya que su relevancia en el contexto no era crítica para los objetivos actuales.
# Resumen estadístico detallado
describe(datos)
## vars n mean sd median trimmed mad min max range
## Algorithm* 1 560 2.42 1.15 2.00 2.40 1.48 1.0 4.00 3.00
## Framework* 2 560 2.61 1.13 3.00 2.64 1.48 1.0 4.00 3.00
## Problem_Type* 3 560 2.02 0.81 2.00 2.03 1.48 1.0 3.00 2.00
## Dataset_Type* 4 560 2.42 1.12 2.00 2.40 1.48 1.0 4.00 3.00
## Accuracy 5 521 0.88 0.94 0.76 0.76 0.19 0.5 9.72 9.21
## Precision 6 541 0.81 0.85 0.72 0.71 0.22 0.4 9.73 9.33
## Recall 7 540 0.75 0.78 0.65 0.66 0.27 0.3 9.37 9.07
## F1_Score 8 540 0.81 0.89 0.71 0.70 0.22 0.4 9.37 8.97
## Training_Time 9 540 2.99 4.42 2.43 2.52 1.87 0.1 46.99 46.88
## Date* 10 560 280.50 161.80 280.50 280.50 207.56 1.0 560.00 559.00
## skew kurtosis se
## Algorithm* 0.10 -1.42 0.05
## Framework* -0.12 -1.38 0.05
## Problem_Type* -0.05 -1.46 0.03
## Dataset_Type* 0.08 -1.36 0.05
## Accuracy 7.32 55.40 0.04
## Precision 7.96 69.45 0.04
## Recall 7.27 59.60 0.03
## F1_Score 7.47 59.15 0.04
## Training_Time 7.63 66.83 0.19
## Date* 0.00 -1.21 6.84
# Función para calcular las frecuencias absolutas, relativas, acumuladas y la moda
resumen_categorico <- function(variable, nombre_variable) {
# Calcular la tabla de frecuencias absolutas
frecuencias_absolutas <- table(variable)
# Calcular la frecuencia relativa
frecuencias_relativas <- prop.table(frecuencias_absolutas) * 100
# Calcular la frecuencia acumulada
frecuencias_acumuladas <- cumsum(frecuencias_absolutas)
# Identificar la moda
moda <- names(frecuencias_absolutas[frecuencias_absolutas == max(frecuencias_absolutas)])
cantidad_moda <- max(frecuencias_absolutas)
# Crear el dataframe con el resumen
resumen_df <- data.frame(
Categoria = names(frecuencias_absolutas),
Frecuencia_Absoluta = as.numeric(frecuencias_absolutas),
Frecuencia_Relativa = round(as.numeric(frecuencias_relativas), 2),
Frecuencia_Acumulada = as.numeric(frecuencias_acumuladas)
)
# Añadir la moda como fila adicional
resumen_df <- resumen_df %>%
add_row(Categoria = paste("Moda:", moda),
Frecuencia_Absoluta = cantidad_moda,
Frecuencia_Relativa = NA, # No aplica para la moda
Frecuencia_Acumulada = NA) # No aplica para la moda
# Crear una tabla estilizada con kable
tabla_kable <- resumen_df %>%
kbl(caption = paste("Resumen de Frecuencias para", nombre_variable), digits = 2, align = "c") %>%
kable_styling(full_width = F, bootstrap_options = c("striped", "hover", "condensed"),
font_size = 12, position = "center") %>%
column_spec(1, bold = TRUE, background = "lightblue")
tabla_kable %>%
row_spec(nrow(resumen_df), bold = TRUE, color = "white", background = "red")
}
# Aplicar la función a las variables categóricas
resumen_categorico(datos$Algorithm, "Algorithm")
Categoria | Frecuencia_Absoluta | Frecuencia_Relativa | Frecuencia_Acumulada |
---|---|---|---|
K-Means | 163 | 29.11 | 163 |
Neural Network | 135 | 24.11 | 298 |
Random Forest | 126 | 22.50 | 424 |
SVM | 136 | 24.29 | 560 |
Moda: K-Means | 163 | NA | NA |
resumen_categorico(datos$Framework, "Framework")
Categoria | Frecuencia_Absoluta | Frecuencia_Relativa | Frecuencia_Acumulada |
---|---|---|---|
Keras | 124 | 22.14 | 124 |
PyTorch | 135 | 24.11 | 259 |
Scikit-learn | 134 | 23.93 | 393 |
TensorFlow | 167 | 29.82 | 560 |
Moda: TensorFlow | 167 | NA | NA |
resumen_categorico(datos$Problem_Type, "Problem Type")
Categoria | Frecuencia_Absoluta | Frecuencia_Relativa | Frecuencia_Acumulada |
---|---|---|---|
Classification | 175 | 31.25 | 175 |
Clustering | 196 | 35.00 | 371 |
Regression | 189 | 33.75 | 560 |
Moda: Clustering | 196 | NA | NA |
resumen_categorico(datos$Dataset_Type, "Dataset Type")
Categoria | Frecuencia_Absoluta | Frecuencia_Relativa | Frecuencia_Acumulada |
---|---|---|---|
Image | 157 | 28.04 | 157 |
Tabular | 136 | 24.29 | 293 |
Text | 143 | 25.54 | 436 |
Time Series | 124 | 22.14 | 560 |
Moda: Image | 157 | NA | NA |
# 1. Distribución de Algoritmos
freq_algorithm <- as.data.frame(table(datos$Algorithm))
freq_algorithm$Percentage <- round((freq_algorithm$Freq / sum(freq_algorithm$Freq)) * 100, 1)
# Ordenar los datos por la frecuencia de forma ascendente
freq_algorithm <- freq_algorithm[order(freq_algorithm$Freq), ]
ggplot(freq_algorithm, aes(x = reorder(Var1, Freq), y = Freq)) + # Reorder para el orden ascendente
geom_bar(stat = "identity", fill = "steelblue", color = "grey50") + # Color gris para el contorno
geom_text(aes(label = paste(Freq, "(", Percentage, "%)", sep="")),
vjust = -0.5,
size = 6,
angle = 0) +
labs(title = "Distribución de Algoritmos",
x = "Algoritmo",
y = "Frecuencias (Porcentajes)") +
theme_minimal(base_size = 18) +
theme(panel.grid.major = element_line(color = "grey90"), # Añadir el grid
panel.grid.minor = element_line(color = "grey90"), # Añadir el grid menor
panel.border = element_rect(color = "grey50", fill = NA), # Añadir el borde
plot.title = element_text(hjust = 0.5),
axis.text.x = element_text(angle = 45, hjust = 1)) +
ylim(0, max(freq_algorithm$Freq) + 20)
# 2. Distribución de Frameworks
freq_framework <- as.data.frame(table(datos$Framework))
freq_framework$Percentage <- round((freq_framework$Freq / sum(freq_framework$Freq)) * 100, 1)
# Ordenar los datos por la frecuencia de forma ascendente
freq_framework <- freq_framework[order(freq_framework$Freq), ]
ggplot(freq_framework, aes(x = reorder(Var1, Freq), y = Freq)) +
geom_bar(stat = "identity", fill = "lightgreen", color = "grey50") +
geom_text(aes(label = paste(Freq, "(", Percentage, "%)", sep="")),
vjust = -0.5,
size = 6,
angle = 0) +
labs(title = "Distribución de Frameworks",
x = "Framework",
y = "Frecuencias (Porcentajes)") +
theme_minimal(base_size = 18) +
theme(panel.grid.major = element_line(color = "grey90"),
panel.grid.minor = element_line(color = "grey90"),
panel.border = element_rect(color = "grey50", fill = NA),
plot.title = element_text(hjust = 0.5),
axis.text.x = element_text(angle = 45, hjust = 1)) +
ylim(0, max(freq_framework$Freq) + 20)
# 3. Distribución de Tipos de Problema
freq_problem_type <- as.data.frame(table(datos$Problem_Type))
freq_problem_type$Percentage <- round((freq_problem_type$Freq / sum(freq_problem_type$Freq)) * 100, 1)
# Ordenar los datos por la frecuencia de forma ascendente
freq_problem_type <- freq_problem_type[order(freq_problem_type$Freq), ]
ggplot(freq_problem_type, aes(x = reorder(Var1, Freq), y = Freq)) +
geom_bar(stat = "identity", fill = "lightcoral", color = "grey50") +
geom_text(aes(label = paste(Freq, "(", Percentage, "%)", sep="")),
vjust = -0.5,
size = 6,
angle = 0) +
labs(title = "Distribución de Tipos de Problema",
x = "Tipo de Problema",
y = "Frecuencias (Porcentajes)") +
theme_minimal(base_size = 18) +
theme(panel.grid.major = element_line(color = "grey90"),
panel.grid.minor = element_line(color = "grey90"),
panel.border = element_rect(color = "grey50", fill = NA),
plot.title = element_text(hjust = 0.5),
axis.text.x = element_text(angle = 45, hjust = 1)) +
ylim(0, max(freq_problem_type$Freq) + 20)
# 4. Distribución de Tipos de Dataset
freq_dataset_type <- as.data.frame(table(datos$Dataset_Type))
freq_dataset_type$Percentage <- round((freq_dataset_type$Freq / sum(freq_dataset_type$Freq)) * 100, 1)
# Ordenar los datos por la frecuencia de forma ascendente
freq_dataset_type <- freq_dataset_type[order(freq_dataset_type$Freq), ]
ggplot(freq_dataset_type, aes(x = reorder(Var1, Freq), y = Freq)) +
geom_bar(stat = "identity", fill = "lightgoldenrod", color = "grey50") +
geom_text(aes(label = paste(Freq, "(", Percentage, "%)", sep="")),
vjust = -0.5,
size = 6,
angle = 0) +
labs(title = "Distribución de Tipos de Dataset",
x = "Tipo de Dataset",
y = "Frecuencias (Porcentajes)") +
theme_minimal(base_size = 18) +
theme(panel.grid.major = element_line(color = "grey90"),
panel.grid.minor = element_line(color = "grey90"),
panel.border = element_rect(color = "grey50", fill = NA),
plot.title = element_text(hjust = 0.5),
axis.text.x = element_text(angle = 45, hjust = 1)) +
ylim(0, max(freq_dataset_type$Freq) + 20)
# Calcular las proporciones de cada categoría en Problem_Type
prop_problem_type <- as.data.frame(table(datos$Problem_Type))
prop_problem_type$Percentage <- round((prop_problem_type$Freq / sum(prop_problem_type$Freq)) * 100, 1)
# Gráfico de torta (pie chart)
ggplot(prop_problem_type, aes(x = "", y = Freq, fill = Var1)) +
geom_bar(width = 1, stat = "identity") +
coord_polar(theta = "y") + # Polar para hacer el gráfico de torta
labs(title = "Distribución de Tipos de Problema",
x = "",
y = "") +
theme_void() + # Tema vacío para gráfico de torta
theme(plot.title = element_text(hjust = 0.5, size = 20, face = "bold"),
legend.title = element_text(size = 15),
legend.text = element_text(size = 12)) +
geom_text(aes(label = paste0(Percentage, "%")),
position = position_stack(vjust = 0.5), size = 5)
RESULTADOS EN TABLAS DE FRECUENCIA:
datos_numericos <- datos[, sapply(datos, is.numeric)]
summary(datos_numericos)
## Accuracy Precision Recall F1_Score
## Min. :0.5038 Min. :0.4019 Min. :0.3001 Min. :0.4000
## 1st Qu.:0.6236 1st Qu.:0.5632 1st Qu.:0.4819 1st Qu.:0.5515
## Median :0.7578 Median :0.7195 Median :0.6493 Median :0.7086
## Mean :0.8779 Mean :0.8129 Mean :0.7486 Mean :0.8122
## 3rd Qu.:0.8824 3rd Qu.:0.8596 3rd Qu.:0.8404 3rd Qu.:0.8438
## Max. :9.7181 Max. :9.7320 Max. :9.3662 Max. :9.3740
## NA's :39 NA's :19 NA's :20 NA's :20
## Training_Time
## Min. : 0.1032
## 1st Qu.: 1.2441
## Median : 2.4347
## Mean : 2.9910
## 3rd Qu.: 3.8131
## Max. :46.9856
## NA's :20
datos_filtrados <- datos$Accuracy[is.finite(datos$Accuracy) & !is.na(datos$Accuracy)] # Eliminar valores no finitos
# Definir los intervalos
intervalos <- cut(datos_filtrados, breaks = seq(min(datos_filtrados, na.rm = TRUE),
max(datos_filtrados, na.rm = TRUE),
length.out = 10), include.lowest = TRUE)
# Calcular las frecuencias absoluta, relativa y acumulada
frecuencia_absoluta <- table(intervalos)
frecuencia_relativa <- prop.table(frecuencia_absoluta)
frecuencia_acumulada <- cumsum(frecuencia_absoluta)
frecuencia_relativa_porcentaje <- frecuencia_relativa * 100
# Crear la tabla de frecuencias
tabla_frecuencias <- data.frame(
Intervalo = names(frecuencia_absoluta),
Frecuencia_Absoluta = as.numeric(frecuencia_absoluta),
Frecuencia_Acumulada = as.numeric(frecuencia_acumulada),
Frecuencia_Relativa = round(as.numeric(frecuencia_relativa_porcentaje), 2) # En porcentaje
)
# Fila al final con los totales
totales <- data.frame(
Intervalo = "Total",
Frecuencia_Absoluta = sum(tabla_frecuencias$Frecuencia_Absoluta),
Frecuencia_Acumulada = NA, # No tiene sentido acumular en la fila total
Frecuencia_Relativa = sum(tabla_frecuencias$Frecuencia_Relativa)
)
tabla_frecuencias <- rbind(tabla_frecuencias, totales)
# Mostrar la tabla usando kable
library(kableExtra)
tabla_frecuencias %>%
kbl(caption = "Tabla de Frecuencias Agrupadas para la variable Accuracy", align = "c") %>%
kable_styling(full_width = F, position = "center", font_size = 12) %>%
row_spec(nrow(tabla_frecuencias), bold = TRUE, color = "white", background = "gray")
Intervalo | Frecuencia_Absoluta | Frecuencia_Acumulada | Frecuencia_Relativa |
---|---|---|---|
[0.504,1.53] | 511 | 511 | 98.08 |
(1.53,2.55] | 0 | 511 | 0.00 |
(2.55,3.58] | 0 | 511 | 0.00 |
(3.58,4.6] | 0 | 511 | 0.00 |
(4.6,5.62] | 2 | 513 | 0.38 |
(5.62,6.65] | 2 | 515 | 0.38 |
(6.65,7.67] | 1 | 516 | 0.19 |
(7.67,8.69] | 3 | 519 | 0.58 |
(8.69,9.72] | 2 | 521 | 0.38 |
Total | 521 | NA | 99.99 |
datos_filtrados <- datos$Precision[is.finite(datos$Precision) & !is.na(datos$Precision)]
intervalos <- cut(datos_filtrados, breaks = seq(min(datos_filtrados, na.rm = TRUE),
max(datos_filtrados, na.rm = TRUE),
length.out = 10), include.lowest = TRUE)
frecuencia_absoluta <- table(intervalos)
frecuencia_relativa <- prop.table(frecuencia_absoluta)
frecuencia_acumulada <- cumsum(frecuencia_absoluta)
frecuencia_relativa_porcentaje <- frecuencia_relativa * 100
tabla_frecuencias <- data.frame(
Intervalo = names(frecuencia_absoluta),
Frecuencia_Absoluta = as.numeric(frecuencia_absoluta),
Frecuencia_Acumulada = as.numeric(frecuencia_acumulada),
Frecuencia_Relativa = round(as.numeric(frecuencia_relativa_porcentaje), 2)
)
totales <- data.frame(
Intervalo = "Total",
Frecuencia_Absoluta = sum(tabla_frecuencias$Frecuencia_Absoluta),
Frecuencia_Acumulada = NA, # No tiene sentido acumular en la fila total
Frecuencia_Relativa = sum(tabla_frecuencias$Frecuencia_Relativa)
)
tabla_frecuencias <- rbind(tabla_frecuencias, totales)
library(kableExtra)
tabla_frecuencias %>%
kbl(caption = "Tabla de Frecuencias Agrupadas para la variable Precision", align = "c") %>%
kable_styling(full_width = F, position = "center", font_size = 12) %>%
row_spec(nrow(tabla_frecuencias), bold = TRUE, color = "white", background = "gray")
Intervalo | Frecuencia_Absoluta | Frecuencia_Acumulada | Frecuencia_Relativa |
---|---|---|---|
[0.402,1.44] | 531 | 531 | 98.15 |
(1.44,2.48] | 0 | 531 | 0.00 |
(2.48,3.51] | 0 | 531 | 0.00 |
(3.51,4.55] | 3 | 534 | 0.55 |
(4.55,5.59] | 1 | 535 | 0.18 |
(5.59,6.62] | 2 | 537 | 0.37 |
(6.62,7.66] | 1 | 538 | 0.18 |
(7.66,8.7] | 0 | 538 | 0.00 |
(8.7,9.73] | 3 | 541 | 0.55 |
Total | 541 | NA | 99.98 |
datos_filtrados <- datos$Recall[is.finite(datos$Recall) & !is.na(datos$Recall)]
intervalos <- cut(datos_filtrados, breaks = seq(min(datos_filtrados, na.rm = TRUE),
max(datos_filtrados, na.rm = TRUE),
length.out = 10), include.lowest = TRUE)
frecuencia_absoluta <- table(intervalos)
frecuencia_relativa <- prop.table(frecuencia_absoluta)
frecuencia_acumulada <- cumsum(frecuencia_absoluta)
frecuencia_relativa_porcentaje <- frecuencia_relativa * 100
tabla_frecuencias <- data.frame(
Intervalo = names(frecuencia_absoluta),
Frecuencia_Absoluta = as.numeric(frecuencia_absoluta),
Frecuencia_Acumulada = as.numeric(frecuencia_acumulada),
Frecuencia_Relativa = round(as.numeric(frecuencia_relativa_porcentaje), 2)
)
totales <- data.frame(
Intervalo = "Total",
Frecuencia_Absoluta = sum(tabla_frecuencias$Frecuencia_Absoluta),
Frecuencia_Acumulada = NA, # No tiene sentido acumular en la fila total
Frecuencia_Relativa = sum(tabla_frecuencias$Frecuencia_Relativa)
)
tabla_frecuencias <- rbind(tabla_frecuencias, totales)
library(kableExtra)
tabla_frecuencias %>%
kbl(caption = "Tabla de Frecuencias Agrupadas para la variable Recall", align = "c") %>%
kable_styling(full_width = F, position = "center", font_size = 12) %>%
row_spec(nrow(tabla_frecuencias), bold = TRUE, color = "white", background = "gray")
Intervalo | Frecuencia_Absoluta | Frecuencia_Acumulada | Frecuencia_Relativa |
---|---|---|---|
[0.3,1.31] | 530 | 530 | 98.15 |
(1.31,2.31] | 0 | 530 | 0.00 |
(2.31,3.32] | 0 | 530 | 0.00 |
(3.32,4.33] | 1 | 531 | 0.19 |
(4.33,5.34] | 2 | 533 | 0.37 |
(5.34,6.34] | 4 | 537 | 0.74 |
(6.34,7.35] | 0 | 537 | 0.00 |
(7.35,8.36] | 2 | 539 | 0.37 |
(8.36,9.37] | 1 | 540 | 0.19 |
Total | 540 | NA | 100.01 |
datos_filtrados <- datos$F1_Score[is.finite(datos$F1_Score) & !is.na(datos$F1_Score)]
intervalos <- cut(datos_filtrados, breaks = seq(min(datos_filtrados, na.rm = TRUE),
max(datos_filtrados, na.rm = TRUE),
length.out = 10), include.lowest = TRUE)
frecuencia_absoluta <- table(intervalos)
frecuencia_relativa <- prop.table(frecuencia_absoluta)
frecuencia_acumulada <- cumsum(frecuencia_absoluta)
frecuencia_relativa_porcentaje <- frecuencia_relativa * 100
tabla_frecuencias <- data.frame(
Intervalo = names(frecuencia_absoluta),
Frecuencia_Absoluta = as.numeric(frecuencia_absoluta),
Frecuencia_Acumulada = as.numeric(frecuencia_acumulada),
Frecuencia_Relativa = round(as.numeric(frecuencia_relativa_porcentaje), 2)
)
totales <- data.frame(
Intervalo = "Total",
Frecuencia_Absoluta = sum(tabla_frecuencias$Frecuencia_Absoluta),
Frecuencia_Acumulada = NA, # No tiene sentido acumular en la fila total
Frecuencia_Relativa = sum(tabla_frecuencias$Frecuencia_Relativa)
)
tabla_frecuencias <- rbind(tabla_frecuencias, totales)
library(kableExtra)
tabla_frecuencias %>%
kbl(caption = "Tabla de Frecuencias Agrupadas para la variable F1_Score", align = "c") %>%
kable_styling(full_width = F, position = "center", font_size = 12) %>%
row_spec(nrow(tabla_frecuencias), bold = TRUE, color = "white", background = "gray")
Intervalo | Frecuencia_Absoluta | Frecuencia_Acumulada | Frecuencia_Relativa |
---|---|---|---|
[0.4,1.4] | 530 | 530 | 98.15 |
(1.4,2.39] | 0 | 530 | 0.00 |
(2.39,3.39] | 0 | 530 | 0.00 |
(3.39,4.39] | 0 | 530 | 0.00 |
(4.39,5.39] | 3 | 533 | 0.56 |
(5.39,6.38] | 2 | 535 | 0.37 |
(6.38,7.38] | 0 | 535 | 0.00 |
(7.38,8.38] | 2 | 537 | 0.37 |
(8.38,9.37] | 3 | 540 | 0.56 |
Total | 540 | NA | 100.01 |
datos_filtrados <- datos$Training_Time[is.finite(datos$Training_Time) & !is.na(datos$Training_Time)]
intervalos <- cut(datos_filtrados, breaks = seq(min(datos_filtrados, na.rm = TRUE),
max(datos_filtrados, na.rm = TRUE),
length.out = 10), include.lowest = TRUE)
frecuencia_absoluta <- table(intervalos)
frecuencia_relativa <- prop.table(frecuencia_absoluta)
frecuencia_acumulada <- cumsum(frecuencia_absoluta)
frecuencia_relativa_porcentaje <- frecuencia_relativa * 100
tabla_frecuencias <- data.frame(
Intervalo = names(frecuencia_absoluta),
Frecuencia_Absoluta = as.numeric(frecuencia_absoluta),
Frecuencia_Acumulada = as.numeric(frecuencia_acumulada),
Frecuencia_Relativa = round(as.numeric(frecuencia_relativa_porcentaje), 2)
)
totales <- data.frame(
Intervalo = "Total",
Frecuencia_Absoluta = sum(tabla_frecuencias$Frecuencia_Absoluta),
Frecuencia_Acumulada = NA, # No tiene sentido acumular en la fila total
Frecuencia_Relativa = sum(tabla_frecuencias$Frecuencia_Relativa)
)
tabla_frecuencias <- rbind(tabla_frecuencias, totales)
library(kableExtra)
tabla_frecuencias %>%
kbl(caption = "Tabla de Frecuencias Agrupadas para la variable Training_Time", align = "c") %>%
kable_styling(full_width = F, position = "center", font_size = 12) %>%
row_spec(nrow(tabla_frecuencias), bold = TRUE, color = "white", background = "gray")
Intervalo | Frecuencia_Absoluta | Frecuencia_Acumulada | Frecuencia_Relativa |
---|---|---|---|
[0.103,5.31] | 531 | 531 | 98.33 |
(5.31,10.5] | 0 | 531 | 0.00 |
(10.5,15.7] | 1 | 532 | 0.19 |
(15.7,20.9] | 2 | 534 | 0.37 |
(20.9,26.1] | 0 | 534 | 0.00 |
(26.1,31.4] | 2 | 536 | 0.37 |
(31.4,36.6] | 0 | 536 | 0.00 |
(36.6,41.8] | 0 | 536 | 0.00 |
(41.8,47] | 4 | 540 | 0.74 |
Total | 540 | NA | 100.00 |
# Calcular media, moda y mediana para Accuracy
media_Accuracy <- mean(datos$Accuracy, na.rm = TRUE)
mediana_Accuracy <- median(datos$Accuracy, na.rm = TRUE)
moda <- function(x) {
uniq <- unique(na.omit(x))
uniq[which.max(tabulate(match(x, uniq)))]
}
moda_Accuracy <- moda(datos$Accuracy)
# Calcular media, moda y mediana para Precision
media_Precision <- mean(datos$Precision, na.rm = TRUE)
mediana_Precision <- median(datos$Precision, na.rm = TRUE)
moda_Precision <- moda(datos$Precision)
# Calcular media, moda y mediana para Recall
media_Recall <- mean(datos$Recall, na.rm = TRUE)
mediana_Recall <- median(datos$Recall, na.rm = TRUE)
moda_Recall <- moda(datos$Recall)
# Calcular media, moda y mediana para F1_Score
media_F1_Score <- mean(datos$F1_Score, na.rm = TRUE)
mediana_F1_Score <- median(datos$F1_Score, na.rm = TRUE)
moda_F1_Score <- moda(datos$F1_Score)
# Calcular media, moda y mediana para Training_Time
media_Training_Time <- mean(datos$Training_Time, na.rm = TRUE)
mediana_Training_Time <- median(datos$Training_Time, na.rm = TRUE)
moda_Training_Time <- moda(datos$Training_Time)
# Crear un data frame con los resultados
resultados <- data.frame(
Variable = c("Accuracy", "Precision", "Recall", "F1_Score", "Training_Time"),
Media = c(media_Accuracy, media_Precision, media_Recall, media_F1_Score, media_Training_Time),
Mediana = c(mediana_Accuracy, mediana_Precision, mediana_Recall, mediana_F1_Score, mediana_Training_Time),
Moda = c(moda_Accuracy, moda_Precision, moda_Recall, moda_F1_Score, moda_Training_Time)
)
# Mostrar la tabla utilizando kableExtra
kable(resultados, col.names = c("Variable", "Media", "Mediana", "Moda")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = F) %>%
row_spec(0, bold = TRUE, color = "white", background = "#4CAF50") %>%
row_spec(1:3, background = "#f5f5f5")
Variable | Media | Mediana | Moda |
---|---|---|---|
Accuracy | 0.8778581 | 0.7578397 | 0.6618051 |
Precision | 0.8129050 | 0.7194524 | 0.6929447 |
Recall | 0.7485760 | 0.6492793 | 0.8766533 |
F1_Score | 0.8121745 | 0.7086363 | 0.4426950 |
Training_Time | 2.9910403 | 2.4347191 | 4.9785924 |
# Accuracy
rango_accuracy <- range(datos$Accuracy, na.rm = TRUE)
varianza_accuracy <- var(datos$Accuracy, na.rm = TRUE)
sd_accuracy <- sd(datos$Accuracy, na.rm = TRUE)
cv_accuracy <- sd_accuracy / mean(datos$Accuracy, na.rm = TRUE)
# Precision
rango_precision <- range(datos$Precision, na.rm = TRUE)
varianza_precision <- var(datos$Precision, na.rm = TRUE)
sd_precision <- sd(datos$Precision, na.rm = TRUE)
cv_precision <- sd_precision / mean(datos$Precision, na.rm = TRUE)
# Recall
rango_recall <- range(datos$Recall, na.rm = TRUE)
varianza_recall <- var(datos$Recall, na.rm = TRUE)
sd_recall <- sd(datos$Recall, na.rm = TRUE)
cv_recall <- sd_recall / mean(datos$Recall, na.rm = TRUE)
# F1_Score
rango_f1 <- range(datos$F1_Score, na.rm = TRUE)
varianza_f1 <- var(datos$F1_Score, na.rm = TRUE)
sd_f1 <- sd(datos$F1_Score, na.rm = TRUE)
cv_f1 <- sd_f1 / mean(datos$F1_Score, na.rm = TRUE)
# Training Time
rango_tt <- range(datos$Training_Time, na.rm = TRUE)
varianza_tt <- var(datos$Training_Time, na.rm = TRUE)
sd_tt <- sd(datos$Training_Time, na.rm = TRUE)
cv_tt <- sd_tt / mean(datos$Training_Time, na.rm = TRUE)
# Crear el dataframe con todas las medidas
tabla_dispersion <- data.frame(
Variable = c("Accuracy", "Precision", "Recall", "F1_Score", "Training Time"),
Rango = c(paste(rango_accuracy[1], "-", rango_accuracy[2]),
paste(rango_precision[1], "-", rango_precision[2]),
paste(rango_recall[1], "-", rango_recall[2]),
paste(rango_f1[1], "-", rango_f1[2]),
paste(rango_tt[1], "-", rango_tt[2])),
Varianza = c(varianza_accuracy, varianza_precision, varianza_recall, varianza_f1, varianza_tt),
`Desviación Estándar` = c(sd_accuracy, sd_precision, sd_recall, sd_f1, sd_tt),
`Coeficiente de Variación` = c(cv_accuracy, cv_precision, cv_recall, cv_f1, cv_tt)
)
# Mostrar la tabla con kable
library(kableExtra)
tabla_dispersion %>%
kbl(caption = "Medidas de Dispersión para Variables Cuantitativas", digits = 4, align = "c") %>%
kable_styling(full_width = F, bootstrap_options = c("striped", "hover", "condensed"),
font_size = 12, position = "center") %>%
column_spec(1, bold = TRUE, background = "lightblue")
Variable | Rango | Varianza | Desviación.Estándar | Coeficiente.de.Variación |
---|---|---|---|---|
Accuracy | 0.50378143748907 - 9.718079600838 | 0.8895 | 0.9431 | 1.0743 |
Precision | 0.40193095816257 - 9.7320081190236 | 0.7250 | 0.8515 | 1.0474 |
Recall | 0.30009428510314 - 9.3661822765607 | 0.6153 | 0.7844 | 1.0479 |
F1_Score | 0.40000698085322 - 9.3740486657127 | 0.7971 | 0.8928 | 1.0993 |
Training Time | 0.10320161473037 - 46.985625752494 | 19.5704 | 4.4238 | 1.4790 |
# Calcular percentiles y cuartiles para cada variable
# Accuracy
percentiles_accuracy <- quantile(datos$Accuracy, probs = c(0.25, 0.5, 0.75), na.rm = TRUE)
# Precision
percentiles_precision <- quantile(datos$Precision, probs = c(0.25, 0.5, 0.75), na.rm = TRUE)
# Recall
percentiles_recall <- quantile(datos$Recall, probs = c(0.25, 0.5, 0.75), na.rm = TRUE)
# F1_Score
percentiles_f1 <- quantile(datos$F1_Score, probs = c(0.25, 0.5, 0.75), na.rm = TRUE)
# Training Time
percentiles_tt <- quantile(datos$Training_Time, probs = c(0.25, 0.5, 0.75), na.rm = TRUE)
# Crear el dataframe con los percentiles (Cuartiles)
tabla_posicion <- data.frame(
Variable = c("Accuracy", "Precision", "Recall", "F1_Score", "Training Time"),
Q1_25 = c(percentiles_accuracy[1], percentiles_precision[1], percentiles_recall[1], percentiles_f1[1], percentiles_tt[1]),
Q2_50 = c(percentiles_accuracy[2], percentiles_precision[2], percentiles_recall[2], percentiles_f1[2], percentiles_tt[2]), # Mediana
Q3_75 = c(percentiles_accuracy[3], percentiles_precision[3], percentiles_recall[3], percentiles_f1[3], percentiles_tt[3])
)
# Mostrar la tabla con kable
library(kableExtra)
tabla_posicion %>%
kbl(caption = "Medidas de Posición: Percentiles y Cuartiles", digits = 4, align = "c") %>%
kable_styling(full_width = F, bootstrap_options = c("striped", "hover", "condensed"),
font_size = 12, position = "center") %>%
column_spec(1, bold = TRUE, background = "lightblue")
Variable | Q1_25 | Q2_50 | Q3_75 |
---|---|---|---|
Accuracy | 0.6236 | 0.7578 | 0.8824 |
Precision | 0.5632 | 0.7195 | 0.8596 |
Recall | 0.4819 | 0.6493 | 0.8404 |
F1_Score | 0.5515 | 0.7086 | 0.8438 |
Training Time | 1.2441 | 2.4347 | 3.8131 |
# Calcular la asimetría y la curtosis para cada variable
asimetria_accuracy <- skewness(datos$Accuracy, na.rm = TRUE)
curtosis_accuracy <- kurtosis(datos$Accuracy, na.rm = TRUE)
asimetria_precision <- skewness(datos$Precision, na.rm = TRUE)
curtosis_precision <- kurtosis(datos$Precision, na.rm = TRUE)
asimetria_recall <- skewness(datos$Recall, na.rm = TRUE)
curtosis_recall <- kurtosis(datos$Recall, na.rm = TRUE)
asimetria_f1 <- skewness(datos$F1_Score, na.rm = TRUE)
curtosis_f1 <- kurtosis(datos$F1_Score, na.rm = TRUE)
asimetria_tt <- skewness(datos$Training_Time, na.rm = TRUE)
curtosis_tt <- kurtosis(datos$Training_Time, na.rm = TRUE)
tabla_forma_distribucion <- data.frame(
Variable = c("Accuracy", "Precision", "Recall", "F1_Score", "Training Time"),
Asimetría = c(asimetria_accuracy, asimetria_precision, asimetria_recall, asimetria_f1, asimetria_tt),
Curtosis = c(curtosis_accuracy, curtosis_precision, curtosis_recall, curtosis_f1, curtosis_tt)
)
library(kableExtra)
tabla_forma_distribucion %>%
kbl(caption = "Medidas de Forma de Distribución: Asimetría y Curtosis", digits = 4, align = "c") %>%
kable_styling(full_width = F, bootstrap_options = c("striped", "hover", "condensed"),
font_size = 12, position = "center") %>%
column_spec(1, bold = TRUE, background = "lightblue")
Variable | Asimetría | Curtosis |
---|---|---|
Accuracy | 7.3592 | 56.1738 |
Precision | 8.0077 | 70.3743 |
Recall | 7.3134 | 60.4005 |
F1_Score | 7.5107 | 59.9427 |
Training Time | 7.6694 | 67.7217 |
Podemos observar como la asimetría para todas las variables cuantitativas es positiva, lo que nos permite inducir que la distribución tiene una cola más larga hacia la derecha (asimetría a la derecha). En cuanto a la curtosis, siendo esta el “peso” de las colas de la distribución en comparación con una distribución normal, vemos como todo los resultados arrojados son mayor que 0, por lo que se dice que la distribución tiene curtosis de tipo leptocúrtica, esto significa que la distribución tiene colas más pesadas y es más puntiaguda en comparación con la distribución normal.
Para el análisis de las variables cuantitativas, primero se utilizará la Prueba de Shapiro-Wilk con el objetivo de evaluar si los datos de cada variable siguen una distribución normal.
# Realizar las pruebas de Shapiro-Wilk para cada variable
resultados_shapiro <- data.frame(
Variable = c("Accuracy", "Precision", "Recall", "F1_Score", "Training_Time"),
W_Statistic = c(shapiro.test(datos$Accuracy)$statistic,
shapiro.test(datos$Precision)$statistic,
shapiro.test(datos$Recall)$statistic,
shapiro.test(datos$F1_Score)$statistic,
shapiro.test(datos$Training_Time)$statistic),
p_value = c(shapiro.test(datos$Accuracy)$p.value,
shapiro.test(datos$Precision)$p.value,
shapiro.test(datos$Recall)$p.value,
shapiro.test(datos$F1_Score)$p.value,
shapiro.test(datos$Training_Time)$p.value),
Conclusion = ifelse(c(shapiro.test(datos$Accuracy)$p.value,
shapiro.test(datos$Precision)$p.value,
shapiro.test(datos$Recall)$p.value,
shapiro.test(datos$F1_Score)$p.value,
shapiro.test(datos$Training_Time)$p.value) < 0.05,
"No normal", "Normal")
)
library(kableExtra)
resultados_shapiro %>%
kbl(caption = "Resultados de la Prueba de Shapiro-Wilk", digits = 4, align = "c") %>%
kable_styling(full_width = F, bootstrap_options = c("striped", "hover", "condensed"),
font_size = 12, position = "center") %>%
column_spec(1, bold = TRUE, background = "lightblue")
Variable | W_Statistic | p_value | Conclusion |
---|---|---|---|
Accuracy | 0.2277 | 0 | No normal |
Precision | 0.2564 | 0 | No normal |
Recall | 0.3181 | 0 | No normal |
F1_Score | 0.2547 | 0 | No normal |
Training_Time | 0.3492 | 0 | No normal |
Implicaciones: -Rechazo de la Normalidad. La prueba de Shapiro-Wilk arroja un valor P igual a 0 (menor a 0.05 - valor de referencia), lo que sugiere que las diferencias entre los datos y una distribución normal son tan grandes que la probabilidad de que los datos sean normales es extremadamente baja.
HISTOGRAMAS:
# Histograma con curva de densidad para cada variable
# Accuracy
ggplot(datos, aes(x = Accuracy)) +
geom_histogram(aes(y = ..density..), binwidth = 0.05, fill = "skyblue", color = "black") +
geom_density(color = "red", size = 1.2) +
labs(title = "Distribución de Accuracy con Curva de Densidad", x = "Accuracy", y = "Densidad") +
theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(density)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning: Removed 39 rows containing non-finite outside the scale range
## (`stat_bin()`).
## Warning: Removed 39 rows containing non-finite outside the scale range
## (`stat_density()`).
# Precision
ggplot(datos, aes(x = Precision)) +
geom_histogram(aes(y = ..density..), binwidth = 0.05, fill = "lightgreen", color = "black") +
geom_density(color = "red", size = 1.2) +
labs(title = "Distribución de Precision con Curva de Densidad", x = "Precision", y = "Densidad") +
theme_minimal()
## Warning: Removed 19 rows containing non-finite outside the scale range
## (`stat_bin()`).
## Warning: Removed 19 rows containing non-finite outside the scale range
## (`stat_density()`).
# Recall
ggplot(datos, aes(x = Recall)) +
geom_histogram(aes(y = ..density..), binwidth = 0.05, fill = "lightcoral", color = "black") +
geom_density(color = "red", size = 1.2) +
labs(title = "Distribución de Recall con Curva de Densidad", x = "Recall", y = "Densidad") +
theme_minimal()
## Warning: Removed 20 rows containing non-finite outside the scale range
## (`stat_bin()`).
## Warning: Removed 20 rows containing non-finite outside the scale range
## (`stat_density()`).
# F1_Score
ggplot(datos, aes(x = F1_Score)) +
geom_histogram(aes(y = ..density..), binwidth = 0.05, fill = "lightblue", color = "black") +
geom_density(color = "red", size = 1.2) +
labs(title = "Distribución de F1_Score con Curva de Densidad", x = "F1_Score", y = "Densidad") +
theme_minimal()
## Warning: Removed 20 rows containing non-finite outside the scale range (`stat_bin()`).
## Removed 20 rows containing non-finite outside the scale range
## (`stat_density()`).
# Training Time
ggplot(datos, aes(x = Training_Time)) +
geom_histogram(aes(y = ..density..), binwidth = 0.05, fill = "orange", color = "black") +
geom_density(color = "red", size = 1.2) +
labs(title = "Distribución de Training Time con Curva de Densidad", x = "Training Time", y = "Densidad") +
theme_minimal()
## Warning: Removed 20 rows containing non-finite outside the scale range (`stat_bin()`).
## Removed 20 rows containing non-finite outside the scale range
## (`stat_density()`).
GRÁFICO DE CAJAS Y BIGOTES:
# Boxplot para cada variable
# Accuracy
ggplot(datos, aes(y = Accuracy)) +
geom_boxplot(fill = "skyblue", color = "black") +
labs(title = "Diagrama de Caja para Accuracy", y = "Accuracy") +
theme_minimal()
## Warning: Removed 39 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
# Precision
ggplot(datos, aes(y = Precision)) +
geom_boxplot(fill = "lightgreen", color = "black") +
labs(title = "Diagrama de Caja para Precision", y = "Precision") +
theme_minimal()
## Warning: Removed 19 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
# Recall
ggplot(datos, aes(y = Recall)) +
geom_boxplot(fill = "lightcoral", color = "black") +
labs(title = "Diagrama de Caja para Recall", y = "Recall") +
theme_minimal()
## Warning: Removed 20 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
# F1_Score
ggplot(datos, aes(y = F1_Score)) +
geom_boxplot(fill = "lightblue", color = "black") +
labs(title = "Diagrama de Caja para F1_Score", y = "F1_Score") +
theme_minimal()
## Warning: Removed 20 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
# Training Time
ggplot(datos, aes(y = Training_Time)) +
geom_boxplot(fill = "orange", color = "black") +
labs(title = "Diagrama de Caja para Training Time", y = "Training Time") +
theme_minimal()
## Warning: Removed 20 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
GRÁFICO Q-Q(QUANTILE-QUANTILE):
# Gráfico Q-Q para cada variable
# Accuracy
qqnorm(datos$Accuracy, main = "Gráfico Q-Q de Accuracy")
qqline(datos$Accuracy, col = "red")
# Precision
qqnorm(datos$Precision, main = "Gráfico Q-Q de Precision")
qqline(datos$Precision, col = "red")
# Recall
qqnorm(datos$Recall, main = "Gráfico Q-Q de Recall")
qqline(datos$Recall, col = "red")
# F1_Score
qqnorm(datos$F1_Score, main = "Gráfico Q-Q de F1_Score")
qqline(datos$F1_Score, col = "red")
# Training Time
qqnorm(datos$Training_Time, main = "Gráfico Q-Q de Training Time")
qqline(datos$Training_Time, col = "red")
El primer paso es analizar la cantidad de valores NA presentes en la base de datos:
#Identificar cantidad de valores NA en la base de datos
total_na <- sum(is.na(datos))
cat("Cantidad total de valores NA en la base de datos:", total_na, "\n")
## Cantidad total de valores NA en la base de datos: 118
#Identificar la cantidad de valores NA por cada columna
na_por_columna <- colSums(is.na(datos))
cat("Cantidad de valores NA por columna:\n")
## Cantidad de valores NA por columna:
print(na_por_columna)
## Algorithm Framework Problem_Type Dataset_Type Accuracy
## 0 0 0 0 39
## Precision Recall F1_Score Training_Time Date
## 19 20 20 20 0
#Identificar columnas que contienen valores NA
columnas_con_na <- names(na_por_columna[na_por_columna > 0])
cat("Columnas que contienen valores NA:", paste(columnas_con_na, collapse = ", "), "\n")
## Columnas que contienen valores NA: Accuracy, Precision, Recall, F1_Score, Training_Time
Ahora, creamos un gráficoque nos permita visualizar los valores faltantes(NA):
numeric_vars <- datos[, sapply(datos, is.numeric)]
numeric_vars_na <- numeric_vars[, colSums(is.na(numeric_vars)) > 0]
# Gráfico de agregación de NA solo para variables numéricas con valores faltantes
aggr(numeric_vars_na, numbers = TRUE, col = c("navyblue", "red"),
cex.axis = 0.7, gap = 3, ylab = c("Proporción de valores faltantes", "Patrón de faltantes"))
numeric_vars <- datos[, sapply(datos, is.numeric)]
md.pattern(numeric_vars)
## Precision Recall F1_Score Training_Time Accuracy
## 448 1 1 1 1 1 0
## 39 1 1 1 1 0 1
## 16 1 1 1 0 1 1
## 17 1 1 0 1 1 1
## 2 1 1 0 0 1 2
## 18 1 0 1 1 1 1
## 1 1 0 1 0 1 2
## 16 0 1 1 1 1 1
## 1 0 1 1 0 1 2
## 1 0 1 0 1 1 2
## 1 0 0 1 1 1 2
## 19 20 20 20 39 118
numeric_vars <- datos[, sapply(datos, is.numeric)]
gg_miss_var(numeric_vars, show_pct = TRUE)
library(Amelia)
missmap(datos_numericos,
main = "Mapa de Valores Faltantes",
col = c("black", "yellow"),
legend = TRUE)
El método PMM es ideal para variables numéricas, ya que utiliza valores observados similares a las predicciones del modelo para imputar los valores faltantes. Vamos a aplicar este método.
# Definir qué método usar para cada tipo de variable
metodos <- make.method(datos)
# Asignar 'pmm' a las variables numéricas que tienen NA
metodos[c("Accuracy", "Precision", "Recall", "F1_Score", "Training_Time")] <- "pmm"
# Verificar los métodos asignados
print(metodos)
## Algorithm Framework Problem_Type Dataset_Type Accuracy
## "" "" "" "" "pmm"
## Precision Recall F1_Score Training_Time Date
## "pmm" "pmm" "pmm" "pmm" ""
# Imputar usando PMM solo en variables numéricas
imp <- mice(datos, method = metodos, m = 5, maxit = 50, seed = 500)
##
## iter imp variable
## 1 1 Accuracy Precision Recall F1_Score Training_Time
## 1 2 Accuracy Precision Recall F1_Score Training_Time
## 1 3 Accuracy Precision Recall F1_Score Training_Time
## 1 4 Accuracy Precision Recall F1_Score Training_Time
## 1 5 Accuracy Precision Recall F1_Score Training_Time
## 2 1 Accuracy Precision Recall F1_Score Training_Time
## 2 2 Accuracy Precision Recall F1_Score Training_Time
## 2 3 Accuracy Precision Recall F1_Score Training_Time
## 2 4 Accuracy Precision Recall F1_Score Training_Time
## 2 5 Accuracy Precision Recall F1_Score Training_Time
## 3 1 Accuracy Precision Recall F1_Score Training_Time
## 3 2 Accuracy Precision Recall F1_Score Training_Time
## 3 3 Accuracy Precision Recall F1_Score Training_Time
## 3 4 Accuracy Precision Recall F1_Score Training_Time
## 3 5 Accuracy Precision Recall F1_Score Training_Time
## 4 1 Accuracy Precision Recall F1_Score Training_Time
## 4 2 Accuracy Precision Recall F1_Score Training_Time
## 4 3 Accuracy Precision Recall F1_Score Training_Time
## 4 4 Accuracy Precision Recall F1_Score Training_Time
## 4 5 Accuracy Precision Recall F1_Score Training_Time
## 5 1 Accuracy Precision Recall F1_Score Training_Time
## 5 2 Accuracy Precision Recall F1_Score Training_Time
## 5 3 Accuracy Precision Recall F1_Score Training_Time
## 5 4 Accuracy Precision Recall F1_Score Training_Time
## 5 5 Accuracy Precision Recall F1_Score Training_Time
## 6 1 Accuracy Precision Recall F1_Score Training_Time
## 6 2 Accuracy Precision Recall F1_Score Training_Time
## 6 3 Accuracy Precision Recall F1_Score Training_Time
## 6 4 Accuracy Precision Recall F1_Score Training_Time
## 6 5 Accuracy Precision Recall F1_Score Training_Time
## 7 1 Accuracy Precision Recall F1_Score Training_Time
## 7 2 Accuracy Precision Recall F1_Score Training_Time
## 7 3 Accuracy Precision Recall F1_Score Training_Time
## 7 4 Accuracy Precision Recall F1_Score Training_Time
## 7 5 Accuracy Precision Recall F1_Score Training_Time
## 8 1 Accuracy Precision Recall F1_Score Training_Time
## 8 2 Accuracy Precision Recall F1_Score Training_Time
## 8 3 Accuracy Precision Recall F1_Score Training_Time
## 8 4 Accuracy Precision Recall F1_Score Training_Time
## 8 5 Accuracy Precision Recall F1_Score Training_Time
## 9 1 Accuracy Precision Recall F1_Score Training_Time
## 9 2 Accuracy Precision Recall F1_Score Training_Time
## 9 3 Accuracy Precision Recall F1_Score Training_Time
## 9 4 Accuracy Precision Recall F1_Score Training_Time
## 9 5 Accuracy Precision Recall F1_Score Training_Time
## 10 1 Accuracy Precision Recall F1_Score Training_Time
## 10 2 Accuracy Precision Recall F1_Score Training_Time
## 10 3 Accuracy Precision Recall F1_Score Training_Time
## 10 4 Accuracy Precision Recall F1_Score Training_Time
## 10 5 Accuracy Precision Recall F1_Score Training_Time
## 11 1 Accuracy Precision Recall F1_Score Training_Time
## 11 2 Accuracy Precision Recall F1_Score Training_Time
## 11 3 Accuracy Precision Recall F1_Score Training_Time
## 11 4 Accuracy Precision Recall F1_Score Training_Time
## 11 5 Accuracy Precision Recall F1_Score Training_Time
## 12 1 Accuracy Precision Recall F1_Score Training_Time
## 12 2 Accuracy Precision Recall F1_Score Training_Time
## 12 3 Accuracy Precision Recall F1_Score Training_Time
## 12 4 Accuracy Precision Recall F1_Score Training_Time
## 12 5 Accuracy Precision Recall F1_Score Training_Time
## 13 1 Accuracy Precision Recall F1_Score Training_Time
## 13 2 Accuracy Precision Recall F1_Score Training_Time
## 13 3 Accuracy Precision Recall F1_Score Training_Time
## 13 4 Accuracy Precision Recall F1_Score Training_Time
## 13 5 Accuracy Precision Recall F1_Score Training_Time
## 14 1 Accuracy Precision Recall F1_Score Training_Time
## 14 2 Accuracy Precision Recall F1_Score Training_Time
## 14 3 Accuracy Precision Recall F1_Score Training_Time
## 14 4 Accuracy Precision Recall F1_Score Training_Time
## 14 5 Accuracy Precision Recall F1_Score Training_Time
## 15 1 Accuracy Precision Recall F1_Score Training_Time
## 15 2 Accuracy Precision Recall F1_Score Training_Time
## 15 3 Accuracy Precision Recall F1_Score Training_Time
## 15 4 Accuracy Precision Recall F1_Score Training_Time
## 15 5 Accuracy Precision Recall F1_Score Training_Time
## 16 1 Accuracy Precision Recall F1_Score Training_Time
## 16 2 Accuracy Precision Recall F1_Score Training_Time
## 16 3 Accuracy Precision Recall F1_Score Training_Time
## 16 4 Accuracy Precision Recall F1_Score Training_Time
## 16 5 Accuracy Precision Recall F1_Score Training_Time
## 17 1 Accuracy Precision Recall F1_Score Training_Time
## 17 2 Accuracy Precision Recall F1_Score Training_Time
## 17 3 Accuracy Precision Recall F1_Score Training_Time
## 17 4 Accuracy Precision Recall F1_Score Training_Time
## 17 5 Accuracy Precision Recall F1_Score Training_Time
## 18 1 Accuracy Precision Recall F1_Score Training_Time
## 18 2 Accuracy Precision Recall F1_Score Training_Time
## 18 3 Accuracy Precision Recall F1_Score Training_Time
## 18 4 Accuracy Precision Recall F1_Score Training_Time
## 18 5 Accuracy Precision Recall F1_Score Training_Time
## 19 1 Accuracy Precision Recall F1_Score Training_Time
## 19 2 Accuracy Precision Recall F1_Score Training_Time
## 19 3 Accuracy Precision Recall F1_Score Training_Time
## 19 4 Accuracy Precision Recall F1_Score Training_Time
## 19 5 Accuracy Precision Recall F1_Score Training_Time
## 20 1 Accuracy Precision Recall F1_Score Training_Time
## 20 2 Accuracy Precision Recall F1_Score Training_Time
## 20 3 Accuracy Precision Recall F1_Score Training_Time
## 20 4 Accuracy Precision Recall F1_Score Training_Time
## 20 5 Accuracy Precision Recall F1_Score Training_Time
## 21 1 Accuracy Precision Recall F1_Score Training_Time
## 21 2 Accuracy Precision Recall F1_Score Training_Time
## 21 3 Accuracy Precision Recall F1_Score Training_Time
## 21 4 Accuracy Precision Recall F1_Score Training_Time
## 21 5 Accuracy Precision Recall F1_Score Training_Time
## 22 1 Accuracy Precision Recall F1_Score Training_Time
## 22 2 Accuracy Precision Recall F1_Score Training_Time
## 22 3 Accuracy Precision Recall F1_Score Training_Time
## 22 4 Accuracy Precision Recall F1_Score Training_Time
## 22 5 Accuracy Precision Recall F1_Score Training_Time
## 23 1 Accuracy Precision Recall F1_Score Training_Time
## 23 2 Accuracy Precision Recall F1_Score Training_Time
## 23 3 Accuracy Precision Recall F1_Score Training_Time
## 23 4 Accuracy Precision Recall F1_Score Training_Time
## 23 5 Accuracy Precision Recall F1_Score Training_Time
## 24 1 Accuracy Precision Recall F1_Score Training_Time
## 24 2 Accuracy Precision Recall F1_Score Training_Time
## 24 3 Accuracy Precision Recall F1_Score Training_Time
## 24 4 Accuracy Precision Recall F1_Score Training_Time
## 24 5 Accuracy Precision Recall F1_Score Training_Time
## 25 1 Accuracy Precision Recall F1_Score Training_Time
## 25 2 Accuracy Precision Recall F1_Score Training_Time
## 25 3 Accuracy Precision Recall F1_Score Training_Time
## 25 4 Accuracy Precision Recall F1_Score Training_Time
## 25 5 Accuracy Precision Recall F1_Score Training_Time
## 26 1 Accuracy Precision Recall F1_Score Training_Time
## 26 2 Accuracy Precision Recall F1_Score Training_Time
## 26 3 Accuracy Precision Recall F1_Score Training_Time
## 26 4 Accuracy Precision Recall F1_Score Training_Time
## 26 5 Accuracy Precision Recall F1_Score Training_Time
## 27 1 Accuracy Precision Recall F1_Score Training_Time
## 27 2 Accuracy Precision Recall F1_Score Training_Time
## 27 3 Accuracy Precision Recall F1_Score Training_Time
## 27 4 Accuracy Precision Recall F1_Score Training_Time
## 27 5 Accuracy Precision Recall F1_Score Training_Time
## 28 1 Accuracy Precision Recall F1_Score Training_Time
## 28 2 Accuracy Precision Recall F1_Score Training_Time
## 28 3 Accuracy Precision Recall F1_Score Training_Time
## 28 4 Accuracy Precision Recall F1_Score Training_Time
## 28 5 Accuracy Precision Recall F1_Score Training_Time
## 29 1 Accuracy Precision Recall F1_Score Training_Time
## 29 2 Accuracy Precision Recall F1_Score Training_Time
## 29 3 Accuracy Precision Recall F1_Score Training_Time
## 29 4 Accuracy Precision Recall F1_Score Training_Time
## 29 5 Accuracy Precision Recall F1_Score Training_Time
## 30 1 Accuracy Precision Recall F1_Score Training_Time
## 30 2 Accuracy Precision Recall F1_Score Training_Time
## 30 3 Accuracy Precision Recall F1_Score Training_Time
## 30 4 Accuracy Precision Recall F1_Score Training_Time
## 30 5 Accuracy Precision Recall F1_Score Training_Time
## 31 1 Accuracy Precision Recall F1_Score Training_Time
## 31 2 Accuracy Precision Recall F1_Score Training_Time
## 31 3 Accuracy Precision Recall F1_Score Training_Time
## 31 4 Accuracy Precision Recall F1_Score Training_Time
## 31 5 Accuracy Precision Recall F1_Score Training_Time
## 32 1 Accuracy Precision Recall F1_Score Training_Time
## 32 2 Accuracy Precision Recall F1_Score Training_Time
## 32 3 Accuracy Precision Recall F1_Score Training_Time
## 32 4 Accuracy Precision Recall F1_Score Training_Time
## 32 5 Accuracy Precision Recall F1_Score Training_Time
## 33 1 Accuracy Precision Recall F1_Score Training_Time
## 33 2 Accuracy Precision Recall F1_Score Training_Time
## 33 3 Accuracy Precision Recall F1_Score Training_Time
## 33 4 Accuracy Precision Recall F1_Score Training_Time
## 33 5 Accuracy Precision Recall F1_Score Training_Time
## 34 1 Accuracy Precision Recall F1_Score Training_Time
## 34 2 Accuracy Precision Recall F1_Score Training_Time
## 34 3 Accuracy Precision Recall F1_Score Training_Time
## 34 4 Accuracy Precision Recall F1_Score Training_Time
## 34 5 Accuracy Precision Recall F1_Score Training_Time
## 35 1 Accuracy Precision Recall F1_Score Training_Time
## 35 2 Accuracy Precision Recall F1_Score Training_Time
## 35 3 Accuracy Precision Recall F1_Score Training_Time
## 35 4 Accuracy Precision Recall F1_Score Training_Time
## 35 5 Accuracy Precision Recall F1_Score Training_Time
## 36 1 Accuracy Precision Recall F1_Score Training_Time
## 36 2 Accuracy Precision Recall F1_Score Training_Time
## 36 3 Accuracy Precision Recall F1_Score Training_Time
## 36 4 Accuracy Precision Recall F1_Score Training_Time
## 36 5 Accuracy Precision Recall F1_Score Training_Time
## 37 1 Accuracy Precision Recall F1_Score Training_Time
## 37 2 Accuracy Precision Recall F1_Score Training_Time
## 37 3 Accuracy Precision Recall F1_Score Training_Time
## 37 4 Accuracy Precision Recall F1_Score Training_Time
## 37 5 Accuracy Precision Recall F1_Score Training_Time
## 38 1 Accuracy Precision Recall F1_Score Training_Time
## 38 2 Accuracy Precision Recall F1_Score Training_Time
## 38 3 Accuracy Precision Recall F1_Score Training_Time
## 38 4 Accuracy Precision Recall F1_Score Training_Time
## 38 5 Accuracy Precision Recall F1_Score Training_Time
## 39 1 Accuracy Precision Recall F1_Score Training_Time
## 39 2 Accuracy Precision Recall F1_Score Training_Time
## 39 3 Accuracy Precision Recall F1_Score Training_Time
## 39 4 Accuracy Precision Recall F1_Score Training_Time
## 39 5 Accuracy Precision Recall F1_Score Training_Time
## 40 1 Accuracy Precision Recall F1_Score Training_Time
## 40 2 Accuracy Precision Recall F1_Score Training_Time
## 40 3 Accuracy Precision Recall F1_Score Training_Time
## 40 4 Accuracy Precision Recall F1_Score Training_Time
## 40 5 Accuracy Precision Recall F1_Score Training_Time
## 41 1 Accuracy Precision Recall F1_Score Training_Time
## 41 2 Accuracy Precision Recall F1_Score Training_Time
## 41 3 Accuracy Precision Recall F1_Score Training_Time
## 41 4 Accuracy Precision Recall F1_Score Training_Time
## 41 5 Accuracy Precision Recall F1_Score Training_Time
## 42 1 Accuracy Precision Recall F1_Score Training_Time
## 42 2 Accuracy Precision Recall F1_Score Training_Time
## 42 3 Accuracy Precision Recall F1_Score Training_Time
## 42 4 Accuracy Precision Recall F1_Score Training_Time
## 42 5 Accuracy Precision Recall F1_Score Training_Time
## 43 1 Accuracy Precision Recall F1_Score Training_Time
## 43 2 Accuracy Precision Recall F1_Score Training_Time
## 43 3 Accuracy Precision Recall F1_Score Training_Time
## 43 4 Accuracy Precision Recall F1_Score Training_Time
## 43 5 Accuracy Precision Recall F1_Score Training_Time
## 44 1 Accuracy Precision Recall F1_Score Training_Time
## 44 2 Accuracy Precision Recall F1_Score Training_Time
## 44 3 Accuracy Precision Recall F1_Score Training_Time
## 44 4 Accuracy Precision Recall F1_Score Training_Time
## 44 5 Accuracy Precision Recall F1_Score Training_Time
## 45 1 Accuracy Precision Recall F1_Score Training_Time
## 45 2 Accuracy Precision Recall F1_Score Training_Time
## 45 3 Accuracy Precision Recall F1_Score Training_Time
## 45 4 Accuracy Precision Recall F1_Score Training_Time
## 45 5 Accuracy Precision Recall F1_Score Training_Time
## 46 1 Accuracy Precision Recall F1_Score Training_Time
## 46 2 Accuracy Precision Recall F1_Score Training_Time
## 46 3 Accuracy Precision Recall F1_Score Training_Time
## 46 4 Accuracy Precision Recall F1_Score Training_Time
## 46 5 Accuracy Precision Recall F1_Score Training_Time
## 47 1 Accuracy Precision Recall F1_Score Training_Time
## 47 2 Accuracy Precision Recall F1_Score Training_Time
## 47 3 Accuracy Precision Recall F1_Score Training_Time
## 47 4 Accuracy Precision Recall F1_Score Training_Time
## 47 5 Accuracy Precision Recall F1_Score Training_Time
## 48 1 Accuracy Precision Recall F1_Score Training_Time
## 48 2 Accuracy Precision Recall F1_Score Training_Time
## 48 3 Accuracy Precision Recall F1_Score Training_Time
## 48 4 Accuracy Precision Recall F1_Score Training_Time
## 48 5 Accuracy Precision Recall F1_Score Training_Time
## 49 1 Accuracy Precision Recall F1_Score Training_Time
## 49 2 Accuracy Precision Recall F1_Score Training_Time
## 49 3 Accuracy Precision Recall F1_Score Training_Time
## 49 4 Accuracy Precision Recall F1_Score Training_Time
## 49 5 Accuracy Precision Recall F1_Score Training_Time
## 50 1 Accuracy Precision Recall F1_Score Training_Time
## 50 2 Accuracy Precision Recall F1_Score Training_Time
## 50 3 Accuracy Precision Recall F1_Score Training_Time
## 50 4 Accuracy Precision Recall F1_Score Training_Time
## 50 5 Accuracy Precision Recall F1_Score Training_Time
## Warning: Number of logged events: 5
head(imp$imp) # Mostrar solo las primeras filas del resultado de la imputación
## $Algorithm
## [1] 1 2 3 4 5
## <0 rows> (o 0- extensión row.names)
##
## $Framework
## [1] 1 2 3 4 5
## <0 rows> (o 0- extensión row.names)
##
## $Problem_Type
## [1] 1 2 3 4 5
## <0 rows> (o 0- extensión row.names)
##
## $Dataset_Type
## [1] 1 2 3 4 5
## <0 rows> (o 0- extensión row.names)
##
## $Accuracy
## 1 2 3 4 5
## 9 0.5609430 0.6236155 0.6531268 0.7118691 0.8570435
## 16 0.7218751 0.6076009 0.9856975 0.7130907 0.7577980
## 30 0.9389872 0.5483382 0.9669375 0.5180802 0.6838797
## 34 0.9962418 0.9815576 0.6299066 0.5910590 0.8974048
## 45 0.8570435 9.4901527 0.6618051 0.9341363 0.9815576
## 107 0.5581832 0.7536174 0.5166016 0.7130417 0.7836561
## 116 0.7836561 0.9974332 0.6076009 0.5663579 0.7836561
## 130 0.8852037 0.5306748 0.5288903 0.9130338 0.6838797
## 138 0.8684369 0.7402535 0.9974332 0.7399694 0.6838797
## 144 0.5445622 0.7140998 0.7243468 0.5058103 0.5760124
## 146 0.7836561 0.6551810 0.8902628 0.9008640 0.8570435
## 148 0.6060224 0.9635173 0.5321045 0.7373154 0.7577980
## 159 0.7733487 0.9815576 5.9788899 0.7577980 0.7836561
## 163 0.7836561 0.5288903 0.7020702 0.8427826 0.7577980
## 164 0.6796167 0.7406721 0.8899255 0.9938928 0.7577980
## 181 0.5428291 0.5428291 0.5288903 0.8035470 0.6838797
## 187 0.5682199 0.7080770 0.6551810 0.5198094 0.7577980
## 189 0.7577980 0.6730499 0.9879369 0.5581832 0.9815576
## 194 0.5638567 0.7439270 0.6898929 0.7271887 0.5675831
## 221 0.8570435 0.5288903 0.5524651 0.7788917 0.8570435
## 224 0.5428291 0.9681061 0.8590615 0.9938928 0.8570435
## 239 0.7577980 0.8776352 0.6076009 0.7595299 0.7577980
## 245 0.9353767 0.8590615 0.8051669 0.7700060 0.7577980
## 281 0.9815576 0.8590615 5.9788899 0.8910140 0.7577980
## 285 0.6838797 0.6730499 0.9344525 0.6837672 0.7577980
## 288 0.7836561 0.5288903 0.6551810 0.5609430 0.9815576
## 302 0.9815576 0.9974332 0.5037814 0.8002972 0.6838797
## 316 0.8474755 0.9974332 0.6730499 0.9879369 0.9815576
## 335 0.9654743 0.7402535 0.6551810 0.6994114 0.7836561
## 339 0.7635207 0.9974332 0.6531268 0.7162489 0.7836561
## 367 0.6838797 0.6898929 0.6665010 0.7461389 0.8570435
## 384 0.9759059 0.7457973 0.7961752 0.7598870 0.9815576
## 415 0.7769011 0.7402535 0.8256165 0.6004668 0.6838797
## 423 0.9613786 0.9974332 0.6730499 0.7406721 0.6838797
## 427 0.6838797 0.7402535 0.5288903 0.5400574 0.6838797
## 441 0.9815576 0.5155670 0.7747648 0.7747648 0.7836561
## 471 0.9974332 0.9223916 0.7402535 0.7098637 0.7836561
## 534 0.7577980 0.9669375 0.7964754 0.5817619 0.7577980
## 550 0.9856975 0.5898416 0.6730499 0.7595409 0.7577980
##
## $Precision
## 1 2 3 4 5
## 37 0.7330510 0.9134424 0.7140345 0.7330510 0.5560947
## 126 0.7075929 0.9113583 0.6506566 0.7558266 0.7050163
## 127 0.9802760 0.8975721 0.5505800 0.8593077 0.8297940
## 168 0.7050163 0.4648155 0.6506566 0.5689127 0.9149062
## 177 0.6582564 0.9909938 0.7702399 0.6625619 0.8367636
## 236 0.6926002 0.6098219 0.6171119 0.9341548 0.6506566
## 253 0.9399000 0.6749121 0.7050163 0.4531603 0.7808028
## 289 0.9149062 0.7432292 0.5505800 0.5124472 0.6506566
## 294 0.8261457 0.7925048 0.5505800 0.4648155 0.9048685
## 310 0.7050163 0.4201682 0.9048685 0.8721420 0.9048685
## 343 0.6641941 0.6621104 0.7050163 0.6625619 0.6132958
## 410 0.7936971 0.6466126 0.9149062 0.6367456 0.8297940
## 419 0.8821621 0.4790373 0.8297940 0.8213553 0.7702399
## 439 0.6506566 0.6812608 0.6171119 0.5528024 0.9048685
## 444 0.9513559 0.7558266 0.5505800 0.4710017 0.5505800
## 483 0.7558266 0.4406010 0.7050163 0.8424142 0.5505800
## 528 0.4493030 0.4688613 0.6171119 0.9990085 0.8297940
## 540 0.6749804 0.7787845 0.7050163 0.6466126 0.5833625
## 558 0.6366858 0.9273873 0.9048685 0.4953449 0.9149062
# Completar el dataset
datos_imputados <- complete(imp)
# Mostrar los primeros valores imputados
head(datos_imputados)
## Algorithm Framework Problem_Type Dataset_Type Accuracy Precision
## 1 SVM Scikit-learn Regression Time Series 0.6618051 0.6929447
## 2 K-Means Keras Clustering Time Series 0.7443216 0.4900292
## 3 Neural Network Keras Clustering Image 0.8852037 0.5948056
## 4 SVM Keras Clustering Text 0.8416477 0.8424142
## 5 SVM Scikit-learn Regression Tabular 0.7229514 0.6856109
## 6 K-Means PyTorch Regression Image 0.6368133 0.6255330
## Recall F1_Score Training_Time Date
## 1 0.9868006 0.4426950 4.978592 2023-03-08 11:26:21
## 2 0.8766533 0.4414046 3.721428 2023-03-09 11:26:21
## 3 0.9685424 0.9644707 3.282594 2023-03-10 11:26:21
## 4 0.8748388 0.7041523 4.041629 2023-03-11 11:26:21
## 5 0.3010956 0.6456472 3.603991 2023-03-12 11:26:21
## 6 7.4548096 0.8865271 3.006475 2023-03-13 11:26:21
Crear histogramas para comparar los datos originales e imputados
# Histogramas para Accuracy
ggp1 <- ggplot(data.frame(value = datos$Accuracy), aes(x = value)) +
geom_histogram(fill = "#FBB000", color = "#F25221", alpha = 0.9, bins = 30) +
ggtitle("Datos originales de Accuracy") +
xlab("Accuracy") + ylab("Frecuencia") +
theme_minimal()
ggp2 <- ggplot(data.frame(value = datos_imputados$Accuracy), aes(x = value)) +
geom_histogram(fill = "#43B047", color = "#049CBB", alpha = 0.9, bins = 30) +
ggtitle("Imputación con PMM (Accuracy)") +
xlab("Accuracy") + ylab("Frecuencia") +
theme_minimal()
# Mostrar los gráficos lado a lado
grid.arrange(ggp1, ggp2, ncol = 2)
## Warning: Removed 39 rows containing non-finite outside the scale range
## (`stat_bin()`).
# Histogramas para Precision
ggp3 <- ggplot(data.frame(value = datos$Precision), aes(x = value)) +
geom_histogram(fill = "#FBB000", color = "#F25221", alpha = 0.9, bins = 30) +
ggtitle("Datos originales de Precision") +
xlab("Precision") + ylab("Frecuencia") +
theme_minimal()
ggp4 <- ggplot(data.frame(value = datos_imputados$Precision), aes(x = value)) +
geom_histogram(fill = "#43B047", color = "#049CBB", alpha = 0.9, bins = 30) +
ggtitle("Imputación con PMM (Precision)") +
xlab("Precision") + ylab("Frecuencia") +
theme_minimal()
# Mostrar los gráficos lado a lado
grid.arrange(ggp3, ggp4, ncol = 2)
## Warning: Removed 19 rows containing non-finite outside the scale range
## (`stat_bin()`).
# Histogramas para Recall
ggp5 <- ggplot(data.frame(value = datos$Recall), aes(x = value)) +
geom_histogram(fill = "#FBB000", color = "#F25221", alpha = 0.9, bins = 30) +
ggtitle("Datos originales de Recall") +
xlab("Recall") + ylab("Frecuencia") +
theme_minimal()
ggp6 <- ggplot(data.frame(value = datos_imputados$Recall), aes(x = value)) +
geom_histogram(fill = "#43B047", color = "#049CBB", alpha = 0.9, bins = 30) +
ggtitle("Imputación con PMM (Recall)") +
xlab("Recall") + ylab("Frecuencia") +
theme_minimal()
# Mostrar los gráficos lado a lado
grid.arrange(ggp5, ggp6, ncol = 2)
## Warning: Removed 20 rows containing non-finite outside the scale range
## (`stat_bin()`).
# Histogramas para F1_Score
ggp7 <- ggplot(data.frame(value = datos$F1_Score), aes(x = value)) +
geom_histogram(fill = "#FBB000", color = "#F25221", alpha = 0.9, bins = 30) +
ggtitle("Datos originales de F1_Score") +
xlab("F1_Score") + ylab("Frecuencia") +
theme_minimal()
ggp8 <- ggplot(data.frame(value = datos_imputados$F1_Score), aes(x = value)) +
geom_histogram(fill = "#43B047", color = "#049CBB", alpha = 0.9, bins = 30) +
ggtitle("Imputación con PMM (F1_Score)") +
xlab("F1_Score") + ylab("Frecuencia") +
theme_minimal()
# Mostrar los gráficos lado a lado
grid.arrange(ggp7, ggp8, ncol = 2)
## Warning: Removed 20 rows containing non-finite outside the scale range
## (`stat_bin()`).
# Histogramas para Training_Time
ggp9 <- ggplot(data.frame(value = datos$Training_Time), aes(x = value)) +
geom_histogram(fill = "#FBB000", color = "#F25221", alpha = 0.9, bins = 30) +
ggtitle("Datos originales de Training_Time") +
xlab("Training_Time") + ylab("Frecuencia") +
theme_minimal()
ggp10 <- ggplot(data.frame(value = datos_imputados$Training_Time), aes(x = value)) +
geom_histogram(fill = "#43B047", color = "#049CBB", alpha = 0.9, bins = 30) +
ggtitle("Imputación con PMM (Training_Time)") +
xlab("Training_Time") + ylab("Frecuencia") +
theme_minimal()
# Mostrar los gráficos lado a lado
grid.arrange(ggp9, ggp10, ncol = 2)
## Warning: Removed 20 rows containing non-finite outside the scale range
## (`stat_bin()`).
# Verificar si las imputaciones han sido completadas
colSums(is.na(datos_imputados))
## Algorithm Framework Problem_Type Dataset_Type Accuracy
## 0 0 0 0 0
## Precision Recall F1_Score Training_Time Date
## 0 0 0 0 0
# Gráfico de dispersión de Accuracy vs otras variables
xyplot(imp, Accuracy ~ Precision + Recall + F1_Score + Training_Time,
pch = 18, cex = 1, main = "Comparación de Accuracy con otras variables")
# Gráfico de dispersión de Precision vs otras variables
xyplot(imp, Precision ~ Accuracy + Recall + F1_Score + Training_Time,
pch = 18, cex = 1, main = "Comparación de Precision con otras variables")
# Gráfico de dispersión de Recall vs otras variables
xyplot(imp, Recall ~ Accuracy + Precision + F1_Score + Training_Time,
pch = 18, cex = 1, main = "Comparación de Recall con otras variables")
# Gráfico de dispersión de F1_Score vs otras variables
xyplot(imp, F1_Score ~ Accuracy + Precision + Recall + Training_Time,
pch = 18, cex = 1, main = "Comparación de F1_Score con otras variables")
# Gráfico de dispersión de Training_Time vs otras variables
xyplot(imp, Training_Time ~ Accuracy + Precision + Recall + F1_Score,
pch = 18, cex = 1, main = "Comparación de Training_Time con otras variables")
# Gráfico de densidad de los datos imputados vs observados
densityplot(imp, main = "Densidad de los Valores Imputados y Observados",
col = c("blue", "red"))
# Gráfico de convergencia de las imputaciones
plot(imp)
Carcaterización:
#Función para contar valores atípicos
contar_atipicos <- function(x) {
iqr <- IQR(x, na.rm = TRUE)
cuartil1 <- quantile(x, 0.25, na.rm = TRUE)
cuartil3 <- quantile(x, 0.75, na.rm = TRUE)
lim_inferior <- cuartil1 - 1.5 * iqr
lim_superior <- cuartil3 + 1.5 * iqr
atipicos <- x[x < lim_inferior | x > lim_superior]
return(length(atipicos))
}
#Contar valores atípicos para cada variable numérica
num_Accuracy <- contar_atipicos(datos$Accuracy)
num_Precision <- contar_atipicos(datos$Precision)
num_Recall <- contar_atipicos(datos$Recall)
num_F1_Score <- contar_atipicos(datos$F1_Score)
num_Training_Time <- contar_atipicos(datos$Training_Time)
cat("Cantidad de valores atípicos en la variable Accuracy es:", num_Accuracy, "\n")
## Cantidad de valores atípicos en la variable Accuracy es: 49
cat("Cantidad de valores atípicos en la variable Precision es:", num_Precision, "\n")
## Cantidad de valores atípicos en la variable Precision es: 29
cat("Cantidad de valores atípicos en la variable Recall es:", num_Recall, "\n")
## Cantidad de valores atípicos en la variable Recall es: 30
cat("Cantidad de valores atípicos en la variable F1_Score es:", num_F1_Score, "\n")
## Cantidad de valores atípicos en la variable F1_Score es: 30
cat("Cantidad de valores atípicos en la variable Training_Time es:", num_Training_Time, "\n")
## Cantidad de valores atípicos en la variable Training_Time es: 29
A continuación se manejan los valores atípicos, y se visualizan las distribuciones de tres variables específicas(numéricas) a través de diagramas de caja (boxplots).
par(mfrow=c(1,5))
boxplot(datos$Accuracy,main="Accuracy")
boxplot(datos$Precision,main="Precision")
boxplot(datos$Recall,main="Recall")
boxplot(datos$F1_Score,main="F1_Score")
boxplot(datos$Training_Time,main="Training_Time")
De los gráficos anteriores podemos ver que: Las cuatro variables númericas presentan valores atípicos muy altos, por lo que se les dará su respectivo tratamiento.
# Función para convertir valores atípicos a NA
convertir_atipicos_a_na <- function(x) {
iqr <- IQR(x, na.rm = TRUE)
cuartil1 <- quantile(x, 0.25, na.rm = TRUE)
cuartil3 <- quantile(x, 0.75, na.rm = TRUE)
lim_inferior <- cuartil1 - 1.5 * iqr
lim_superior <- cuartil3 + 1.5 * iqr
# Reemplazar los valores atípicos por NA
x <- ifelse(x < lim_inferior | x > lim_superior, NA, x)
return(x)
}
# Aplicar la función a las variables numéricas
datos$Accuracy <- convertir_atipicos_a_na(datos$Accuracy)
datos$Precision <- convertir_atipicos_a_na(datos$Precision)
datos$Recall <- convertir_atipicos_a_na(datos$Recall)
datos$F1_Score <- convertir_atipicos_a_na(datos$F1_Score)
datos$Training_Time <- convertir_atipicos_a_na(datos$Training_Time)
# Función para imputar los NA con la mediana
imputar_na_con_mediana <- function(x) {
x[is.na(x)] <- median(x, na.rm = TRUE)
return(x)
}
# Aplicar la función a las variables numéricas
datos$Accuracy <- imputar_na_con_mediana(datos$Accuracy)
datos$Precision <- imputar_na_con_mediana(datos$Precision)
datos$Recall <- imputar_na_con_mediana(datos$Recall)
datos$F1_Score <- imputar_na_con_mediana(datos$F1_Score)
datos$Training_Time <- imputar_na_con_mediana(datos$Training_Time)
Ahora verificamos que efectivamente ya no quedan NA´s en la base de datos y la imputación fue exitosa.
# Verificar mediante boxplots después de la imputación
par(mfrow = c(1, 5))
boxplot(datos$Accuracy, main = "Accuracy (Imputado)")
boxplot(datos$Precision, main = "Precision (Imputado)")
boxplot(datos$Recall, main = "Recall (Imputado)")
boxplot(datos$F1_Score, main = "F1_Score (Imputado)")
boxplot(datos$Training_Time, main = "Training_Time (Imputado)")
datos_numericos <- datos[, sapply(datos, is.numeric)]
missmap(datos_numericos,
main = "Mapa de Valores Faltantes",
col = c("black", "yellow"),
legend = TRUE)
##Análisis descriptivo de las variable
Vamos a generar tablas de contingencia para explorar las relaciones
entre dos pares de variables categóricas:
- Algorithm y Framework
- Problem_Type y Dataset_Type
# Tabla de contingencia entre Algorithm y Framework
tabla_algo_framework <- table(datos$Algorithm, datos$Framework)
tabla_algo_framework %>%
kbl(caption = "Tabla de Contingencia: Algorithm vs Framework") %>%
kable_styling(full_width = F, bootstrap_options = c("striped", "hover", "condensed"))
Keras | PyTorch | Scikit-learn | TensorFlow | |
---|---|---|---|---|
K-Means | 43 | 33 | 41 | 46 |
Neural Network | 32 | 33 | 28 | 42 |
Random Forest | 25 | 32 | 31 | 38 |
SVM | 24 | 37 | 34 | 41 |
ggplot(as.data.frame(tabla_algo_framework), aes(Var1, Freq, fill = Var2)) +
geom_bar(stat = "identity", position = "fill") +
scale_fill_brewer(palette = "Set2") +
labs(title = "Relación entre Algorithm y Framework",
x = "Algoritmo",
y = "Proporción dentro del Framework",
fill = "Framework") +
theme_minimal(base_size = 16) +
theme(plot.title = element_text(hjust = 0.5),
axis.text.x = element_text(angle = 45, hjust = 1))
# Tabla de contingencia entre Problem_Type y Dataset_Type
tabla_problem_dataset <- table(datos$Problem_Type, datos$Dataset_Type)
tabla_problem_dataset %>%
kbl(caption = "Tabla de Contingencia: Problem_Type vs Dataset_Type") %>%
kable_styling(full_width = F, bootstrap_options = c("striped", "hover", "condensed"))
Image | Tabular | Text | Time Series | |
---|---|---|---|---|
Classification | 56 | 33 | 44 | 42 |
Clustering | 54 | 52 | 47 | 43 |
Regression | 47 | 51 | 52 | 39 |
ggplot(as.data.frame(tabla_problem_dataset), aes(Var1, Freq, fill = Var2)) +
geom_bar(stat = "identity", position = "fill") +
scale_fill_brewer(palette = "Set3") +
labs(title = "Relación entre Problem_Type y Dataset_Type",
x = "Tipo de Problema",
y = "Proporción dentro del Tipo de Dataset",
fill = "Tipo de Dataset") +
theme_minimal(base_size = 16) +
theme(plot.title = element_text(hjust = 0.5),
axis.text.x = element_text(angle = 45, hjust = 1))
Ahora se realizarán proporciones y análisis cruzado:
# Proporciones por filas
prop_filas_algo_framework <- prop.table(tabla_algo_framework, 1) * 100
# Mostrar la tabla con formato
prop_filas_algo_framework %>%
kbl(digits = 2, caption = "Tabla 3: Proporciones por Filas entre Algoritmo y Framework (%)") %>%
kable_styling(full_width = F, bootstrap_options = c("striped", "hover", "condensed"))
Keras | PyTorch | Scikit-learn | TensorFlow | |
---|---|---|---|---|
K-Means | 26.38 | 20.25 | 25.15 | 28.22 |
Neural Network | 23.70 | 24.44 | 20.74 | 31.11 |
Random Forest | 19.84 | 25.40 | 24.60 | 30.16 |
SVM | 17.65 | 27.21 | 25.00 | 30.15 |
# Convertir la tabla de proporciones en un dataframe
prop_algo_framework_df <- as.data.frame(as.table(prop_filas_algo_framework))
# Gráfico de heatmap
ggplot(prop_algo_framework_df, aes(Var2, Var1, fill = Freq)) +
geom_tile(color = "white") +
scale_fill_gradient(low = "white", high = "steelblue") +
labs(title = "Heatmap de Proporciones entre Algoritmo y Framework",
x = "Framework",
y = "Algoritmo",
fill = "Proporción (%)") +
theme_minimal(base_size = 15) +
theme(plot.title = element_text(hjust = 0.5, size = 15, face = "bold", margin = margin(b = 20)),
axis.title.x = element_text(size = 15, margin = margin(t = 10)),
axis.title.y = element_text(size = 15, margin = margin(r = 10)),
axis.text.x = element_text(size = 12),
axis.text.y = element_text(size = 12),
legend.title = element_text(size = 15),
legend.text = element_text(size = 12))
# Proporciones por columnas
prop_columnas_problem_dataset <- prop.table(tabla_problem_dataset, 2) * 100
# Mostrar la tabla con formato
prop_columnas_problem_dataset %>%
kbl(digits = 2, caption = "Tabla 4: Proporciones por Columnas entre Tipo de Problema y Tipo de Dataset (%)") %>%
kable_styling(full_width = F, bootstrap_options = c("striped", "hover", "condensed"))
Image | Tabular | Text | Time Series | |
---|---|---|---|---|
Classification | 35.67 | 24.26 | 30.77 | 33.87 |
Clustering | 34.39 | 38.24 | 32.87 | 34.68 |
Regression | 29.94 | 37.50 | 36.36 | 31.45 |
# Convertir la tabla de proporciones en un dataframe
prop_problem_dataset_df <- as.data.frame(as.table(prop_columnas_problem_dataset))
# Gráfico de heatmap mejorado para Problem_Type vs Dataset_Type
ggplot(prop_problem_dataset_df, aes(Var2, Var1, fill = Freq)) +
geom_tile(color = "white") +
scale_fill_gradient(low = "white", high = "lightcoral") +
labs(title = "Heatmap de Proporciones entre Tipo de Problema y Tipo de Dataset",
x = "Tipo de Dataset",
y = "Tipo de Problema",
fill = "Proporción (%)") +
theme_minimal(base_size = 15) +
theme(plot.title = element_text(hjust = 0.5, size = 12, face = "bold", margin = margin(b = 20)),
axis.title.x = element_text(size = 15, margin = margin(t = 10)),
axis.title.y = element_text(size = 15, margin = margin(r = 10)),
axis.text.x = element_text(size = 12),
axis.text.y = element_text(size = 12),
legend.title = element_text(size = 15),
legend.text = element_text(size = 12))
# Gráfico de dispersión entre Precision y Recall
ggplot(datos, aes(x = Precision, y = Recall)) +
geom_point(color = "steelblue", size = 3, alpha = 0.6) +
labs(title = "Relación entre Precisión y Recall",
x = "Precisión",
y = "Recall") +
theme_minimal(base_size = 15)
# Calcular la matriz de correlación
cor_matrix <- cor(datos[, c("Accuracy", "Precision", "Recall", "Training_Time")], use = "complete.obs")
# Mostrar la matriz de correlación
print(cor_matrix)
## Accuracy Precision Recall Training_Time
## Accuracy 1.00000000 -0.10075707 0.02555252 -0.03910346
## Precision -0.10075707 1.00000000 -0.01814039 0.03632114
## Recall 0.02555252 -0.01814039 1.00000000 -0.06268609
## Training_Time -0.03910346 0.03632114 -0.06268609 1.00000000
# Transformar la matriz de correlación en un formato largo para ggplot
cor_melted <- melt(cor_matrix)
# Gráfico de correlación (heatmap)
ggplot(cor_melted, aes(x = Var1, y = Var2, fill = value)) +
geom_tile() +
scale_fill_gradient2(low = "red", high = "blue", mid = "white", midpoint = 0, limit = c(-1,1)) +
labs(title = "Matriz de Correlación",
x = "",
y = "") +
theme_minimal(base_size = 15) +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Podemos observar que los valores de correlación son muy pequeños entre
dos variables diferentes, lo que indica que las variables no están
fuertemente correlacionadas entre sí. Esto nos permite inducir que las
variables no tienen una relación lineal significativa.
Interpretación: - Valores cercanos a 1 o -1 indican una fuerte correlación positiva o negativa, respectivamente. - Valores cercanos a 0 (caso arrojado) indican una correlación débil o inexistente. En este caso, los valores de correlación están bastante cerca de 0, lo que indica que las variables cuantitativas (Accuracy, Precision, Recall, Training_Time) no están linealmente relacionadas de manera fuerte.
NOTA: Es importante destacar que el resto de las pruebas y procedimientos relacionados con el análisis de datos, tales como la identificación de valores atípicos, el resumen estadístico de las variables y las pruebas de normalidad ya fueron abordados previamente en el desarrollo del EDA.
Este análisis estará guiado a dar respuesta a la pregunta problema planteada al inicio. Dado que las variables numéricas (como el tiempo de entrenamiento y la precisión) no están normalmente distribuidas y estás relacionando variables categóricas (como el tipo de problema, algoritmo y framework), la prueba adecuada sería una prueba no paramétrica, ya que no se hacen suposiciones sobre la distribución normal de los datos.
En este caso, las pruebas adecuadas serían:
# Filtrar los datos para Random Forest y Scikit-learn
datos_filtrados <- subset(datos, Algorithm == "Random Forest" & Framework == "Scikit-learn")
# Clasificación vs Regresión
subset_1 <- subset(datos_filtrados, Problem_Type %in% c("Classification", "Regression"))
mann_whitney_test_1 <- wilcox.test(Training_Time ~ Problem_Type, data = subset_1)
# Clasificación vs Clustering
subset_2 <- subset(datos_filtrados, Problem_Type %in% c("Classification", "Clustering"))
mann_whitney_test_2 <- wilcox.test(Training_Time ~ Problem_Type, data = subset_2)
# Regresión vs Clustering
subset_3 <- subset(datos_filtrados, Problem_Type %in% c("Regression", "Clustering"))
mann_whitney_test_3 <- wilcox.test(Training_Time ~ Problem_Type, data = subset_3)
# Mostrar los resultados
print(mann_whitney_test_1)
##
## Wilcoxon rank sum exact test
##
## data: Training_Time by Problem_Type
## W = 61, p-value = 0.896
## alternative hypothesis: true location shift is not equal to 0
print(mann_whitney_test_2)
##
## Wilcoxon rank sum exact test
##
## data: Training_Time by Problem_Type
## W = 63, p-value = 0.05031
## alternative hypothesis: true location shift is not equal to 0
print(mann_whitney_test_3)
##
## Wilcoxon rank sum exact test
##
## data: Training_Time by Problem_Type
## W = 36, p-value = 0.1444
## alternative hypothesis: true location shift is not equal to 0
Clasificación vs Regresión: Interpretación: No hay diferencias significativas en el tiempo de entrenamiento entre los problemas de clasificación y regresión (p > 0.05).
Clasificación vs Clustering: Interpretación: Este resultado es casi significativo, con un p-valor muy cercano a 0.05. Esto indica que podría haber una diferencia en el tiempo de entrenamiento entre los problemas de clasificación y clustering, pero no es lo suficientemente fuerte para ser concluyente.
Regresión vs Clustering: Interpretación: No hay diferencias significativas en el tiempo de entrenamiento entre los problemas de regresión y clustering (p > 0.05).
Prueba de Correlación de Spearman
# Filtrar los datos para Random Forest y Scikit-learn
datos_filtrados <- subset(datos, Algorithm == "Random Forest" & Framework == "Scikit-learn")
# Realizar la correlación de Spearman entre Training_Time y Precision
spearman_test <- cor.test(datos_filtrados$Training_Time, datos_filtrados$Precision, method = "spearman")
# Mostrar el resultado
print(spearman_test)
##
## Spearman's rank correlation rho
##
## data: datos_filtrados$Training_Time and datos_filtrados$Precision
## S = 4668, p-value = 0.7524
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 0.05887097
Interpretación: - Coeficiente rho: Un valor de 0.0589 indica que la relación entre el tiempo de entrenamiento y la precisión es prácticamente inexistente (muy cercana a cero). - p-valor: El p-valor de 0.7524 es mayor que 0.05, lo que significa que no hay una correlación significativa entre el tiempo de entrenamiento y la precisión bajo Random Forest y Scikit-learn.
Gráfico de Comparación de Tiempos de Entrenamiento por Tipo de Problema
# Gráfico de boxplot para comparar el tiempo de entrenamiento entre los tipos de problemas
ggplot(datos_filtrados, aes(x = Problem_Type, y = Training_Time, fill = Problem_Type)) +
geom_boxplot(outlier.colour = "white", outlier.size = 2) +
labs(title = "Comparación de Tiempos de Entrenamiento por Tipo de Problema",
x = "Tipo de Problema",
y = "Tiempo de Entrenamiento (Horas)") +
theme_minimal(base_size = 15) +
theme(legend.position = "none")
El gráfico puede mostrar ciertas diferencias en la dispersión o rangos
de los tiempos de entrenamiento entre los tipos de problemas, pero estas
diferencias no son necesariamente significativas.
Gráfico de Dispersión de Training Time vs Precision
# Gráfico de dispersión para mostrar la relación entre tiempo de entrenamiento y precisión
ggplot(datos_filtrados, aes(x = Training_Time, y = Precision, color = Problem_Type)) +
geom_point(size = 3) +
geom_smooth(method = "lm", se = FALSE) + # Añadir líneas de tendencia
labs(title = "Relación entre Tiempo de Entrenamiento y Precisión",
x = "Tiempo de Entrenamiento (Horas)",
y = "Precisión") +
theme_minimal(base_size = 15)
## `geom_smooth()` using formula = 'y ~ x'
Como se puede ver, los puntos están distribuidos de manera dispersa, lo
que confirma los resultados de las pruebas estadísticas de Spearman,
donde no se encontró una correlación significativa entre el tiempo de
entrenamiento y la precisión.
Posible tendencia visual: Aunque los resultados estadísticos no muestran significancia, el gráfico podría sugerir, de manera visual, que los modelos de Clustering tienden a tener tiempos de entrenamiento más bajos con precisión más alta en general.
En este análisis exploratorio de datos, se buscó responder la pregunta clave: ¿Qué tipo de problema logra el menor tiempo de entrenamiento sin comprometer la precisión, utilizando el algoritmo Random Forest y el framework Scikit-learn?. Para abordar esta pregunta, se realizó una serie de análisis estadísticos y pruebas analíticas no paramétricas, dada la naturaleza de las variables en el conjunto de datos.
Los análisis realizados, incluidos la prueba U de Mann-Whitney y la correlación de Spearman, arrojaron resultados no concluyentes en cuanto a la relación entre el tipo de problema y las métricas de desempeño como el tiempo de entrenamiento y la precisión.
A pesar de la expectativa inicial de que ciertos tipos de problemas podrían diferir en su desempeño en términos de tiempo y precisión, los resultados indican que el tipo de problema no tiene un efecto significativo sobre el tiempo de entrenamiento ni sobre la precisión bajo Random Forest y Scikit-learn en este conjunto de datos.
Esto podría deberse a varias razones, entre esas la homogeneidad del dataset. El conjunto de datos utilizado podría no tener suficientes diferencias entre los tipos de problemas para que estas se manifiesten en el tiempo de entrenamiento o la precisión. Si los problemas fueran más diversos o si el tamaño de los datos fuera mayor, es posible que se observaran diferencias más marcadas.
Aunque no se observaron diferencias significativas entre los tiempos de entrenamiento ni la precisión de los modelos para los distintos tipos de problemas, los resultados muestran que el enfoque utilizado ofrece un rendimiento robusto y estable en general. Este análisis confirma que Random Forest, combinado con Scikit-learn, proporciona una opción confiable para abordar problemas de machine learning sin comprometer la precisión mientras se optimiza el tiempo de entrenamiento.