Carga de datos y librerías necesarias para el ejercicio

library(ggplot2) # librería para gráficar
library(class) # librería para el modelo KNN
data(iris)

Introducción al algorítmo knn

El algorítmo de vecinos mas cercanos k o knn por sus siglas en inglés es un método no-paramétrico que sirve para clasificación y regresión de datos. El método consiste en utilizar las características de los vecinos más cercanos para ejecutar una clasificación o regresión de datos. De esta manera, el modelo logra generar y predecir “clusteres” o agrupaciones de datos similares. Es un modelo útil que puede incorporar diferente esquemas de asignación de “pesos” o importancia a diferentes atributos o casos analizados. Los “pesos” determinan las distancias entre cada uno de los elementos del conjunto de datos que se evalúan.

Para este ejemplo se utilizan los datos de Iris que se incluyen en R, y es un listado de plantas plantas con datos sobre las dimensiones de su sépalo y pétalo y agrupado por especie. La “distancia” o “cercanía” entre cada uno de los ejemplares de los datos se calcula en función de las diferencias entre las dimensiones de los pétalos y sépalos. La siguiente gráfica permite visualizar como la relación entre tamaños de sépalo y pétalo pueden agrupar a las distintas especies de plantas.

data(iris) # cargar data "iris" de R
# Crear gráfica de dispersión con datos de longitud y ancho de pétalo
qplot(Petal.Length, Petal.Width, data = iris, color = Species)

Ejercicio en R con datos “IRIS”

El objetivo del modelo es predecir la especie de planta en función de las dimensiones del sépalo y pétalo. Consiste en tres pasos:

  1. Crear dataframe principal de los datos
  2. Normalizar los datos
  3. Dividir los datos en 70% para entrenar el modelo y 30% para probar el modelo
  4. Configurar el modelo
  5. Correr el modelo (entrenar y probar)
  6. Evaluar la capacidad de predicción del modelo

1. Crear dataframe “datos”

# Asignar el nombre "datos" al dataframe de "iris". Esto facilita usar el ejemplo con otros conjutos de datos con mayor facilidad.
datos <- iris

2. Normalizar los datos

Los datos generalmente se normalizan para poder. En este caso la normalización consiste en crear una función que transforme los datos de las dimensiones en una escala que se calcula del cociente del valor en cuestión menos el valor mínimo de la lista entre el rango de la lista.

# Normalizar datos
nor <-function(x) {(x -min(x))/(max(x)-min(x))}
# Aplicar la función de normalización a las columnas 1 a 4 del dataframe. La última columna se omite porque es la columna de la especie y no es numérica.
datos_norm <- as.data.frame(lapply(datos[,c(1,2,3,4)], nor))
# Crear un nuevo dataframe "datos_norm" combinando el dataframe anterior de datos normalizados con la columna 5 que corresponde a los valores de las especies
datos_norm <- cbind(datos_norm, datos[,5])

datos_norm es el datafram normalizado con el cual se entrenará y probará el modelo.

3. Generar dataframes para entrenamiento y prueba

Al tratarse de un modelo supervisado, es necesario primero realizar un entrenamiento con una parte de los datos normalizados “datos_norm”. Se toma al 70% como una muestra para “entrenar” el modelo y el 30% restante para posteriormente probar el modelo.

# Extraer el id de los valores de una muestra del 70% de los valores del dataframe
id_muestra <- sample(1:nrow(datos_norm), 0.7*nrow(datos_norm))
# Se crea un dataframe denominado "modelo_knn_train" que corresponde a un 70% muestreado al azar
modelo_knn_train <- datos_norm[id_muestra, -5]
# Se crea un dataframe denominado "modelo_knn_train" a partir del 30% restante del dataframe
modelo_knn_test <- datos_norm[-id_muestra, -5]

# NOTA: La última columna se elimina porque es "factor" al ser factor, no permite correr el modelo, además, es la columna que se va a predecir. 
# Extraer el valor real que se va a predecir. Son los valores de referencia con los cuales se evalúa la precición del modelo.
train_df <- datos_norm[id_muestra, 5]
test_df <- datos_norm[-id_muestra, 5]

4. Configurar el modelo

