Escudo de la República de Colombia Escudo de la República de Colombia
Menú
Logo FCE Blanco

Panel de Accesibilidad

 

¿Qué es Machine Learning?

El Machine Learning (ML) se considera como una rama de la inteligencia artificial, que busca dar a los computadores la capacidad de aprender, dicho aprendizaje se da a través del análisis de los datos por medio de algoritmos que estudian la estructura de los datos y diferencian el “ruido”, con el fin de predecir su comportamiento. Lo central en ML es la observación de los datos, el aprendizaje de ellos y la automatización de procesos de reconocimiento (Conways & Myles, 2012).Algunos ejemplos del  uso de ML son los buscadores como Google, Youtube, Netflix, los cuales hacen recomendaciones basándose en búsquedas pasadas.

Se presenta dos tipos de aprendizaje: supervisado y no supervisado. El aprendizaje supervisado se caracteriza por tener una experiencia o conocimiento previo por medio de cual se comparan etiquetas reales con predichas, aquì los modelos màs comunes son los de clasificación y regresión. Por otro lado, en aprendizaje no supervisado no hay etiquetas con las cuales comparar, aquì se trata de buscar estructuras o patrones en los datos, los modelos más conocidos son cluster, K-vecinos más cercanos (KNN) y el análisis de componentes principales (ACP).

En el siguiente diagrama se explica el procedimiento que se lleva a cabo al momento de hacer modelos concernientes a Machine Learning.

Tratamiento incial de los datos.

Antes de iniciar con los diferentes modelos de Machine Learning, es importante conocer, explorar y tratar los datos, para ello R cuenta con diferentes funciones que serán explicadas a continuación. Para esta sección se trabajará con la base de datos iris, la cual se encuentra en R.

La exploración de los datos se hace en tres pasos. El primero de ellos es comprobar la distribución de las variables individuales; esto es para conocer la distribución de cada variable y verificar los valores faltantes y atípicos, así se puede saber si las variables necesitan alguna transformación o si deben ser excluidas del modelo. El segundo paso es ver la relación entre las variables dependientes (etiquetas) y  variables independientes (predictoras). El último paso es verificar la relación entre las predictoras, con el fin de poder eliminar aquellas variables redundantes.

Uno de los primeros pasos en la exploración de los datos se encamina en conocer el número de observaciones y variables. Pero lo primero que haremos será visualizar la base de datos con la función View().

 >View(iris)

La estructura y las dimensiones las podremos observar con las funciones str() y dim() de la siguiente manera:

 >str(iris)
'data.frame': 150 obs. of  5 variables:
$ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
$ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
$ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
$ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
 
 >dim(iris)
[1] 150   5

Las funciones anteriores nos arrojan el número de variables (5) y observaciones (150) de la base de datos, además nos dicen que los datos dentro las variables Sepal.Length, Sepal.Width, Petal.Length y Petal.Width son  de tipo numérico; mientras que Species es una variable de tipo factor con 3 niveles: setosa, versicolor y virginica.

Adicionalmente con la función names() se pueden ver los nombres de las variables contenidas en la base.

 >names(iris)
