Implementar el modelo de máquinas de soporte vectorial (SVM) con programación R para resolver la tarea de clasificación de una condición de salud de las personas mediante predicción de anomalías de corazón evaluando la exactitud del modelo mediante la matriz de confusión.
Se cargan librerías y se descargan los datos: https://raw.githubusercontent.com/rpizarrog/Analisis-Inteligente-de-datos/main/datos/heart_2020_cleaned.csv
Los datos están relacionados con aspectos médicos y son valores categóricos y numéricos de varias variables que caracterizan el estado de salud de 319795 personas.
Se construye un modelo supervisado basado en el algoritmo de máquinas de soporte vectorial (SVM) para resolver la tarea de clasificación binaria e identificar si una persona padece del corazón o no.
Se construyen datos de entrenamiento y validación al 80% y 20% cada uno.
Primero se construye un modelo SVM de tipo lineal, segundo se construye un modelo SVM de tipo polinomial y tercero se construye un modelo SVM de tipo radial
Se construyen datos de entrenamiento y validación al 80% y 20% cada uno.
Se desarrollan los modelos de:
Regresión Logística binaria
Árbol de Clasificación tipo class
KNN Vecinos mas cercanos
SVM Lineal
SVM Polinomial
SVM Radial
Bosques aleatorios. Random Forest
Los modelo se aceptan si tienen un valor de exactitud por encima del 70%.
El método de clasificación-regresión Máquinas de Vector Soporte (Vector Support Machines, SVMs) fue desarrollado en la década de los 90, dentro de campo de la ciencia computacional.
Si bien originariamente se desarrolló como un método de clasificación binaria, su aplicación se ha extendido a problemas de clasificación múltiple y regresión. SVMs ha resultado ser uno de los mejores clasificadores para un amplio abanico de situaciones, por lo que se considera uno de los referentes dentro del ámbito de aprendizaje estadístico y machine learning. https://www.cienciadedatos.net/documentos/34_maquinas_de_vector_soporte_support_vector_machines
Las Máquinas Soporte Vectorial (SVM, del inglés Support Vector Machines) tienen su origen en los trabajos sobre la teoría del aprendizaje estadístico, inicialmente, las SVM fueron pensadas para aclarar y resolver problemas de clasificación binaria, su aplicación se ha extendido a problemas de clasificación múltiple y regresión (Castañeda 2019).
En un espacio p-dimensional, un hiperplano se define como un subespacio plano y afín de dimensiones \(p-1\). El término afín significa que el subespacio no tiene por qué pasar por el origen. En un espacio de dos dimensiones, el hiperplano es un subespacio de 1 dimensión, es decir, una recta.
SVM también puede utilizarse como un método de regresión (support vector regression o SVR). SVR sigue los mismos principios que el SVM para clasificación, con alguna diferencia en cuanto al algoritmo (se establece un margen de tolerancia para las predicciones, épsilon).
La esencia de las SVM puede ser entendida sin el uso de fórmulas, para lo cual es necesario el conocimiento de cuatro conceptos básicos: el hiperplano de separación, el hiperplano óptimo, el margen suave y la función kernel o núcleo (Cuevas, Alvarez, and Azcona 2019).
Hiperplano de separación: Las SVM poseen una gran capacidad para aprender a partir de un conjunto de N muestras experimentales denominado conjunto de entrenamiento: \((x_1,y_1),(x_2,y_2),...,(x_n,y_m)\). Donde cada muestra \((x_i,y_i)\) para \(i=1…N\) está formado por un vector de \(n\) características \(x_iϵR_n\) y a una etiqueta y \(iϵR\) que indica la clase \(±1\) a la que pertenece cada muestra.
El objetivo es encontrar la función \(f:R_n→±1\) que separe los datos en dos clases y que clasifique o pronostique correctamente nuevas muestras perteneciente al conjunto de pruebas o de validación.
En un problema linealmente separable existen muchos hiperplanos que pueden clasificar los datos, pero las SVM no hayan uno cualquiera sino el único que maximiza la distancia entre el y el dato más cercano de cada clase.
El hiperplano de separación óptimo (HSO) y margen máximo: Está definido por el margen máximo de separación entre las dos clases.
Tomando como referencia la notación de la figura del hiperplano de separación, existen dos hiperplanos que definen las muestras a ambos lados de cada clase:
\[ w∗x+b=+1 \]
y \[ w∗x+b=−1 \]
que son paralelos al HSO \[ w∗x+b=0 \]
El margen máximo está dado por la distancia entre los hiperplanos paralelos y el HSO, cuyo resultado geométrico equivale a \(2/||w||\).
El vector de pesos \(w\) contiene la ponderación de cada atributo, indicando qué tanto aportan en el proceso de clasificación o regresión.
Hiperplano óptimo significa hallar el mejor hiperplano de separación es la esencia del problema de maximización con restricciones lineales.
La expresión final del clasificador buscado finalmente sería donde el signo resultante indicará la clase a la cual pertenece un dato determinado.
Margen suave: Cuando los datos de prueba no son linealmente separables se pueden adoptar dos técnicas para resolver el problema: con optimización “margen suave” y a través de kernel.
El proceso de optimización del hiperplano en este caso incorpora un parámetro de regularización o tuning parameter \(C\), el cual controla la severidad permitida de las violaciones de las n observaciones sobre el margen e hiperplano, y a la vez, el equilibrio bias-varianza. Sin entrar en detalles matemáticos, si \(C>0\), no más de \(C\) observaciones pueden encontrarse en el lado incorrecto del hiperplano. Si \(C\) es pequeño, los márgenes serán estrechos pues muy pocas observaciones podrán estar en el lado incorrecto del mismo (esto equivale a un modelo bastante bien ajustado a los datos, el cual puede tener poco bias pero mucha varianza). Conforme se incrementa \(C\), mayor es la tolerancia a las violaciones sobre el margen, con lo que el margen será más ancho y habrá más vectores soporte (esto equivale a un modelo más flexible y con mayor bias pero menor varianza). Si \(C=0\), el clasificador es equivalente al maximal margin classifier, pues no están permitidas violaciones sobre el margen (todas las observaciones deben estar correctamente clasificadas).
En la práctica el parámetro \(C\) se elige u optimiza por validación cruzada.
Función Kernel: La mayoría de los eventos reales no son separables linealmente por lo que se dificulta la definición del HSO. La figura 2 muestra un conjunto de datos donde no pueden ser separados linealmente por un hiperplano en \(Rn\), pero si en un espacio de mayor dimensión \(Rh\)
Se presenta una imagen hiperplano lineal no lineal, siendo un representación de datos a una mayor dimensión y separación lineal de las clases en el nuevo espacio.
Cuando no existe una apropiada superficie lineal de decisión en el espacio original de los datos, se considera un mapeo del vector de entrada en un espacio de mayor dimensión \(Rh\) llamado espacio de características, que está dotado de producto escalar.
Eligiendo la transformación adecuada \(Rn→Rh\) se realiza el mapeo y se busca el HSO siguiendo lo dicho anteriormente del apartado anterior que será lineal en \(Rh\), pero representa un espacio no lineal en \(Rn\).
Este tipo de proyección hacia un espacio de característica es a través de las funciones denominadas kernels: \(K(xi,xk)=ᶲ(xi)∗ᶲ(xk)\).
Las funciones kernel permiten realizar las operaciones algebraicas en \(Rh\) de manera eficiente y sin conocer a la transformación \(ᶲ\). Así, en principio cualquier técnica de análisis multivariado para datos \(xϵRn\) que se pueda reformular en un algoritmo computacional en términos de productos escalares, se puede generalizar a los datos transformados utilizando las funciones núcleos.
Existen varias funciones kernel o núcleos, destacando las siguientes cuatro, consideradas básicas:
Kernel lineal:
\[ K(xi,xj)=xiT∗xj \]
Kernel polinomial:
\[ K(xi,xj)=(p+ΥxiT∗xj)d,Υ>0 \]
Kernel gaussiano RBF:
\[ K(xi,xj)=exp(−Υ||xi−xj||2),Υ>0 \]
Entonces: las máquinas de vectores de soporte separan los datos en diferentes clases de datos mediante el uso de un hiperplano. Este hiperplano, está respaldado por el uso de vectores de soporte. Estos vectores se utilizan para garantizar que el margen del hiperplano sea lo más grande posible. (datagio 2022).
En R, la librerías e1071 contienen los algoritmos necesarios para obtener modelos de clasificación simple, múltiple y regresión, basados en Support Vector Machines.
Existe la librería LiblineaR que contien efunciones para clasificación en el tratamiento de grandes datos.
Para este caso se utiliza la librería e1071
library(knitr) # Para ver tablas mas amigables en formato html markdown
library(ggplot2) # Gráficas
library(dplyr) # Varias operaciones
library(caret) # Para particionar datos de entranamiento y de validación
#install.packages("e1071") # Para SVM
library(e1071)
library(plotly) # Para gráficas interactivas
Cargar datos de manera local o con URL.
Se cargan dos conjuntos de datos datos1 y dato2, ambos contienen la misma información solo que el segundo es la transformación a valores numéricos de los valores categóricos de datos1.
datos_cat <- read.csv("https://raw.githubusercontent.com/rpizarrog/Machine-Learning-con-R/main/datos/heart_2020_cleaned.csv", stringsAsFactors = TRUE, encoding = "UTF-8")
datos_num <- read.csv("https://raw.githubusercontent.com/rpizarrog/Analisis-Inteligente-de-datos/main/datos/danios%20al%20corazon%20numericos%20limpios.csv", stringsAsFactors = TRUE, encoding = "UTF-8")
Son 319795 registros y 18 variables. El 80% serán datos de entrenamiento y el 20% serán datos de validación.
La variable HeartDisease es de tipo factor y tiene dos niveles “No” y “Yes”.
str(datos_cat)
## 'data.frame': 319795 obs. of 18 variables:
## $ HeartDisease : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 2 1 1 1 1 ...
## $ BMI : num 16.6 20.3 26.6 24.2 23.7 ...
## $ Smoking : Factor w/ 2 levels "No","Yes": 2 1 2 1 1 2 1 2 1 1 ...
## $ AlcoholDrinking : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 1 1 ...
## $ Stroke : Factor w/ 2 levels "No","Yes": 1 2 1 1 1 1 1 1 1 1 ...
## $ PhysicalHealth : num 3 0 20 0 28 6 15 5 0 0 ...
## $ MentalHealth : num 30 0 30 0 0 0 0 0 0 0 ...
## $ DiffWalking : Factor w/ 2 levels "No","Yes": 1 1 1 1 2 2 1 2 1 2 ...
## $ Sex : Factor w/ 2 levels "Female","Male": 1 1 2 1 1 1 1 1 1 2 ...
## $ AgeCategory : Factor w/ 13 levels "18-24","25-29",..: 8 13 10 12 5 12 11 13 13 10 ...
## $ Race : Factor w/ 6 levels "American Indian/Alaskan Native",..: 6 6 6 6 6 3 6 6 6 6 ...
## $ Diabetic : Factor w/ 4 levels "No","No, borderline diabetes",..: 3 1 3 1 1 1 1 3 2 1 ...
## $ PhysicalActivity: Factor w/ 2 levels "No","Yes": 2 2 2 1 2 1 2 1 1 2 ...
## $ GenHealth : Factor w/ 5 levels "Excellent","Fair",..: 5 5 2 3 5 2 2 3 2 3 ...
## $ SleepTime : num 5 7 8 6 8 12 4 9 5 10 ...
## $ Asthma : Factor w/ 2 levels "No","Yes": 2 1 2 1 1 1 2 2 1 1 ...
## $ KidneyDisease : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 2 1 ...
## $ SkinCancer : Factor w/ 2 levels "No","Yes": 2 1 1 2 1 1 2 1 1 1 ...
# summary(datos_cat)
str(datos_num)
## 'data.frame': 319795 obs. of 18 variables:
## $ HeartDisease : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 2 1 1 1 1 ...
## $ BMI : num 16.6 20.3 26.6 24.2 23.7 ...
## $ Smoking : int 1 2 1 2 2 1 2 1 2 2 ...
## $ AlcoholDrinking : int 2 2 2 2 2 2 2 2 2 2 ...
## $ Stroke : int 2 1 2 2 2 2 2 2 2 2 ...
## $ PhysicalHealth : int 3 0 20 0 28 6 15 5 0 0 ...
## $ MentalHealth : int 30 0 30 0 0 0 0 0 0 0 ...
## $ DiffWalking : int 2 2 2 2 1 1 2 1 2 1 ...
## $ Sex : int 1 1 2 1 1 1 1 1 1 2 ...
## $ AgeCategory : int 8 13 10 12 5 12 11 13 13 10 ...
## $ Race : int 1 1 1 1 1 2 1 1 1 1 ...
## $ Diabetic : int 1 2 1 2 2 2 2 1 3 2 ...
## $ PhysicalActivity: int 1 1 1 2 1 2 1 2 2 1 ...
## $ GenHealth : int 4 4 5 3 4 5 5 3 5 3 ...
## $ SleepTime : int 5 7 8 6 8 12 4 9 5 10 ...
## $ Asthma : int 1 2 1 2 2 2 1 1 2 2 ...
## $ KidneyDisease : int 2 2 2 2 2 2 2 2 1 2 ...
## $ SkinCancer : int 1 2 2 1 2 2 1 2 2 2 ...
# summary(datos_num)
kable(x = head(datos_cat, 10), caption = "Primeros diez registros datos con valores categóricos")
| HeartDisease | BMI | Smoking | AlcoholDrinking | Stroke | PhysicalHealth | MentalHealth | DiffWalking | Sex | AgeCategory | Race | Diabetic | PhysicalActivity | GenHealth | SleepTime | Asthma | KidneyDisease | SkinCancer |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| No | 16.60 | Yes | No | No | 3 | 30 | No | Female | 55-59 | White | Yes | Yes | Very good | 5 | Yes | No | Yes |
| No | 20.34 | No | No | Yes | 0 | 0 | No | Female | 80 or older | White | No | Yes | Very good | 7 | No | No | No |
| No | 26.58 | Yes | No | No | 20 | 30 | No | Male | 65-69 | White | Yes | Yes | Fair | 8 | Yes | No | No |
| No | 24.21 | No | No | No | 0 | 0 | No | Female | 75-79 | White | No | No | Good | 6 | No | No | Yes |
| No | 23.71 | No | No | No | 28 | 0 | Yes | Female | 40-44 | White | No | Yes | Very good | 8 | No | No | No |
| Yes | 28.87 | Yes | No | No | 6 | 0 | Yes | Female | 75-79 | Black | No | No | Fair | 12 | No | No | No |
| No | 21.63 | No | No | No | 15 | 0 | No | Female | 70-74 | White | No | Yes | Fair | 4 | Yes | No | Yes |
| No | 31.64 | Yes | No | No | 5 | 0 | Yes | Female | 80 or older | White | Yes | No | Good | 9 | Yes | No | No |
| No | 26.45 | No | No | No | 0 | 0 | No | Female | 80 or older | White | No, borderline diabetes | No | Fair | 5 | No | Yes | No |
| No | 40.69 | No | No | No | 0 | 0 | Yes | Male | 65-69 | White | No | Yes | Good | 10 | No | No | No |
kable(x = head(datos_num, 10), caption = "Primeros diez registros datos con valores categóricos")
| HeartDisease | BMI | Smoking | AlcoholDrinking | Stroke | PhysicalHealth | MentalHealth | DiffWalking | Sex | AgeCategory | Race | Diabetic | PhysicalActivity | GenHealth | SleepTime | Asthma | KidneyDisease | SkinCancer |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| No | 16.60 | 1 | 2 | 2 | 3 | 30 | 2 | 1 | 8 | 1 | 1 | 1 | 4 | 5 | 1 | 2 | 1 |
| No | 20.34 | 2 | 2 | 1 | 0 | 0 | 2 | 1 | 13 | 1 | 2 | 1 | 4 | 7 | 2 | 2 | 2 |
| No | 26.58 | 1 | 2 | 2 | 20 | 30 | 2 | 2 | 10 | 1 | 1 | 1 | 5 | 8 | 1 | 2 | 2 |
| No | 24.21 | 2 | 2 | 2 | 0 | 0 | 2 | 1 | 12 | 1 | 2 | 2 | 3 | 6 | 2 | 2 | 1 |
| No | 23.71 | 2 | 2 | 2 | 28 | 0 | 1 | 1 | 5 | 1 | 2 | 1 | 4 | 8 | 2 | 2 | 2 |
| Yes | 28.87 | 1 | 2 | 2 | 6 | 0 | 1 | 1 | 12 | 2 | 2 | 2 | 5 | 12 | 2 | 2 | 2 |
| No | 21.63 | 2 | 2 | 2 | 15 | 0 | 2 | 1 | 11 | 1 | 2 | 1 | 5 | 4 | 1 | 2 | 1 |
| No | 31.64 | 1 | 2 | 2 | 5 | 0 | 1 | 1 | 13 | 1 | 1 | 2 | 3 | 9 | 1 | 2 | 2 |
| No | 26.45 | 2 | 2 | 2 | 0 | 0 | 2 | 1 | 13 | 1 | 3 | 2 | 5 | 5 | 2 | 1 | 2 |
| No | 40.69 | 2 | 2 | 2 | 0 | 0 | 1 | 2 | 10 | 1 | 2 | 1 | 3 | 10 | 2 | 2 | 2 |
Se trabajará con el conjunto de datos datos_num por la conveniencia en el modelo.
Crear variable llamada HeartDisease01 que se utilizará en el modelo de SVM tendrá valores 0 de para no daño y 1 para daño del corazón.
#datos_num = mutate (datos_num,HeartDisease01=if_else(HeartDisease=='Yes',1,0))
Eliminar la variable HeartDisease del conjunto de datos de datos_num.
#datos_num <- select(datos_num, -HeartDisease)
Todas las variables son de entrada o variables independientes:
“BMI”: Indice de masa corporal con valores entre 12.02 y 94.85.
“Smoking”: Si la persona es fumadora o no con valores categóritos de ‘Yes’ o ‘No’. [1 | 2]
“AlcoholDrinking” : Si consume alcohol o no, con valores categóricos de ‘Yes’ o ‘No’.[1 | 2]
“Stroke”: Si padece alguna anomalía cerebrovascular, apoplejia o algo similar, con valores categóricos de ‘Yes’ o ‘No’. [1 | 2]
“PhysicalHealth” Estado físico en lo general con valores entre 0 y 30.
“MentalHealth”. Estado mental en lo general con valores entre 0 y 30.
“DiffWalking” . Que si se le dificulta caminar o tiene algún padecimiento al caminar, con valores categóritoc de ‘Yes’ o ‘No’.[1 | 2]
“Sex”: Género de la persona, con valores de ‘Female’ y ‘Male’ para distinguir al género femenino y masculino respectivamente. [1 | 2]
“AgeCategory”: Una clasificación de la edad de la persona de entre 18 y 80 años. La primera categoría con un rango de edad entre 18-24, a partir de 25 con rangos de 5 en 5 hasta la clase de 75-80 y una última categoría mayores de 80 años. [1 - 13]
“Race”. Raza u origen de la persona con valores categóricos de ‘American Indian/Alaskan Native’, ’Asian’,’Black’, ’Hispanic’, ’Other’ y’White’. [1 - 6]
“Diabetic”. Si padece o ha padecido de diabetes en cuatro condiciones siendo Yes y No para si o no: ‘No’, ‘borderline diabetes’ condición antes de detectarse diabetes tipo 2, ‘Yes’, y ‘Yes (during pregnancy)’ durante embarazo. [1 - 4]
“PhysicalActivity” que si realiza actividad física, con valores categóricos de ‘Yes’ o ‘No’. [1 | 2]
“GenHealth”: EStado general de salud de la persona con valores categóricos de ‘Excellent’, ‘Very good’, ‘Good’, ‘Fair’ y ‘Poor’ con significado en español de excelente, muy buena, buena, regular y pobre o deficiente. [1 - 5]
“SleepTime”: valor numérico de las horas de sueño u horas que duerme la persona con valores en un rango entre 1 y 24.
“Asthma”: si padece de asma o no, con valores categóricos de ‘Yes’ o ‘No’. [1 | 2].
“KidneyDisease”: si tiene algún padecimiento en los riñones, con valores categóricos de ‘Yes’ o ‘No’. [1 | 2].
“SkinCancer”: si padece algún tipo de cáncer de piel, con valores categóricos de ‘Yes’ o ‘No’. [1 | 2].
La variable de interés como dependiente o variable de salida es la de daño al corazón (HeartDisease), con valores categóricos de ‘Yes’ o ‘No’. Ahora con la variable HeartDisease01 para valores o para No daño y 1 para daño al corazón,
Se parten los datos en en datos de entrenamiento con el 80% y datos de validación con el 20%.
set.seed(2022)
entrena <- createDataPartition(y = datos_num$HeartDisease,
p = 0.8,
list = FALSE,
times = 1)
# Datos entrenamiento
datos.entrenamiento <- datos_num[entrena, ] # [renglones, columna]
# Datos validación
datos.validacion <- datos_num[-entrena, ]
Se muestran los primeros 20 registros datos de entrenamiento. Son 255,836 observaciones en datos de entrenamiento que representa el 80% del total de los datos
paste("Registros en datos de entrenamiento: ", nrow(datos.entrenamiento))
## [1] "Registros en datos de entrenamiento: 255837"
kable(head(datos.entrenamiento, 20), caption = "Primeros 20 registros de datos de entrenamiento")
| HeartDisease | BMI | Smoking | AlcoholDrinking | Stroke | PhysicalHealth | MentalHealth | DiffWalking | Sex | AgeCategory | Race | Diabetic | PhysicalActivity | GenHealth | SleepTime | Asthma | KidneyDisease | SkinCancer | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | No | 16.60 | 1 | 2 | 2 | 3 | 30 | 2 | 1 | 8 | 1 | 1 | 1 | 4 | 5 | 1 | 2 | 1 |
| 2 | No | 20.34 | 2 | 2 | 1 | 0 | 0 | 2 | 1 | 13 | 1 | 2 | 1 | 4 | 7 | 2 | 2 | 2 |
| 3 | No | 26.58 | 1 | 2 | 2 | 20 | 30 | 2 | 2 | 10 | 1 | 1 | 1 | 5 | 8 | 1 | 2 | 2 |
| 4 | No | 24.21 | 2 | 2 | 2 | 0 | 0 | 2 | 1 | 12 | 1 | 2 | 2 | 3 | 6 | 2 | 2 | 1 |
| 5 | No | 23.71 | 2 | 2 | 2 | 28 | 0 | 1 | 1 | 5 | 1 | 2 | 1 | 4 | 8 | 2 | 2 | 2 |
| 6 | Yes | 28.87 | 1 | 2 | 2 | 6 | 0 | 1 | 1 | 12 | 2 | 2 | 2 | 5 | 12 | 2 | 2 | 2 |
| 7 | No | 21.63 | 2 | 2 | 2 | 15 | 0 | 2 | 1 | 11 | 1 | 2 | 1 | 5 | 4 | 1 | 2 | 1 |
| 8 | No | 31.64 | 1 | 2 | 2 | 5 | 0 | 1 | 1 | 13 | 1 | 1 | 2 | 3 | 9 | 1 | 2 | 2 |
| 9 | No | 26.45 | 2 | 2 | 2 | 0 | 0 | 2 | 1 | 13 | 1 | 3 | 2 | 5 | 5 | 2 | 1 | 2 |
| 10 | No | 40.69 | 2 | 2 | 2 | 0 | 0 | 1 | 2 | 10 | 1 | 2 | 1 | 3 | 10 | 2 | 2 | 2 |
| 11 | Yes | 34.30 | 1 | 2 | 2 | 30 | 0 | 1 | 2 | 9 | 1 | 1 | 2 | 2 | 15 | 1 | 2 | 2 |
| 12 | No | 28.71 | 1 | 2 | 2 | 0 | 0 | 2 | 1 | 8 | 1 | 2 | 1 | 4 | 5 | 2 | 2 | 2 |
| 13 | No | 28.37 | 1 | 2 | 2 | 0 | 0 | 1 | 2 | 12 | 1 | 1 | 1 | 4 | 8 | 2 | 2 | 2 |
| 14 | No | 28.15 | 2 | 2 | 2 | 7 | 0 | 1 | 1 | 13 | 1 | 2 | 2 | 3 | 7 | 2 | 2 | 2 |
| 15 | No | 29.29 | 1 | 2 | 2 | 0 | 30 | 1 | 1 | 9 | 1 | 2 | 2 | 3 | 5 | 2 | 2 | 2 |
| 16 | No | 29.18 | 2 | 2 | 2 | 1 | 0 | 2 | 1 | 7 | 1 | 2 | 1 | 4 | 6 | 2 | 2 | 2 |
| 17 | No | 26.26 | 2 | 2 | 2 | 5 | 2 | 2 | 1 | 11 | 1 | 2 | 2 | 4 | 10 | 2 | 2 | 2 |
| 18 | No | 22.59 | 1 | 2 | 2 | 0 | 30 | 1 | 2 | 11 | 1 | 3 | 1 | 3 | 8 | 2 | 2 | 2 |
| 20 | No | 18.13 | 2 | 2 | 2 | 0 | 0 | 2 | 2 | 13 | 1 | 2 | 1 | 5 | 8 | 2 | 2 | 1 |
| 21 | No | 21.16 | 2 | 2 | 2 | 0 | 0 | 2 | 1 | 13 | 2 | 3 | 2 | 3 | 8 | 2 | 2 | 2 |
Se muestran los primeros 20 registros de datos de validación . Son 63,959 observaciones en datos de validación que representa el 20% del total de los datos
paste("Registros en datos de validación: ", nrow(datos.validacion))
## [1] "Registros en datos de validación: 63958"
kable(head(datos.validacion, 20), caption = "Primeros 20 registros de datos de validación")
| HeartDisease | BMI | Smoking | AlcoholDrinking | Stroke | PhysicalHealth | MentalHealth | DiffWalking | Sex | AgeCategory | Race | Diabetic | PhysicalActivity | GenHealth | SleepTime | Asthma | KidneyDisease | SkinCancer | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 19 | No | 29.86 | 1 | 2 | 2 | 0 | 0 | 1 | 1 | 12 | 2 | 1 | 2 | 5 | 5 | 2 | 1 | 2 |
| 25 | No | 25.75 | 2 | 2 | 2 | 0 | 0 | 2 | 1 | 13 | 1 | 2 | 1 | 4 | 6 | 2 | 2 | 1 |
| 27 | No | 34.34 | 1 | 2 | 2 | 21 | 8 | 1 | 1 | 10 | 1 | 2 | 1 | 5 | 9 | 2 | 2 | 2 |
| 30 | No | 36.58 | 2 | 2 | 2 | 0 | 0 | 2 | 1 | 9 | 1 | 1 | 2 | 3 | 5 | 2 | 2 | 1 |
| 43 | Yes | 25.06 | 2 | 2 | 2 | 0 | 0 | 1 | 1 | 13 | 1 | 1 | 2 | 3 | 7 | 2 | 2 | 1 |
| 47 | No | 33.23 | 2 | 2 | 2 | 0 | 0 | 2 | 2 | 10 | 1 | 1 | 1 | 4 | 8 | 2 | 2 | 2 |
| 48 | No | 25.11 | 2 | 2 | 2 | 5 | 5 | 2 | 1 | 10 | 2 | 2 | 1 | 3 | 7 | 2 | 2 | 2 |
| 55 | No | 32.10 | 2 | 2 | 2 | 14 | 0 | 2 | 2 | 10 | 1 | 1 | 1 | 4 | 9 | 2 | 2 | 2 |
| 60 | No | 27.20 | 1 | 2 | 1 | 0 | 0 | 2 | 2 | 13 | 1 | 2 | 2 | 4 | 8 | 2 | 2 | 1 |
| 61 | No | 28.94 | 1 | 2 | 2 | 0 | 0 | 2 | 1 | 11 | 1 | 1 | 1 | 3 | 5 | 1 | 2 | 2 |
| 62 | No | 21.03 | 2 | 2 | 2 | 1 | 0 | 2 | 1 | 13 | 1 | 2 | 1 | 5 | 8 | 2 | 2 | 2 |
| 64 | No | 31.46 | 1 | 2 | 2 | 0 | 0 | 2 | 2 | 12 | 1 | 2 | 1 | 4 | 8 | 2 | 2 | 2 |
| 72 | No | 27.76 | 1 | 2 | 2 | 15 | 0 | 1 | 1 | 13 | 1 | 2 | 2 | 3 | 8 | 1 | 2 | 2 |
| 74 | No | 30.23 | 2 | 2 | 2 | 0 | 5 | 2 | 1 | 10 | 1 | 2 | 1 | 3 | 6 | 2 | 2 | 2 |
| 79 | Yes | 28.29 | 1 | 2 | 2 | 30 | 30 | 2 | 1 | 11 | 1 | 1 | 1 | 2 | 9 | 2 | 1 | 2 |
| 89 | No | 32.81 | 1 | 2 | 2 | 0 | 0 | 1 | 1 | 11 | 1 | 1 | 1 | 3 | 5 | 2 | 2 | 2 |
| 91 | No | 44.29 | 2 | 2 | 2 | 30 | 10 | 1 | 1 | 11 | 1 | 2 | 2 | 5 | 7 | 2 | 2 | 1 |
| 93 | No | 21.80 | 1 | 2 | 2 | 0 | 0 | 2 | 1 | 12 | 1 | 2 | 1 | 4 | 8 | 2 | 2 | 1 |
| 99 | No | 24.37 | 2 | 2 | 2 | 0 | 0 | 2 | 1 | 8 | 1 | 2 | 1 | 4 | 7 | 1 | 2 | 2 |
| 111 | No | 26.63 | 2 | 2 | 2 | 0 | 0 | 2 | 1 | 12 | 2 | 1 | 1 | 3 | 8 | 2 | 2 | 2 |
Dado que la estimación del costo consume recursos de procesamiento, sobre todo tiempo, se calcula una muestra estimada al 99% y 2% de margen de error, Siendo 255836 registros en los datos de entrenamiento, la cantidad de muestra estimada debe ser 4,024 observaciones. \[ n=\frac{Z^2_{_{\alpha/2}}Npq}{e^2(N-1)+Z^2_{_{\alpha/2}}pq} \]
set.seed(2020)
n <- 4024
muestra <- sample(x = 1:nrow(datos.entrenamiento), size = n, replace = FALSE)
Se construye el modelo de SVM de tipo lineal con los datos de entrenamiento. Con el paquete e1071 se genera el modelo de SVM
A la hora de ajustar un support vector classifier, es importante tener en cuenta que el hiperparámetro C (cost) controla el equilibrio bias-varianza y la capacidad predictiva del modelo, ya que determina la severidad permitida respecto a las violaciones sobre el margen.
En otras palabras, se necesita fijar un margen de separación entre observaciones a priori. Por ello es recomendable evaluar distintos valores del mismo mediante validación cruzada y escoger el valor óptimo.
Importante: Estandarizar los predictores cuando no estén medidos en la misma escala, para que los de mayor magnitud no tengan mayor influencia que el resto. Un argumento disponible en la función svm() para ello es scale = TRUE).
Para ajustar un support vector classifier, el kernel indicado en la función svm() ha de ser lineal. Se obtiene un valor de coste óptimo mediante validación cruzada utilizando la función tune() del paquete e1071.
La expresión HeartDisease ~ . en la función tune() significa que la variable dependiente es HeartDsiease y que depende de todas las variables independientes.
Esto es similar a declarar la fórmula como HeartDsiease ~ BMI+ Smoking+ AlcoholDrinking+ Stroke+ PhysicalHealth+ MentalHealth+ DiffWalking+ Sex+ AgeCategory+ Race+ Diabetic+ PhysicalActivity+ GenHealth+ SleepTime+ Asthma+ KidneyDisease+ SkinCancer.
Se utiliza la muestra para estimar el mejor costo en el modelo.
Se toma el tiempo para procesar el mejor costo para el modelo de kernel lineal para el modelo más óptimo.
set.seed(2020)
t_inicial <- proc.time()[3]
tuning <- tune(svm, HeartDisease ~ ., data = datos.entrenamiento[muestra, ],
kernel = "linear",
ranges = list(cost = c(0.001, 0.01, 0.1, 1, 5, 10, 15, 20)),
scale = TRUE)
t_final <- proc.time()[3] - t_inicial
paste("Tiempo procesamiento con ", n, " registros, fue de:", round(t_final, 2), " segundos")
## [1] "Tiempo procesamiento con 4024 registros, fue de: 67.77 segundos"
summary(tuning)
##
## Parameter tuning of 'svm':
##
## - sampling method: 10-fold cross validation
##
## - best parameters:
## cost
## 0.001
##
## - best performance: 0.08897078
##
## - Detailed performance results:
## cost error dispersion
## 1 0.001 0.08897078 0.00872434
## 2 0.010 0.08897078 0.00872434
## 3 0.100 0.08897078 0.00872434
## 4 1.000 0.08897078 0.00872434
## 5 5.000 0.08897078 0.00872434
## 6 10.000 0.08897078 0.00872434
## 7 15.000 0.08897078 0.00872434
## 8 20.000 0.08897078 0.00872434
Para esta muestra del conjunto de datos de entrenamiento, el mejor valor de costo es 0.001 que se debe utilizar al momento de construir el modelo de SVM.
plot_ly(x = tuning$performances$cost, y = tuning$performances$error, type = 'scatter', mode = 'lines')
modelo_kl <- tuning$best.model
summary(modelo_kl)
##
## Call:
## best.tune(METHOD = svm, train.x = HeartDisease ~ ., data = datos.entrenamiento[muestra,
## ], ranges = list(cost = c(0.001, 0.01, 0.1, 1, 5, 10, 15, 20)),
## kernel = "linear", scale = TRUE)
##
##
## Parameters:
## SVM-Type: C-classification
## SVM-Kernel: linear
## cost: 0.001
##
## Number of Support Vectors: 726
##
## ( 368 358 )
##
##
## Number of Classes: 2
##
## Levels:
## No Yes
Se construye el modelo con la muestra de los datos de entrenamiento igual al modelo óptimo sugerido con costo igual 0.001 que se obtiene de la variable “tuning$performances$cost”
mejor_costo <- as.numeric(tuning$best.parameters)
paste ("Mejor costo", mejor_costo)
## [1] "Mejor costo 0.001"
modelo.klin <- svm(HeartDisease ~ ., data = datos.entrenamiento[muestra, ], kernel = "linear", cost = mejor_costo
, scale = TRUE)
summary(modelo.klin)
##
## Call:
## svm(formula = HeartDisease ~ ., data = datos.entrenamiento[muestra,
## ], kernel = "linear", cost = mejor_costo, scale = TRUE)
##
##
## Parameters:
## SVM-Type: C-classification
## SVM-Kernel: linear
## cost: 0.001
##
## Number of Support Vectors: 726
##
## ( 368 358 )
##
##
## Number of Classes: 2
##
## Levels:
## No Yes
predicciones <- predict(object = modelo.klin, datos.validacion)
datos.comparar <- data.frame("real" = datos.validacion$HeartDisease, "predicho" = predicciones)
kable(head(datos.comparar, 20), caption = "Datos a comparar previo a matriz de confusión" )
| real | predicho | |
|---|---|---|
| 19 | No | No |
| 25 | No | No |
| 27 | No | No |
| 30 | No | No |
| 43 | Yes | No |
| 47 | No | No |
| 48 | No | No |
| 55 | No | No |
| 60 | No | No |
| 61 | No | No |
| 62 | No | No |
| 64 | No | No |
| 72 | No | No |
| 74 | No | No |
| 79 | Yes | No |
| 89 | No | No |
| 91 | No | No |
| 93 | No | No |
| 99 | No | No |
| 111 | No | No |
matriz <- confusionMatrix(datos.comparar$real, datos.comparar$predicho)
matriz
## Confusion Matrix and Statistics
##
## Reference
## Prediction No Yes
## No 58484 0
## Yes 5474 0
##
## Accuracy : 0.9144
## 95% CI : (0.9122, 0.9166)
## No Information Rate : 1
## P-Value [Acc > NIR] : 1
##
## Kappa : 0
##
## Mcnemar's Test P-Value : <2e-16
##
## Sensitivity : 0.9144
## Specificity : NA
## Pos Pred Value : NA
## Neg Pred Value : NA
## Prevalence : 1.0000
## Detection Rate : 0.9144
## Detection Prevalence : 0.9144
## Balanced Accuracy : NA
##
## 'Positive' Class : No
##
Se tiene un valor de accuracy = exactitud de 0.9144 o de \(91.44\%\) que significa que el modelo le atina en la predicción o clasificación aproximadamente al 91% de cada 100 casos procesados.
Se crea un registro de una persona con ciertas condiciones de salud.
# HeartDisease = 'No'
BMI <- 38
Smoking <- 1 # 'Yes'
AlcoholDrinking = 1 # 'Yes'
Stroke <- 1 # 'Yes'
PhysicalHealth <- 2
MentalHealth <- 5
DiffWalking <- 1 # 'Yes'
Sex = 2 # 'Male
AgeCategory = 11 # '70-74'
Race = 2 # 'Black'
Diabetic <- 1 # 'Yes'
PhysicalActivity = 2 # 'No'
GenHealth = 1 # "Fair"
SleepTime = 12
Asthma = 1 # 'Yes'
KidneyDisease = 1 # 'Yes'
SkinCancer = 2 # 'No'
persona <- data.frame(BMI,Smoking, AlcoholDrinking, Stroke, PhysicalHealth, MentalHealth, DiffWalking, Sex, AgeCategory, Race, Diabetic, PhysicalActivity, GenHealth, SleepTime, Asthma, KidneyDisease, SkinCancer)
persona
## BMI Smoking AlcoholDrinking Stroke PhysicalHealth MentalHealth DiffWalking
## 1 38 1 1 1 2 5 1
## Sex AgeCategory Race Diabetic PhysicalActivity GenHealth SleepTime Asthma
## 1 2 11 2 1 2 1 12 1
## KidneyDisease SkinCancer
## 1 1 2
La predicción a la condición de la persona es:
prediccion <- predict(object = modelo.klin, newdata = persona)
prediccion
## 1
## No
## Levels: No Yes
‘No’: No tiene daño al corazón
Se construye el modelo de SVM de tipo polinomial con los datos de entrenamiento.
Se toma el tiempo para procesar el mejor costo para el modelo de kernel polinomial para el modelo más óptimo.
set.seed(2020)
t_inicial <- proc.time()[3]
tuning <- tune(svm, HeartDisease ~ ., data = datos.entrenamiento[muestra, ],
kernel = "polynomial",
ranges = list(cost = c(0.001, 0.01, 0.1, 1, 5, 10, 15, 20)),
scale = TRUE)
t_final <- proc.time()[3] - t_inicial
paste("Tiempo procesamiento con ", n, " registros, fue de:", round(t_final, 2), " segundos")
## [1] "Tiempo procesamiento con 4024 registros, fue de: 68.11 segundos"
summary(tuning)
##
## Parameter tuning of 'svm':
##
## - sampling method: 10-fold cross validation
##
## - best parameters:
## cost
## 0.001
##
## - best performance: 0.08897078
##
## - Detailed performance results:
## cost error dispersion
## 1 0.001 0.08897078 0.008724340
## 2 0.010 0.08897140 0.008408707
## 3 0.100 0.09021209 0.007818247
## 4 1.000 0.09940187 0.009273822
## 5 5.000 0.11431182 0.008579982
## 6 10.000 0.11729751 0.005865367
## 7 15.000 0.12226769 0.007321671
## 8 20.000 0.12624162 0.007181867
Para esta muestra del conjunto de datos de entrenamiento, el mejor valor de costo es 0.001 que se debe utilizar al momento de construir el modelo polinomial de SVM.
plot_ly(x = tuning$performances$cost, y = tuning$performances$error, type = 'scatter', mode = 'lines')
modelo_kp <- tuning$best.model
summary(modelo_kp)
##
## Call:
## best.tune(METHOD = svm, train.x = HeartDisease ~ ., data = datos.entrenamiento[muestra,
## ], ranges = list(cost = c(0.001, 0.01, 0.1, 1, 5, 10, 15, 20)),
## kernel = "polynomial", scale = TRUE)
##
##
## Parameters:
## SVM-Type: C-classification
## SVM-Kernel: polynomial
## cost: 0.001
## degree: 3
## coef.0: 0
##
## Number of Support Vectors: 869
##
## ( 511 358 )
##
##
## Number of Classes: 2
##
## Levels:
## No Yes
Se construye el modelo con la muestra de los datos de entrenamiento igual al modelo óptimo sugerido con costo igual 0.001 que se obtiene de la variable “tuning$performances$cost”
mejor_costo <- as.numeric(tuning$best.parameters)
paste ("Mejor costo", mejor_costo)
## [1] "Mejor costo 0.001"
modelo.kpoly <- svm(HeartDisease ~ ., data = datos.entrenamiento[muestra, ], kernel = "polynomial", cost = mejor_costo
, scale = TRUE)
summary(modelo.kpoly)
##
## Call:
## svm(formula = HeartDisease ~ ., data = datos.entrenamiento[muestra,
## ], kernel = "polynomial", cost = mejor_costo, scale = TRUE)
##
##
## Parameters:
## SVM-Type: C-classification
## SVM-Kernel: polynomial
## cost: 0.001
## degree: 3
## coef.0: 0
##
## Number of Support Vectors: 869
##
## ( 511 358 )
##
##
## Number of Classes: 2
##
## Levels:
## No Yes
predicciones <- predict(object = modelo.kpoly, datos.validacion)
datos.comparar <- data.frame("real" = datos.validacion$HeartDisease, "predicho" = predicciones)
kable(head(datos.comparar, 20), caption = "Datos a comparar previo a matriz de confusión" )
| real | predicho | |
|---|---|---|
| 19 | No | No |
| 25 | No | No |
| 27 | No | No |
| 30 | No | No |
| 43 | Yes | No |
| 47 | No | No |
| 48 | No | No |
| 55 | No | No |
| 60 | No | No |
| 61 | No | No |
| 62 | No | No |
| 64 | No | No |
| 72 | No | No |
| 74 | No | No |
| 79 | Yes | No |
| 89 | No | No |
| 91 | No | No |
| 93 | No | No |
| 99 | No | No |
| 111 | No | No |
matriz <- confusionMatrix(datos.comparar$real, datos.comparar$predicho)
matriz
## Confusion Matrix and Statistics
##
## Reference
## Prediction No Yes
## No 58484 0
## Yes 5474 0
##
## Accuracy : 0.9144
## 95% CI : (0.9122, 0.9166)
## No Information Rate : 1
## P-Value [Acc > NIR] : 1
##
## Kappa : 0
##
## Mcnemar's Test P-Value : <2e-16
##
## Sensitivity : 0.9144
## Specificity : NA
## Pos Pred Value : NA
## Neg Pred Value : NA
## Prevalence : 1.0000
## Detection Rate : 0.9144
## Detection Prevalence : 0.9144
## Balanced Accuracy : NA
##
## 'Positive' Class : No
##
Se tiene un valor de accuracy = exactitud de 0.9144 o de \(91.44\%\) que significa que el modelo le atina en la predicción o clasificación aproximadamente al 91% de cada 100 casos procesados.
Se utiliza el mismo registro de una persona con ciertas condiciones de salud para predecir con el modelo polinomial de SVM
# HeartDisease = 'No'
persona
## BMI Smoking AlcoholDrinking Stroke PhysicalHealth MentalHealth DiffWalking
## 1 38 1 1 1 2 5 1
## Sex AgeCategory Race Diabetic PhysicalActivity GenHealth SleepTime Asthma
## 1 2 11 2 1 2 1 12 1
## KidneyDisease SkinCancer
## 1 1 2
La predicción a la condición de la persona es:
prediccion <- predict(object = modelo.kpoly, newdata = persona)
prediccion
## 1
## No
## Levels: No Yes
‘No’: No tiene daño al corazón
Se construye el modelo de SVM de tipo radial con los datos de entrenamiento.
Se toma el tiempo para procesar el mejor costo para el modelo de kernel radial para el modelo más óptimo.
set.seed(2020)
t_inicial <- proc.time()[3]
tuning <- tune(svm, HeartDisease ~ ., data = datos.entrenamiento[muestra, ],
kernel = "radial",
ranges = list(cost = c(0.001, 0.01, 0.1, 1, 5, 10, 15, 20)),
scale = TRUE)
t_final <- proc.time()[3] - t_inicial
paste("Tiempo procesamiento con ", n, " registros, fue de:", round(t_final, 2), " segundos")
## [1] "Tiempo procesamiento con 4024 registros, fue de: 129.64 segundos"
summary(tuning)
##
## Parameter tuning of 'svm':
##
## - sampling method: 10-fold cross validation
##
## - best parameters:
## cost
## 1
##
## - best performance: 0.08872141
##
## - Detailed performance results:
## cost error dispersion
## 1 0.001 0.08897078 0.008724340
## 2 0.010 0.08897078 0.008724340
## 3 0.100 0.08897078 0.008724340
## 4 1.000 0.08872141 0.008166980
## 5 5.000 0.09766614 0.006345307
## 6 10.000 0.10238448 0.007553249
## 7 15.000 0.10412639 0.007276662
## 8 20.000 0.10586768 0.008499833
Para esta muestra del conjunto de datos de entrenamiento, el mejor valor de costo es 1 que se debe utilizar al momento de construir el modelo radial de SVM.
plot_ly(x = tuning$performances$cost, y = tuning$performances$error, type = 'scatter', mode = 'lines')
modelo_kr <- tuning$best.model
summary(modelo_kr)
##
## Call:
## best.tune(METHOD = svm, train.x = HeartDisease ~ ., data = datos.entrenamiento[muestra,
## ], ranges = list(cost = c(0.001, 0.01, 0.1, 1, 5, 10, 15, 20)),
## kernel = "radial", scale = TRUE)
##
##
## Parameters:
## SVM-Type: C-classification
## SVM-Kernel: radial
## cost: 1
##
## Number of Support Vectors: 1176
##
## ( 818 358 )
##
##
## Number of Classes: 2
##
## Levels:
## No Yes
Se construye el modelo con la muestra de los datos de entrenamiento igual al modelo óptimo sugerido con costo igual 0.001 que se obtiene de la variable “tuning$performances$cost”
mejor_costo <- as.numeric(tuning$best.parameters)
paste ("Mejor costo", mejor_costo)
## [1] "Mejor costo 1"
modelo.kradial <- svm(HeartDisease ~ ., data = datos.entrenamiento[muestra, ], kernel = "radial", cost = mejor_costo
, scale = TRUE)
summary(modelo.kradial)
##
## Call:
## svm(formula = HeartDisease ~ ., data = datos.entrenamiento[muestra,
## ], kernel = "radial", cost = mejor_costo, scale = TRUE)
##
##
## Parameters:
## SVM-Type: C-classification
## SVM-Kernel: radial
## cost: 1
##
## Number of Support Vectors: 1176
##
## ( 818 358 )
##
##
## Number of Classes: 2
##
## Levels:
## No Yes
predicciones <- predict(object = modelo.kradial, datos.validacion)
datos.comparar <- data.frame("real" = datos.validacion$HeartDisease, "predicho" = predicciones)
kable(head(datos.comparar, 20), caption = "Datos a comparar previo a matriz de confusión" )
| real | predicho | |
|---|---|---|
| 19 | No | No |
| 25 | No | No |
| 27 | No | No |
| 30 | No | No |
| 43 | Yes | No |
| 47 | No | No |
| 48 | No | No |
| 55 | No | No |
| 60 | No | No |
| 61 | No | No |
| 62 | No | No |
| 64 | No | No |
| 72 | No | No |
| 74 | No | No |
| 79 | Yes | No |
| 89 | No | No |
| 91 | No | No |
| 93 | No | No |
| 99 | No | No |
| 111 | No | No |
matriz <- confusionMatrix(datos.comparar$real, datos.comparar$predicho)
matriz
## Confusion Matrix and Statistics
##
## Reference
## Prediction No Yes
## No 58303 181
## Yes 5317 157
##
## Accuracy : 0.914
## 95% CI : (0.9118, 0.9162)
## No Information Rate : 0.9947
## P-Value [Acc > NIR] : 1
##
## Kappa : 0.0445
##
## Mcnemar's Test P-Value : <2e-16
##
## Sensitivity : 0.91643
## Specificity : 0.46450
## Pos Pred Value : 0.99691
## Neg Pred Value : 0.02868
## Prevalence : 0.99472
## Detection Rate : 0.91158
## Detection Prevalence : 0.91441
## Balanced Accuracy : 0.69046
##
## 'Positive' Class : No
##
Se tiene un valor de accuracy = exactitud de 0.914 o de \(91.4\%\) que significa que el modelo le atina en la predicción o clasificación aproximadamente al 91% de cada 100 casos procesados.
Se utiliza el mismo registro de una persona con ciertas condiciones de salud para predecir con el modelo radial de SVM
persona
## BMI Smoking AlcoholDrinking Stroke PhysicalHealth MentalHealth DiffWalking
## 1 38 1 1 1 2 5 1
## Sex AgeCategory Race Diabetic PhysicalActivity GenHealth SleepTime Asthma
## 1 2 11 2 1 2 1 12 1
## KidneyDisease SkinCancer
## 1 1 2
La predicción a la condición de la persona es:
prediccion <- predict(object = modelo.kpoly, newdata = persona)
prediccion
## 1
## No
## Levels: No Yes
‘No’: No tiene daño al corazón
Se construyeron tres modelos de clasificación con el algoritmo de máquinas de soporte vectorial.
Para construir los modelo se trabajó con una muestra al 99% de confianza con un margen de error del 2% de los datos de entrenamiento; esto se hizo porque el tiempo de procesamiento con todos los registros de los datos de entrenamiento era muy tardado, razón por la cual se utilizó una muestra de 4,024 registros en lugar de las 255,877 observaciones.
Los tres modelos fueron del tipo lineal, polinomial y radial.
En todos los casos el valor de la exactitud accuracy y de acuerdo a la matriz de confusión fue de aproximadamente del 91.4% que significa que el modelo le atina aproximadamente a 91 de cada 100 registros.
No existe una contundente diferencia entre los tres modelos en cuanto al estadístico accuracy, además los tres predicen No daño al corazón de una persona con ciertas condiciones de salud.
Por otra parte existen otros paquete que son alternativos para construir modelos de SVM, ver: https://rubenfcasal.github.io/aprendizaje_estadistico/svm-con-el-paquete-kernlab.html