Primero se debe determinar un número de vecinos para hacer la prueba. Ésto se refiere a la cantidad de vecinos más cercanos de los cuales se van a extraer los datos para hacer la predicción o clasificación. Este valor se puede determinar empíricamente aunque también por convención se estima calculando la raiz cuadrada del número de observaciones disponibles para diseñar el modelo. En este caso hay 150 datos de los cuales 105 son para entrenar el modelo. Se calculan k_1 = valor redondeado hacia “abajo” de la raíz de 105, y k_2 = valor redondeado hacia “arriba” de la raíz de 105.

# Determinar dos valores para K 
k_1 <- floor(sqrt(nrow(modelo_knn_train)))
k_2 <- ceiling(sqrt(nrow(modelo_knn_train)))

5. Correr el modelo con k_1 y k_2.

Para entrenar el modelo, simplemente se corre la función knn de la librería “class” con la siguiente configuración:

Datos para entrenar: modelo_knn_train Datos para probar: modelo_knn_test k = coeficientes k_1 o k_2 cl = datos de salida train_df

Predicción de especies con un valor de k = k_1

# knn.A es el resltado de correr el modleo con k_1
knn.A <- knn(modelo_knn_train, modelo_knn_test, cl=train_df, k=k_1)
knn.A
##  [1] setosa     setosa     setosa     setosa     setosa     setosa    
##  [7] setosa     setosa     setosa     setosa     setosa     setosa    
## [13] setosa     setosa     versicolor versicolor versicolor versicolor
## [19] versicolor versicolor versicolor versicolor virginica  versicolor
## [25] versicolor versicolor versicolor versicolor versicolor virginica 
## [31] versicolor virginica  virginica  virginica  versicolor virginica 
## [37] virginica  virginica  versicolor versicolor virginica  virginica 
## [43] virginica  virginica  virginica 
## Levels: setosa versicolor virginica

Predicción de especies con un valor de k = k_2

# knn.B es el resultado de correr el modelo con k_2
knn.B <- knn(modelo_knn_train, modelo_knn_test, cl=train_df, k=k_2)
knn.B
##  [1] setosa     setosa     setosa     setosa     setosa     setosa    
##  [7] setosa     setosa     setosa     setosa     setosa     setosa    
## [13] setosa     setosa     versicolor versicolor versicolor versicolor
## [19] versicolor versicolor versicolor versicolor virginica  versicolor
## [25] versicolor versicolor versicolor versicolor versicolor virginica 
## [31] versicolor virginica  virginica  virginica  versicolor virginica 
## [37] virginica  virginica  versicolor versicolor virginica  virginica 
## [43] virginica  virginica  virginica 
## Levels: setosa versicolor virginica

6. Evaluar la capacidad de predicción del modelo

El modelo se puede probar con los datos de “iris” y generando una matriz de confusión para evaluar la efectividad del modelo para predecir la especie en función de los otros parámetros de los datos. Las siguientes tablas de confusión comparan los valores reales del datafram “test_df” con los valores predichos con k_1, “knn.A” y con k_2, “knn.B”.

confusion_A <- table(knn.A, test_df)
confusion_B <- table(knn.B, test_df)

confusion_A
##             test_df
## knn.A        setosa versicolor virginica
##   setosa         14          0         0
##   versicolor      0         14         4
##   virginica       0          1        12
confusion_B
##             test_df
## knn.B        setosa versicolor virginica
##   setosa         14          0         0
##   versicolor      0         14         4
##   virginica       0          1        12

La tasa de los errores de clasificación o “confusiones” se puede calcular dividiendo los valores predichos entre los valores reales de las matrices de confusión.

# Matriz de los valores reales
real <- table(test_df,test_df)

# Matriz de valores reales / Matriz de confusión A
precision_knn.A <- sum(diag(confusion_A))/sum(diag(real))

precision_knn.A
## [1] 0.8888889
# Matriz de valores reales / Matriz de confusión B
precision_knn.B <- sum(diag(confusion_B))/sum(diag(real))

precision_knn.B
## [1] 0.8888889

Preguntas

  1. ¿Por qué crees que no hay diferencias entre el modelo con k=10 y k=11 (knn.A y knn.B)?

  2. ¿Qué son los errores tipo I y tipo II?

  3. ¿Cuales son los errores tipo I y tipo II del resultado del ejercicio?