En el área de ´Machine Learning´ (Aprendizaje automático en español), el aprendizaje No-Supervisado es la tarea encargada de encontrar estructuras desconocidas a priori, que se encuentran en un conjunto de datos. Se desconocen las estructuras intrínsecas del conjunto de datos debido a la ausencia de un atributo que de alguna manera guie (supervise) la formación de dichas estructuras.
´Clustering´ (agrupación en español) es una de las técnicas aplicadas en el aprendizaje No-Supervisado. En la actividad, se nos provee de una serie de conjuntos de datos y se requiere que apliquemos las técnicas ´clustering´ vistas en clases, de manera selectiva. Se debe argumentar cada decisión tomada en la realización de la actividad.
#Biblioteca de graficacion 3D
library(rgl)
## Warning: package 'rgl' was built under R version 3.1.3
library(FactoMineR)
## Warning: package 'FactoMineR' was built under R version 3.1.3
library(scatterplot3d)
## Warning: package 'scatterplot3d' was built under R version 3.1.3
#Archivo de funciones definidas
source("funciones.R")
#Loading Datasets
a = read.csv("a.csv", header = F)
a_big = read.csv("a_big.csv", header = F)
good_luck = read.csv("good_luck.csv", header = F)
guess = read.csv("guess.csv", header = F)
h = read.csv("h.csv", header = F)
help = read.csv("help.csv", header = F)
moon = read.csv("moon.csv", header = F)
s = read.csv("s.csv", header = F)
summary(a)
## V1 V2 V3
## Min. :-19.612 Min. :-20.006 Min. :0
## 1st Qu.: -8.100 1st Qu.:-11.055 1st Qu.:0
## Median : 7.869 Median : -8.121 Median :1
## Mean : 3.294 Mean : -3.392 Mean :1
## 3rd Qu.: 10.846 3rd Qu.: 7.943 3rd Qu.:2
## Max. : 21.015 Max. : 20.680 Max. :2
summary(a_big)
## V1 V2 V3
## Min. :-27.462 Min. :-27.951 Min. :0
## 1st Qu.: -7.305 1st Qu.:-11.275 1st Qu.:0
## Median : 7.327 Median : -7.284 Median :1
## Mean : 3.345 Mean : -3.329 Mean :1
## 3rd Qu.: 11.277 3rd Qu.: 7.305 3rd Qu.:2
## Max. : 27.979 Max. : 26.712 Max. :2
summary(good_luck)
## V1 V2 V3
## Min. :-2.85300 Min. :-3.07608 Min. :-3.162396
## 1st Qu.:-0.66357 1st Qu.:-0.65641 1st Qu.:-0.707708
## Median :-0.05781 Median : 0.03336 Median : 0.009084
## Mean :-0.01491 Mean : 0.03993 Mean : 0.009990
## 3rd Qu.: 0.60715 3rd Qu.: 0.74784 3rd Qu.: 0.683820
## Max. : 3.30694 Max. : 4.16582 Max. : 3.260145
## V4 V5 V6
## Min. :-3.22759 Min. :-3.204147 Min. :-3.335482
## 1st Qu.:-0.76546 1st Qu.:-0.672720 1st Qu.:-0.677226
## Median :-0.02199 Median :-0.006338 Median :-0.025197
## Mean :-0.05420 Mean :-0.015037 Mean : 0.000813
## 3rd Qu.: 0.60845 3rd Qu.: 0.659338 3rd Qu.: 0.678486
## Max. : 3.88554 Max. : 3.191227 Max. : 3.061311
## V7 V8 V9
## Min. :-3.396008 Min. :-3.073375 Min. :-3.559169
## 1st Qu.:-0.663668 1st Qu.:-0.695388 1st Qu.:-0.685678
## Median : 0.034641 Median : 0.016920 Median :-0.003808
## Mean :-0.002181 Mean :-0.007488 Mean :-0.006503
## 3rd Qu.: 0.627174 3rd Qu.: 0.647090 3rd Qu.: 0.664717
## Max. : 3.671617 Max. : 3.737200 Max. : 3.227338
## V10 V11
## Min. :-3.05439 Min. :0.000
## 1st Qu.:-0.70022 1st Qu.:0.000
## Median :-0.04033 Median :0.000
## Mean :-0.01427 Mean :0.487
## 3rd Qu.: 0.68201 3rd Qu.:1.000
## Max. : 2.96082 Max. :1.000
summary(guess)
## V1 V2
## Min. :-38.575 Min. :-34.207
## 1st Qu.:-10.144 1st Qu.: -8.089
## Median : 5.529 Median : 7.426
## Mean : 6.903 Mean : 8.853
## 3rd Qu.: 17.894 3rd Qu.: 21.857
## Max. : 67.537 Max. : 68.029
summary(h)
## V1 V2 V3 V4
## Min. :-9.608 Min. :-0.02557 Min. :-11.3510 Min. : 4.718
## 1st Qu.:-3.311 1st Qu.: 5.37268 1st Qu.: -4.7355 1st Qu.: 7.046
## Median : 3.112 Median :10.84431 Median : 0.7600 Median : 9.249
## Mean : 1.957 Mean :10.73390 Mean : 0.6411 Mean : 9.386
## 3rd Qu.: 6.199 3rd Qu.:16.33213 3rd Qu.: 6.6741 3rd Qu.:11.661
## Max. :12.777 Max. :21.16627 Max. : 14.2422 Max. :14.135
summary(help)
## V1 V2 V3 V4
## Min. :-10.000 Min. :-0.02557 Min. :-19.99995 Min. :-4.712
## 1st Qu.: 6.864 1st Qu.: 4.93492 1st Qu.:-10.21263 1st Qu.:-1.180
## Median : 30.112 Median : 9.98509 Median : 0.09956 Median : 2.426
## Mean : 27.848 Mean :10.07264 Mean : 0.10830 Mean : 3.141
## 3rd Qu.: 47.801 3rd Qu.:15.20300 3rd Qu.: 9.93020 3rd Qu.: 7.045
## Max. : 65.000 Max. :21.16627 Max. : 19.99975 Max. :14.135
summary(moon)
## V1 V2 V3
## Min. :-1.11299 Min. :-0.5994 Min. :0.0
## 1st Qu.:-0.03567 1st Qu.:-0.2145 1st Qu.:0.0
## Median : 0.48495 Median : 0.2462 Median :0.5
## Mean : 0.49760 Mean : 0.2498 Mean :0.5
## 3rd Qu.: 1.03710 3rd Qu.: 0.7040 3rd Qu.:1.0
## Max. : 2.09638 Max. : 1.1232 Max. :1.0
summary(s)
## V1 V2 V3
## Min. :-1.00000 Min. :0.000735 Min. :-1.99998
## 1st Qu.:-0.75703 1st Qu.:0.510429 1st Qu.:-1.34367
## Median :-0.09189 Median :1.038975 Median : 0.01552
## Mean :-0.04114 Mean :1.022700 Mean : 0.04017
## 3rd Qu.: 0.69542 3rd Qu.:1.556196 3rd Qu.: 1.40985
## Max. : 1.00000 Max. :1.997053 Max. : 1.99998
## V4
## Min. :-4.70724
## 1st Qu.:-2.37869
## Median :-0.17603
## Mean :-0.03844
## 3rd Qu.: 2.23613
## Max. : 4.71059
En la actividad, se indica que a excepción del set de datos guess.csv, la última columna es la clase. Se nos provee de una columna clase para poder evaluar los modelos de ´clustering´ a través de una matriz de confusión.
Por convención en esta actividad, la asignación de las clases y posteriormente, de los grupos, serán números enteros mayores que 0. En algunos datasets, la columna clase tiene valores reales y negativos.
Además, se nos indica que en algunos conjuntos de datos, debemos aplicar reglas para la elección de la clase, según un intervalo.
Los conjuntos de datos que se deben aplicar reglas para la asignación de una clase, son h, help y s. Para esto, graficaremos un histograma de frecuencia, y asignaremos intervalos equidistantes para la asignación de una clase.
# Datasets en las que se deben aplicar reglas para asignar clases
g1 = list(help, s, h)
names = c("help", "s", "h")
layout(1:3)
histograms = list()
clases = list()
j = 1
for ( i in g1 ){
histograms[[j]] = hist( i$V4, main = names[j],xlab = "Clase")
clases[[j]] = asignarClase(histograms[[j]]$breaks, i$V4)
j = j + 1
}
# Las clases fueron asignadas de acuerdo a intervalos equidistantes
help$clase = clases[[1]]
s$clase = clases[[2]]
h$clase = clases[[3]]
La razón por la que se escogieron clases derivadas de intervalos con rangos iguales (equidistantes) es que al ver el histograma de frecuencia, podría inferirse que la columna de clase fue generada a través de una variable aleatoria con distribución uniforme. Por esa razón, la cantidad de elementos de cada clase debe ser parecida.
Las clases fueron asignadas desde 1 hasta el máximo entero de la secuencia generada por la cardinalidad de los cortes.
El resto de los conjuntos de datos que poseen una clase, están definidos desde el número 0. Esto puede traer confusiones al momento de evaluar el modelo de clustering.
g2 = list(a, a_big, good_luck, moon)
a$clase = a$V3 +1
a_big$clase = a_big$V3 + 1
good_luck$clase = good_luck$V11 + 1
moon$clase = moon$V3 + 1
El único set de datos que no tiene una clase ya definida, es guess.csv. Luego, para determinar el número de conglomerados, se determinará el k, que acumule menos error, a fin de maximizar las distancias inter-cluster (como consecuencia, se minimizan las distancias intra-cluster).
summary(help)
## V1 V2 V3 V4
## Min. :-10.000 Min. :-0.02557 Min. :-19.99995 Min. :-4.712
## 1st Qu.: 6.864 1st Qu.: 4.93492 1st Qu.:-10.21263 1st Qu.:-1.180
## Median : 30.112 Median : 9.98509 Median : 0.09956 Median : 2.426
## Mean : 27.848 Mean :10.07264 Mean : 0.10830 Mean : 3.141
## 3rd Qu.: 47.801 3rd Qu.:15.20300 3rd Qu.: 9.93020 3rd Qu.: 7.045
## Max. : 65.000 Max. :21.16627 Max. : 19.99975 Max. :14.135
## clase
## Min. : 1.000
## 1st Qu.: 3.000
## Median : 5.000
## Mean : 5.061
## 3rd Qu.: 7.000
## Max. :11.000
Luego de asignar la clase correspondiente al conjunto de datos help, y posteriormente, realizar un grafico 3D interactivo a través de la biblioteca rgl, es notable que las clases no están bien asignadas. En el gráfico se puede ver que ambas letras S (ya que es una representación de las siglas SOS, en R^3) tienen las mismas clases.
Este problema esta sujeto a la interpretación del analista. En este caso, la forma en que se solucionará el problema, es asignando una clase a cada letra.
NOTA: Para poder visualizar lo realizado, es necesario correr la sección de código “Help New Class”, el archivo script.R.
help$clase2 = 0
help[ 1:1000, ]$clase2 = 1
help[ 1001:2000, ]$clase2 = 2
help[ 2001:3000, ]$clase2 = 3
A continuación observaremos el dataset “guess.csv” y aplicaremos el codo de Jambú para escoger el número de clústeres que minimice la distancia intra-cluster, sin sobreajuste.
summary(guess)
## V1 V2
## Min. :-38.575 Min. :-34.207
## 1st Qu.:-10.144 1st Qu.: -8.089
## Median : 5.529 Median : 7.426
## Mean : 6.903 Mean : 8.853
## 3rd Qu.: 17.894 3rd Qu.: 21.857
## Max. : 67.537 Max. : 68.029
ss = 1:20
for( i in 1:20){
modelo = kmeans(x = guess, centers = i, iter.max = 20)
ss[[i]] = modelo$tot.withinss
}
plot(1:20, ss, xlab = "Clusters", ylab = "Distancia intra clusters total",type = "b")
kGuess = 5
En el gráfico podemos observar que 5 es el número que refleja menor intra-cluster. A partir del 5, los cambios no son significativos. Por lo tanto, escogeremos k = 5 clústeres para el definir el modelo.
#Analizando Good_luck.csv
summary(good_luck)
## V1 V2 V3
## Min. :-2.85300 Min. :-3.07608 Min. :-3.162396
## 1st Qu.:-0.66357 1st Qu.:-0.65641 1st Qu.:-0.707708
## Median :-0.05781 Median : 0.03336 Median : 0.009084
## Mean :-0.01491 Mean : 0.03993 Mean : 0.009990
## 3rd Qu.: 0.60715 3rd Qu.: 0.74784 3rd Qu.: 0.683820
## Max. : 3.30694 Max. : 4.16582 Max. : 3.260145
## V4 V5 V6
## Min. :-3.22759 Min. :-3.204147 Min. :-3.335482
## 1st Qu.:-0.76546 1st Qu.:-0.672720 1st Qu.:-0.677226
## Median :-0.02199 Median :-0.006338 Median :-0.025197
## Mean :-0.05420 Mean :-0.015037 Mean : 0.000813
## 3rd Qu.: 0.60845 3rd Qu.: 0.659338 3rd Qu.: 0.678486
## Max. : 3.88554 Max. : 3.191227 Max. : 3.061311
## V7 V8 V9
## Min. :-3.396008 Min. :-3.073375 Min. :-3.559169
## 1st Qu.:-0.663668 1st Qu.:-0.695388 1st Qu.:-0.685678
## Median : 0.034641 Median : 0.016920 Median :-0.003808
## Mean :-0.002181 Mean :-0.007488 Mean :-0.006503
## 3rd Qu.: 0.627174 3rd Qu.: 0.647090 3rd Qu.: 0.664717
## Max. : 3.671617 Max. : 3.737200 Max. : 3.227338
## V10 V11 clase
## Min. :-3.05439 Min. :0.000 Min. :1.000
## 1st Qu.:-0.70022 1st Qu.:0.000 1st Qu.:1.000
## Median :-0.04033 Median :0.000 Median :1.000
## Mean :-0.01427 Mean :0.487 Mean :1.487
## 3rd Qu.: 0.68201 3rd Qu.:1.000 3rd Qu.:2.000
## Max. : 2.96082 Max. :1.000 Max. :2.000
pairs(good_luck[,-c(11,12)], col=good_luck$clase)
pca = PCA(good_luck[,-c(11,12)])
pca$eig
## eigenvalue percentage of variance
## comp 1 1.2025456 12.025456
## comp 2 1.1210352 11.210352
## comp 3 1.0529327 10.529327
## comp 4 1.0409954 10.409954
## comp 5 1.0195327 10.195327
## comp 6 0.9865676 9.865676
## comp 7 0.9507652 9.507652
## comp 8 0.9463918 9.463918
## comp 9 0.8782735 8.782735
## comp 10 0.8009603 8.009603
## cumulative percentage of variance
## comp 1 12.02546
## comp 2 23.23581
## comp 3 33.76514
## comp 4 44.17509
## comp 5 54.37042
## comp 6 64.23609
## comp 7 73.74374
## comp 8 83.20766
## comp 9 91.99040
## comp 10 100.00000
Al realizar el gráfico 2 a 2 de las variables del set de datos, y además, aplicando un análisis de componentes principales, nos podemos dar cuenta, que los datos parecen no ser separables. Por lo tanto, no existe alguna manera de detectar con una precisión aceptable, los elementos de una clase o de otra.
Sin embargo, aplicaremos un modelo de “clustering” para dar soporte de lo anterior.
NOTA: Para observar el análisis exploratorio de los otros conjuntos de datos, correr la sección de código correspondiente al análisis exploratorio de cada uno.
En este conjunto de datos, podemos observar que solo posee 2 dimensiones (2 features) y por lo tanto podemos graficarlo en un plano.
plot(a$V1, a$V2, col=a$clase, main="Dataset a.csv")
Como podemos observar, los puntos están definidos 3 nubes de puntos, que tienen aproximadamente una forma circular.
Debido a la forma de las nubes de puntos, podemos decir que tanto la técnica de clusterización K-Medias como Clusterización Jerárquica tomando la máxima distancia (“complete”), generaran buenos modelos. Sin embargo, aplicaremos K-Medias, ya que nos beneficiaremos de los centroides generados por el algoritmo, para establecer un punto de partida en el algoritmo que aplicaremos en el dataset a_big.csv, ya que este posee una distribución similar, pero tiene una dimensionalidad 100 veces mayor.
NOTA: El algoritmo utilizado se encuentra definido en el archivo funciones.R
a.model = kMeans(a[,c(1,2)], centers=3, max.iter=50)
plot(a$V1, a$V2, col=a.model[[2]], main="a.csv")
points(a.model[[1]], pch=19, col=4)
Este conjunto de datos posee una distribución similar al anterior. Su dimensionalidad es 100 veces mayor en cuanto a las filas. Además, su nombre es un hint.
Para la definición de un modelo de clusterización para este dataset, utilizaremos el algoritmo de K-Medias, pero iniciando con los centroides obtenidos en el modelo anterior.
a_big.model = kMeans(a_big[,c(1,2)], centers=3, max.iter=50, centros=a.model[[1]])
plot(a_big$V1, a_big$V2, col=a_big.model[[2]], main="a_big.csv")
points(a_big.model[[1]], pch=19, col=4)
Anteriormente, en el análisis exploratorio, es notable que el set de datos posee más de tres dimensiones. Al observar los gráficos de dispersión 2 a 2, se puede llegar a la conclusión que ninguna técnica de clusterización vista en clase podrá generar un modelo aceptable. Esto se debe a que al parecer, los puntos que pertenecen a cada clase, no son separables, quizás en alguna dimensión superior se puede lograr un modelo aceptable, sin embargo no sabemos cómo lidie dicho modelo el problema de sobreajuste.
Aplicaremos un modelo de K-Medias, para observar los resultados y analizar el rendimiento luego, con el fin de dar soporte a lo anterior.
good_luck.model = kmeans(good_luck[,-c(11,12)], centers=2, iter.max=20)
plot(good_luck[,-c(11,12)], col=good_luck.model$cluster)
En el gráfico podemos ver como los puntos que pertenecen a un clúster o a otro, están sobrepuestos, por lo tanto, la precisión no será aceptable.
El dataset guess.csv, no posee una columna con las clases, sin embargo, determinamos que es posible aplicar una implementación de K-Medias y además, que con k=5, se minimiza la distancia intra-cluster de manera aceptable. A partir de k>5, no existen grandes diferencias.
Para este set de datos, no podremos evaluar su rendimiento ya que no tenemos una columna clase con la cual comparar, a través de una matriz de confusión.
guess.model = kmeans(guess, centers = 5, iter.max=30)
guess$cluster = guess.model$cluster
plot(guess$V1, guess$V2, col=guess$cluster)
points(guess.model$centers, pch=19, col=6, main="Dataset guess.csv")
Este conjunto de datos posee 3 dimensiones, al graficarlo (en script.R), se observa que posee una forma de espiral, y en ese espiral, están repartidos los clústeres en una forma rectangular. Para este set de datos, utilizaremos el algoritmo de clusterización jerárquica, sin embargo, los clústeres poseen formas arbitrarias que hacen que ningún modelo visto en clase tenga una precisión aceptable.
h.distance.matrix = dist(as.matrix(h[,c(1,2,3)]))
h.model = hclust(h.distance.matrix, method="complete")
h.corte = cutree(h.model, 11)
scatterplot3d(h$V1, h$V2, h$V3, color=h.corte, pch=19, main="Dataset h.csv")
Este dataset, es similar al anterior (h.csv) en cuanto dimensionalidad, pero se diferencian en la figura formada. Esta figura, es una figura arbitraria (tiene forma de “s”), de manera que es posible que no se genere un modelo con la precisión requerida.
s.distance.matrix = dist(as.matrix(s[,c(1,2,3)]))
s.model = hclust(s.distance.matrix, method="complete")
s.corte = cutree(s.model, 10)
scatterplot3d(s$V1, s$V2, s$V3, color=s.corte, pch=19, main="Dataset s.csv")
El set de datos help.csv, es una combinación de los 2 anteriores. Está compuesto por la unión de 2 set de datos s (s.csv) y un h (h.csv) trasladados y colocados en un mismo espacio 3D.
Al ver el gráfico, es evidente que cada letra puede ser tomada como un clúster, y luego, aplicar otro modelo de clusterización, dependiendo si el punto pertenece a una s o a la h.
Se utilizará el algoritmo de clusterización jerárquica con el método “single”, ya que cada letra (clúster en forma de letra), podría ser perfectamente cubierta por la forma de un rectángulo, que es una de las situaciones en donde el método se comporta de una manera adecuada.
help.distance.matrix = dist(as.matrix(help[,c(1,2,3)]))
help.model = hclust(help.distance.matrix, method="single")
help.corte = cutree(help.model,3)
scatterplot3d(help$V1, help$V2, help$V3, color=help.corte, pch=19, main="Dataset help.csv")
Este conjunto de datos, está formado por puntos en 2 dimensiones. Los puntos que pertenecen a diferentes clases se agrupan en clústeres que no tienen forma esférica, por lo que la técnica de clusterización jerárquica con el método “single” deberá mostrar resultados adecuados.
moon.distance.matrix = dist(as.matrix(moon[,c(1,2)]))
moon.model = hclust(moon.distance.matrix, method="single")
moon.corte = cutree(moon.model, 2)
plot(moon$V1, moon$V2, col=moon.corte, main="Dataset moon.csv")
La evaluación de los modelos, será basada en la matriz de confusión generada por la columna de clase y el número de clúster asignado por el modelo de clusterización a cada observación. Si la matriz es 2x2, se asumirá como clase (clúster en este caso) objetivo a “1”, y se realizará el cálculo de la sensibilidad, precisión, y F1 Score.
a.conf = table(a$clase, a.model[[2]], dnn=c("Clase", "Cluster"))
a.conf = fix.conf.table(a.conf)
a.conf
## Cluster
## Clase 1 2 3
## 1 1000 0 0
## 2 0 1000 0
## 3 1 0 999
eval.conf.matrix(a.conf)
## La exactitud del modelo es: 0.9996667
## tps: 2999
## fs: 1
a_big.conf = table(a_big$clase, a_big.model[[2]], dnn=c("Clase", "Cluster"))
a_big.conf = fix.conf.table(a_big.conf)
a_big.conf
## Cluster
## Clase 1 2 3
## 1 99405 11 584
## 2 14 99401 585
## 3 666 589 98745
eval.conf.matrix(a_big.conf)
## La exactitud del modelo es: 0.9918367
## tps: 297551
## fs: 2449
good_luck.conf = table(good_luck$clase, good_luck.model$cluster, dnn=c("Clase", "Cluster"))
good_luck.conf = fix.conf.table(good_luck.conf)
good_luck.conf
## Cluster
## Clase 1 2
## 1 273 240
## 2 229 258
eval.conf.matrix(good_luck.conf)
## Precision: 0.5438247
## Sensibilidad: 0.5321637
## F1 Score: 0.537931
h.conf = table(h$clase, h.corte, dnn=c("Clase", "Cluster"))
h.conf = fix.conf.table(h.conf)
h.conf
## Cluster
## Clase 1 2 3 4 5 6 7 8 9 10 11
## 1 0 8 0 0 0 0 0 14 8 0 0
## 2 0 42 0 0 0 0 0 33 35 0 0
## 3 0 26 0 22 0 0 0 0 43 0 13
## 4 0 0 0 54 2 0 0 0 1 0 58
## 5 31 0 0 38 42 0 0 0 0 0 5
## 6 34 0 0 0 8 53 3 0 0 0 0
## 7 0 0 0 0 0 12 39 9 0 37 0
## 8 0 34 0 0 0 0 0 61 8 1 0
## 9 0 16 32 0 0 0 0 0 35 0 12
## 10 0 0 30 25 0 0 0 0 0 0 63
## 11 0 0 0 6 0 0 0 0 0 0 7
eval.conf.matrix(h.conf)
## La exactitud del modelo es: 0.333
## tps: 333
## fs: 667
s.conf = table(s$clase, s.corte, dnn=c("Clase", "Cluster"))
s.conf = fix.conf.table(s.conf)
s.conf
## Cluster
## Clase 1 2 3 4 5 6 7 8 9 10
## 1 52 23 0 0 0 0 0 0 0 0
## 2 46 53 11 0 0 0 0 0 0 0
## 3 0 46 59 0 0 0 0 0 0 0
## 4 0 12 21 0 63 0 19 0 0 0
## 5 0 0 0 0 40 38 34 0 0 0
## 6 0 0 0 23 0 60 0 16 0 0
## 7 0 0 0 40 0 0 0 62 0 0
## 8 0 0 0 16 0 0 0 49 30 0
## 9 0 0 0 0 0 0 0 3 71 29
## 10 0 0 0 0 0 0 0 0 38 46
eval.conf.matrix(s.conf)
## La exactitud del modelo es: 0.43
## tps: 430
## fs: 570
help.conf = table(help$clase2, help.corte, dnn=c("Clase", "Cluster"))
help.conf = fix.conf.table(help.conf)
help.conf
## Cluster
## Clase 1 2 3
## 1 1000 0 0
## 2 0 1000 0
## 3 0 0 1000
eval.conf.matrix(help.conf)
## La exactitud del modelo es: 1
## tps: 3000
## fs: 0
moon.conf = table(moon$clase, moon.corte, dnn=c("Clase", "Cluster"))
moon.conf = fix.conf.table(moon.conf)
moon.conf
## Cluster
## Clase 1 2
## 1 500 0
## 2 0 500
eval.conf.matrix(moon.conf)
## Precision: 1
## Sensibilidad: 1
## F1 Score: 1
En los modelos obtenidos luego de aplicar K-Medias en los dataset a.csv y a_big.csv, se obtuvieron muy buenos resultados. Esto se debe a que los clústeres tienen una forma esférica. Es importante resaltar que una esfera en 2 dimensiones, es una circunferencia (o un círculo).
Los resultados obtenidos luego de aplicar K-Medias al dataset good_luck.csv, nos damos cuenta que el modelo acertó el 50% de las veces, sin embargo, esto es equivalente a lanzar una moneda justa y clasificar en base al resultado. Este resultado es coherente, ya que los puntos que pertenecen a las 2 clases proporcionadas, están mezclados entre sí, de manera que dificulta la toma de decisión a la hora de asignar el clúster correcto.
El dataset guess.csv no fue evaluado, ya que no teníamos una variable para contrastar los resultados.
Los modelos obtenidos luego de aplicar clusterización jerárquica en los datasets h.csv y s.csv, generan una matriz de confusión que indica que los modelos aciertan un 30% de las veces, esto no es del todo deseable. El resultado es consecuencia de que los clústeres tenían una forma arbitraria, y como consecuencia, los algoritmos vistos en clase, no se adaptan correctamente a estas situaciones. Para estas situaciones, se recomiendan algoritmos como Kernel K-Means y Spectral Clustering.
El modelo generado para el dataset help.csv, se comporta de manera perfecta, al igual que el modelo generado para el set de datos moon.csv. Ambos conjuntos de datos, presentan agrupaciones con formas a las que el algoritmo de clusterización jerárquica se adapta perfectamente.
Las funciones utilizadas y que no están expuestas explicitamente en este informe, se encuentran definidas en el archivo funciones.R.