[1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width" "Species"

Se pueden observar tanto la primera como última observación de la base con las funciones head() y tail() respectivamente.

 >head(iris,1)
          Sepal.Length   Sepal.Width    Petal.Length     Petal.Width     Species
1                         5.1                    3.5                    1.4                     0.2       setosa

 

 >tail(iris,1)
             Sepal.Length     Sepal.Width      Petal.Length     Petal.Width       Species
150                       5.9                         3                       5.1                    1.8       virginica

Si se desea tener un resumen más general, esto es posible con la función summary(), la cual nos arroja datos como mínimo, media, mediana, máximo, primer y tercer cuartil.

 >summary(iris)
   Sepal.Length        Sepal.Width          Petal.Length         Petal.Width                 Species
   Min.   :4.300          Min. :2.000           Min. :1.000        Min.   :0.100            setosa :50
 1st Qu.:5.100      1st Qu.:2.800       1st Qu.:1.600      1st Qu.:0.300      versicolor:50
Median :5.800    Median :3.000      Median :4.350     Median :1.300        virginica :50
 Mean   :5.843        Mean :3.057         Mean :3.758       Mean   :1.199
3rd Qu.:6.400      3rd Qu.:3.300      3rd Qu.:5.100      3rd Qu.:1.800
  Max.   :7.900         Max. :4.400          Max. :6.900        Max.   :2.500

 Luego de conocer de qué se trata la base de datos, es importante analizar la distribución de los datos, de tipo numérico, con la función var() y con la creación de gráficos.

> var(iris$Sepal.Width)
[1] 0.1899794

> var(iris$Sepal.Length)
[1] 0.6856935

> var(iris$Petal.Length)
[1] 3.116278

> var(iris$Petal.Width)
[1] 0.5810063

 El gráfico más utilizado para ver el tipo de distribución de los datos es el histograma, cuya función es hist(). En la siguiente línea se muestra el histograma de Sepal.Length.

 >hist(iris$Sepal.Length, main = "Histograma de Sepal.Length")

 >plot(density(iris$Sepal.Length), main = "Grafico de densidad Sepal.Length")

 En cuanto a los datos de tipo categórico, el análisis se puede hacer con un gráfico de pastel o barras. Las funciones para dichos gráficos son pie() y barplot() respectivamente. Pero para poder usar dicha función lo ideal es primero crear una tabla de frecuencias con la función table().

 >table(iris$Species)
setosa           versicolor          virginica
       50                        50                    50

 

 >pie(table(iris$Species), col = rainbow(10))

 >barplot(table(iris$Species), col = rainbow(10), main = "Especies")

 Con el fin de ver las posibles relaciones entre las variables se hace uso de la función cov() y corr(), con las cuales se calculan las matrices de covarianza y correlación respectivamente.

 >cov(iris[,1:4])

 >cor(iris[,1:4])

La correlación también se puede observar de manera gráfica con la siguiente función.

 >install.packages("ggvis")
>library(ggvis)
>iris %>% ggvis(~Sepal.Length, ~Sepal.Width, fill = ~Species) %>% layer_points()

En el gráfico anterior se puede observar que existe una correlación positiva entre el ancho y largo del sépalo para las especies de tipo setosa, mientras que para las de tipo versicolor y virginica la correlación es menor. En el caso del largo y ancho de los pétalos para las tres especies se presenta una correlación positiva.

 >iris %>% ggvis(~Petal.Length, ~Petal.Width, fill = ~Species) %>% layer_points()

 

 

Árboles de decisión. 

Los árboles de decisión dan una serie de reglas que se aplican sobre la entrada de nuevos datos, con el fin de decidir qué clasificación es la más adecuada para ellos.
Para la creación de árboles de decisión en R se usarán principalmente dos paquetes: party y rpart. Para dicha creación, es necesario primero construir una muestra, luego tener un conjunto de datos de entrenamiento y otro conjunto de datos de prueba; con los cuales se construye un modelo de predicción.

Se mostrará a continuación dos formas diferentes de construir árboles de decisión, en el primero se hará uso de la función ctree, la cual permite una partición de variables, pero no maneja muy bien los valores faltantes. En el otro ejemplo se usará la función rpart, con la cual es posible construir diferentes árboles de decisión, y aquel con el mínimo error de predicción es seleccionado.

 Ejemplo 1. Iris. 

Lo primero que se hará es instalar el paquete party

 >install.packages("party")
>library(party)

Ahora, con la función sample() se tomará una muestra de los datos, que será dividida en dos subconjuntos, el primero corresponde al 70% de los datos, entrenamiento; y el segundo, de prueba, corresponde al 30%.
La función set.seed sirve para generar números aleatorios con el fin de crear simulaciones que se puedan reproducir.

>set.seed(1234)
>ind<- sample(2, nrow(iris), replace = T, prob=c(0.7, 0.3))
>trainData<- iris[ind==1,]
>testData<- iris[ind==2,]

Luego con la función ctree del paquete party se construye el árbol de decisión.

 >library(party)
>myFormula<- Species ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width
>iris_ctree<- ctree(myFormula, data = trainData)

Con la función table se crea una tabla donde se observa la predicción.

 >table(predict(iris_ctree), trainData$Species)
                       setosa       versicolor      virginica
      setosa            40                      0                   0
versicolor              0                    37                   3
  virginica              0                       1                31

Para graficar el árbol se usa las funciones plot(). 

 >plot(iris_ctree)

La gráfica de barras anterior, muestra la probabilidad de que una observación caiga en alguna de las tres especies para cada nodo. Por ejemplo, la probabilidad de que una planta cuya longitud de pétalo sea menor a 1,9 sea setosa es del 100% (Nodo 2).

Luego de construido el árbol, es necesario probarlo con los datos de prueba.

>testPred<- predict(iris_ctree, newdata=testData)
>table(testPred, testData$Species)

   testPred        setosa        versicolor        virginica
      setosa                10                       0                     0
versicolor                  0                     12                     2
  virginica                  0                        0                   14


 Ejemplo 2. Bodyfat.

 >library(rpart)
>data("bodyfat", package = "TH.data")

Antes de iniciar, es importante tener claras las variables a partir de las cuales se creará el árbol de decisión, que son las siguientes:

Al igual que en el ejemplo anterior, los datos serán divididos en dos subconjuntos: entrenamiento y prueba; y el árbol será construido con los datos de entrenamiento.

 >set.seed(1234)
>ind2<- sample(2, nrow(bodyfat), replace = T, prob = c(0.7,0.3))
>bodyfat.train<- bodyfat[ind2==1,]
>bodyfat.test<- bodyfat[ind2==2,]

Lo primero que se hará es entrenar un árbol de decisión.

 >myFormula2<- DEXfat~age+waistcirc+hipcirc+elbowbreadth+kneebreadth
>bodyfat_rpart<- rpart(myFormula2, data = bodyfat.train, control = rpart.control(minsplit = 10))

La grafica del arbol se generara con las siguientes lineas de codigo:

 >plot(bodyfat_rpart)
>text(bodyfat_rpart, use.n = T)

 

Ahora se seleccionara el árbol con menor error de predicción.

 >opt<- which.min(bodyfat_rpart$cptable[,"xerror"])
>cp<- bodyfat_rpart$cptable[opt, "CP"]
>bodyfat_prune<- prune(bodyfat_rpart, cp=cp)

>plot(bodyfat_prune)
>text(bodyfat_prune, use.n = T)

Luego de seleccionar el árbol, las predicciones son comparadas con las etiquetas. Con la función abline() se dibuja una línea diagonal, se espera que las predicciones  de un buen modelo sean igual o estén cerca a los valores actuales (puntos cerca a la línea dibujada).

 >DEXfat_pred<- predict(bodyfat_prune, newdata=bodyfat.test)
>xlim<- range(bodyfat$DEXfat)
>plot(DEXfat_pred~DEXfat, data = bodyfat.test, xlab = "Valores Observados", ylab = "Valores Predichos", ylim = xlim, xlim = xlim, col = "red")
>abline(a=0, b=1)

 

KNN.

KNN( K vecinos más cercanos) se trata de un algoritmo de aprendizaje supervisado que pretende clasificar cada dato nuevo en un grupo de acuerdo al número de vecinos más cercanos. Para definir la cercanía se calcula la distancia de la observación nueva con cada observación pasada, luego se ordena de manera ascendente las distancias para finalmente establecer a qué grupo pertenece el dato nuevo.

Los datos que se usarán en esta sección corresponden a la base de datos iris, ya trabajada anteriormente. Lo primero que se hace es conocer los datos, para lo cual se puede recurrir a la realización de gráficos como histogramas, gráficos de dispersión y análisis estadístico como el realizado en la segunda sección (tratamiento inicial de los datos).

El siguiente paso es preparar los datos y/o tratar los datos, para ello se mirara si el rango de cada variable es muy amplio. En caso de que sea así, los datos se deben normalizar. El rango lo podemos calcular con la función summary(), calculando la diferencia entre el valor mínimo y el valor máximo.

 >summary(iris)

Se tiene que el rango de Petal.Length es grande en comparación a las otras variables, lo que podría generar que el cálculo de la distancia esté dominada por dicha esta característica. Con el fin de evitar lo anterior se van a normalizar los datos, para lo cual se construirá la siguiente función.

>normalizar <- function(x) {
    num <- x - min(x)
    denom <- max(x) - min(x)
     return (num/denom)
   }

 

 >iris_norm <- as.data.frame(lapply(iris[1:4], normalizar))
>summary(iris_norm) 

 Al aplicar la función de normalización y hacer un resumen tenemos que el rango para cada una de las variables es igual.

Los datos serán divididos en dos grupos, el primero es usado para entrenar el sistema y corresponde a ⅔ de los datos, el segundo grupo se usa para validar o evaluar el modelo. Para hacer el entrenamiento, debemos asegurarnos de que las tres clases de especies estén presentes, para ello se genera un tipo de “semilla”, con la funciòn set.seed(), que permita crear números aleatorios. Luego se tomará una muestra con la funciòn sample(), la cual crea un vector de dos elementos, y se le asigna a las filas de los datos 1 o 2 (el 1 indica el conjunto de entrenamiento, mientras el 2 indica el conjunto de prueba), dicha asignaciòn está sujeta a las probabilidades ⅔ y ⅓ .

 >set.seed(1234)
>ind <- sample(2, nrow(iris), replace=TRUE, prob=c(2/3, 1/3))

El conjunto de entrenamiento y el conjunto de prueba se establecen con los códigos de las siguientes lineas, cabe aclarar que se toman solo las primeras cuatro columnas, pues la quinta corresponde al tipo de especie, que es lo que queremos predecir.

 > iris.entrenamiento <- iris[ind==1, 1:4]
> iris.test <- iris[ind==2, 1:4]

El siguiente paso consiste en almacenar las etiquetas tanto de entrenamiento como de prueba, dichas etiquetas corresponden al tipo de especie. 

 > Entrenamiento.Etiquetas <- iris[ind==1,5]
>Test.Etiquetas <- iris[ind==2, 5]

Ahora se pasará a crear el modelo de aprendizaje, para lo cual se usará la función knn(), la cual encuentra los k vecinos más cercanos, para las nuevas observaciones, mediante el cálculo de la distancia euclidiana.

 >iris_pred <- knn(train = iris.entrenamiento, test = iris.test, cl = Entrenamiento.Etiquetas, k=3)

Luego de construir el modelo, es de gran importancia probar su eficacia. Para ello se puede comparar las etiquetas que arroja la predicción con las etiquetas reales.  

 >EtiquetasTest <- data.frame(Test.Etiquetas)
>merge <- data.frame(iris_pred, Test.Etiquetas)
>names(merge) <- c("Especies Predichas", "Especies Observadas")
>merge

Se observa que el modelo tiene predicciones precisas, solo hay un error en la fila 30 pues predice versicolor cuando la etiqueta real es virginica.

 

Cluster.

 En esta parte se hará uso de la técnica k-means, técnica cuyo objetivo es la partición de un conjunto de observaciones en un número determinado de grupos. Se trata de un tipo de aprendizaje no supervisado, donde la clasificación se realiza minimizando la suma de distancias entre cada objeto y el centroide de su grupo o cluster.

En el siguiente video se presenta una explicación mas detallada. 

 

Clasificación binaria. 

Es uno de los modelos o algoritmos más usados, dada su sencillez. A continuación se explicaran dos de los ejemplos más conocidos, detección de Spam y clasificación por sexo.