**IAIC**
Práctica Semana 11
Clustering
!!!warn: Descargas
1. [Aquí puedes descargar un ZIP con los ficheros necesarios para realizar esta práctica](P11.zip).
# Problemas Propuestos
**Problema 1**.- Considera los puntos $P_1=(0,48)$, $P_2=(0,78)$, $P_3=(36,126)$, $P_4=(36,0)$ y los centros $m_1=(20,63)$ y $m_2=(36,63)$. Aplica **K-medias** sobre el conjunto $\{P_1,\dots,P_4\}$ tomando $m_1$ y $m_2$ como centroides iniciales ($k=2$). Indica las agrupaciones resultantes antes y después de un paso del algoritmo, y los nuevos centroides obtenidos.
**Problema 2**.- Aplica **K-medias** para clusterizar el siguiente conjunto de puntos, y tomando $k=2$ con los centroides iniciales $m_1=(1,1,−1)$ y $m_2=(0,−1,1)$:
| | $E_1$ | $E_2$ | $E_3$ | $E_4$ | $E_5$ |
|-------|:---------:|:---------:|:--------:|:-------:|:---------------:|
|Punto |$(1,0.5,0)$|$(-1,-1,0)$|$(1,0,-1)$|$(0,0,1)$|$(1,-0.5,-0.5)$ |
**Problema 3**.- Sea $D=\{A_1(2,10),\ A_2(2,5),\ A_3(8,4),\ A_4(5,8),\ A_5(7,5),\ A_6(6,4),\ A_7(1,2),\ A_8(4,9)\}$:
1. Usa un paso de **k-medias** con la distancia euclídea para agrupar $D$ en 3 clusters tomando como centroides iniciales $A_1$, $A_4$ y $A_7$. Indica las agrupaciones resultantes antes y después de un paso del algoritmo, y los nuevos centroides obtenidos.
2. Aplica el método de **AGNES** a $D$ para obtener la jerarquía de clusters usando alguna de las distancias habituales.
3. Aplica **DBSCAN** a $D$ con $\epsilon=2$ y $MinPts=2$. ¿Qué pasa si $\epsilon=10$?
**Problema 4**.- Haciendo uso de la siguiente matriz de distancias entre los puntos de un dataset:
| A | B | C | D | E | F | G |
|---|------|------|------|------|------|------|
| A | 0 | | | | | |
| B | 2'15 | 0 | | | | |
| C | 0'7 | 1'53 | 0 | | | |
| D | 1'07 | 1'14 | 0'43 | 0 | | |
| E | 0'85 | 1'38 | 0'21 | 0'29 | 0 | |
| F | 1'16 | 1'01 | 0'55 | 0'22 | 0'41 | 0 |
| G | 1'56 | 2'83 | 1'86 | 2'04 | 2'02 | 2'05 |
Aplica el método AGNES para obtener la jerarquía de clusters asociados usando: $d_{min}(C_1,C_2)=min\{d(x_1,x_2):\ x_1\in C_1,\ x_2\in C_2\}$.
**Problema 5**.- Utiliza algún algoritmo de Clustering para rebajar el número de colores que se usa en una imagen. Para ello:
1. Carga una imagen en los patches haciendo uso de la función de importación adecuada.
2. Aplica el algoritmo de Clustering al conjunto de colores, determinando a priori el número de colores finales que quieres usar (puedes hacer que sea una decisión del usuario por medio del interfaz).
3. Muestra la imagen resultante con los colores reasignados según el cluster al que pertenecen.
4. ¿Se te ocurre alguna forma de restringir la paleta de colores original (no solo el número de colores)?
**Problema 6**.- Define las funciones que calculas las **métricas de validación interna** vistas en el tema de teoría.
**Problema 7**.- Define las funciones que calculan las **métricas de validación externa** vistas en el tema de teoría.
# Dataframes
!!!Tip
Librería para trabajar con DataFrames
`DF:load`, `DF:save, DF:header, DF:data`, `DF:first`, `DF:last`, `DF:n-of`, `DF:shape`, `DF:pp`, `DF:ren-col`, `DF:add-col`, `DF:move-col`, `DF:add-calc-col`, `DF:col`, `DF:value`, `DF:sort-col`, `DF:filter`, `DF:map`, `DF:foreach`, `DF:col-values`, `DF:filter-col`, `DF:rem-col`, `DF:shuffle`, `DF:split`, `DF:sort-by`, `DF:enum`, `DF:Cat2NumDep`, `DF:Cat2NumIndep`, `DF:Bin2NumDep`, `DF:Bin2NumIndep`, `DF:scale`, `DF:normalize`, `DF:summary`
El formato que se sigue es: `(Tipo-Salida) DF:Funcion Tipo-Entrada-1 ... Tipo-Entrada-N`, donde los tipos son: `Df` (Dataframe), `L` (Lista), `S` (Cadena), `N` (Número), `X` (Genérico)
* Carga un CSV en un DF: `(Df) DF:load f`
* Graba un DF en un CSV: `() DF:save Df f`
* Muestra el DF en el Centro de Comandos: `DF:show Df`
* Pretty Print de un DF (cadena para imprimir): `(S) DF:pp Df`
* Print de un DF: `() DF:print Df`
* Resumen del DF: `() DF:summary Df`
* Recuperación: (`cn`: column name)
* Cabecera: `(L) DF:header Df`
* Datos: `(L) DF:data Df`
* `N` primeras filas: `(L) DF:first N Df`
* `N` últimas filas: `(L) DF:last N Df`
* `N` filas al azar: `(L) DF:n-of N Df`
* Una columna (datos): `(L) DF:col cn Df`
* Valores (sin duplicados) de `cn`: `(L) DF:col-values cn Df`
* Valor de una columna en una fila: `(X) DF:value cn row Df`
* Forma (`N1` filas x `N2` columnas): `([N1 N2]) DF:shape Df`
* Modificación Columnas:
* Cambia nombre de una columna: `(Df) DF:ren-col old-cn new-cn Df`
* Añade nueva columna con contenido: `(Df) DF:add-col cn cont Df`
* Añade nueva columna calculada: `(Df) DF:add-calc-col cn f Df`
* Elimina columna: `(Df) DF:rem-col cn Df`
* Filtra filas con valor `val` en `cn`: `(Df) DF:filter-col cn val Df`
* Ordena las filas según `cn`: `(Df) DF:sort-col cn Df`
* Cambia una columna de posición (`pos` se calcula sin `cn`): `(DF) DF:move-col cn pos Df`
* Modificación Dataframe:
* Filtra las filas verificando `f`: `(Df) DF:filter f Df`
* Aplica `f` a todas las filas: `(L) DF:map f Df`
* Ejecuta una acción `f` a cada fila: `() DF:foreach Df f`
* Reordena al azar las filas: `(Df) DF:shuffle Df`
* Split aleatorio (`r` $\in [0,1]$), `r|(1-r)`: `([Df1 Df2]) DF:split r Df`
* Ordena las filas usando una función `f`: `(Df) DF:sort-by f Df`
* Añade una columna con enumeración: `(Df) DF:enum Df`
* Categórica a Numérica:
* `(DF) DF:Cat2NumDep cn Df`
* `(DF) DF:Cat2NumIndep cn Df`
* Binaria a Numérica:
* `(DF) DF:Bin2NumDep cn Df`
* `(DF) DF:Bin2NumIndep cn Df`
* Normalización (no comprueba que los datos sean numéricos, ni maneja datos faltantes):
* Escala lineal: escala los valores de `cn` para que tomen los valores en $[a,b]$: `(DF) DF:scale cn a b Df`
* Normal: escala los valores de `cn` para seguir una normal $N(0,1)$: `(DF) DF:normalize cn Df`
Test Titanic
~~~~C
to DF:titanic-test
ca
let dftest DF:n-of 10 DF:load "titanic.csv"
DF:print dftest
DF:print (DF:scale "Age" 0 1 dftest)
DF:print (DF:scale "Fare" -1 1 dftest)
DF:print (DF:normalize "Fare" dftest)
let df2 (DF:enum dftest)
DF:print df2
let df3 (DF:move-col "#-row" 0 df2)
DF:print df3
let df4 (DF:move-col "Survived" 8 df3)
DF:print df4
end
~~~~
Test PlayGolf
~~~~C
to DF:PlayGolf-test
ca
let dftest DF:load "PlayGolf.txt"
print "Complete DF: dftest"
DF:print dftest
DF:summary dftest
print "DF:Cat2NumIndep \"Outlook\" dftest"
DF:print DF:Cat2NumIndep "Outlook" dftest
print "DF:Cat2NumDep \"Outlook\" dftest"
DF:print DF:Cat2NumDep "Outlook" dftest
print "DF:Bin2NumDep \"Windy\" dftest"
DF:print DF:Bin2NumDep "Windy" dftest
print "DF:Bin2NumIndep \"Windy\" dftest"
DF:print DF:Bin2NumIndep "Windy" dftest
print "DF:filter [r -> (DF:value \"Windy\" r dftest) and (DF:value \"PlayGolf\" r dftest)] dftest"
let dftest2 DF:filter [r -> (DF:value "Windy" r dftest) and (DF:value "PlayGolf" r dftest)] dftest
DF:print dftest2
print "DF:col-values \"Outlook\" dftest"
print (DF:col-values "Outlook" dftest)
print ""
print "DF:rem-col \"Outlook\" dftest"
DF:print (DF:rem-col "Outlook" dftest)
print "Separate DFs by every value in every attribute:"
print ""
foreach DF:header dftest [
h ->
foreach (DF:col-values h dftest)[
v ->
print (word h " = " v)
let f [r -> DF:value h r dftest = v]
DF:print (DF:filter f dftest)
]
]
end
~~~~
Test Iris
~~~~C
to DF:iris-test
ca
let dftest DF:n-of 10 DF:load "iris.txt"
print "DF:sort-col \"pw\" dftest"
DF:print DF:sort-col "pw" dftest
print "DF:enum dftest"
DF:print DF:enum dftest
print "DF:sort-by [[r1 r2] -> ((first r1) < (first r2)) or ((first r1) = (first r2) and (item 1 r1) < (item 1 r2))] dftest"
DF:print DF:sort-by [[r1 r2] -> ((first r1) < (first r2)) or ((first r1) = (first r2) and (item 1 r1) < (item 1 r2))] dftest
print "DF:header dftest"
print DF:header dftest
print "DF:first 3 dftest"
DF:print (DF:first 3 dftest)
print "DF:last 3 dftest"
DF:print (DF:last 3 dftest)
print "DF:n-of 3 dftest"
DF:print (DF:n-of 3 dftest)
print "DF:add-col \"Random\" (n-values (first DF:shape dftest) [random 10]) dftest"
DF:print (DF:add-col "Random" (n-values (first DF:shape dftest) [random 10]) dftest)
print "DF:add-calc-col \"Join\" [r -> (word (item 0 r) \" \" (item 1 r))] dftest"
let dftest1 DF:add-calc-col "Join" [r -> (word (item 0 r) " " (item 1 r))] dftest
DF:print dftest1
DF:foreach dftest [r -> print r]
print DF:map [x -> first x] dftest
end
~~~~