<jupyter_start><jupyter_text>Clustering<jupyter_code>import numpy as np<jupyter_output><empty_output><jupyter_text>***2. Un sistema recibe un flujo de datos numéricos que se necesitan asignar a un cluster utilizando K-Means online, con k = 3. Considerando que la inicialización se hace con los primeros 6 datos del stream, y luego a continuación vienen 4 datos más, realizar el seguimiento indicando cómo se comporta el algoritmo para generar los clusters, y cuál es el resultado final luego de procesar los primeros 10 elementos: 2, 6, 7, 18, 1, 9, 0, 3, 4 y 23.*** Primero tenes 6 datos iniciales: $2, 6, 7, 18, 1, 9$ y ahora debemos calcular los clusters de cada uno:```_,1,2,_,_,_,6,7,_,9,_,_,_,_,_,_,_,_,18```Vemos a ojo que, usando la distancia Euclídea los clusters iniciales son: $\{1,2\}, \{6,7,9\}, \{18\}$ y sus centroides correspondientes son: $1.5, 7.33, 18$. Ahora debemos ejecutar el resto de K-Means online viendo como van entrando los puntos y recalculando los centroides de forma dinámica. La fórmula es:$C_j = C_j + \frac{X_i - C_j}{N_j}$Siendo $X_i$ el elemento que entra y $N_j$ el tamaño del cluster (incluyendo el ítem nuevo). Ingresa el 0 y pertenece al primer cluster pues es el que minimiza la distancia para todos los clusters disponible. Por lo tanto el primer centroide pasa a ser:```C_1 := 1.5 + (0 - 1.5)/3 = 1```Ingresa el 3 y, otra vez, ingresa al primer cluster:```C_1 := 1 + (3 - 1)/4 = 1.5```Ingresa el 4 y también pertenece al primer cluster:```C_1 := 1.5 + (4 - 1.5)/5 = 2```Y finalmente entra el 23 el cual tiene que, si o si, pertenecer al último cluster:```C_3 := 18 + (23 - 18)/2 = 20.5```Por lo tanto al final los clusters son: $\{0,1,2,3,4\}, \{6,7,9\}, \{18,23\}$. ***3. Se tiene la siguiente tabla en donde cada fila es un usuario y cada columna es una categoría de películas. la tabla indica con una escala de 0 a 1 si al usuario le gusta o no la categoría.*** | Usuario | Western | Comedia | Acción | Ciencia Ficción ||---------|---------|---------|--------|-----------------|| Alice   | 0,2     | 0,6     | 0,5    | 0,1             || Bob     | 0,7     | 0,4     | 0,7    | 0,4             || Charly  | 0,1     | 0,6     | 0,7    | 0,9             || Diane   | 0,5     | 0,1     | 0,9    | 0,8             || Ethan   | 0,2     | 0,4     | 0,5    | 0,6             | ***Se quieren encontrar dos clusters. Explicar de qué forma se aplicaría clustering espectral a partir de los datos proporcionados.*** Sea $X \in \mathbb{R}^{4x5}$ la matriz de 4 datos en 5 dimensiones. Para transformarla en ungrafo vamos a usar el mismo proceso que se ha utilizado en Laplacian Eigenmaps.Primero construimos la matriz de afinidad, esta siempre es simétrica y positiva.. Luego, construimos la matriz Laplaciana, la matriz Laplaciana tiene varias construcciones posibles pero la mas comun es: $L = D - W$Siendo $D$ la matriz diagonal con el grado de cada vertice del grafo, donde por grado se entiende la suma de cada columna de $W_{ij}$.El siguiente paso es descomponer la matriz Laplaciana en sus autovalores y autovectores y determinar la cantidad de autovectores a usar. ***4. Se tienen los centroides [0 0] y [100 40]. Dados los siguientes puntos, indicar para cuál de ellos cambiaría el centroide al cual queda asignado según si se usa distancia Manhattan o Euclídea:[53 15] [51 15] [50 18] [52 13]***<jupyter_code>centroides = [(0,0),(100,40)]
puntos = [(53,15), (51,15), (50,18), (52,13)]
euclidea  = lambda x,y: np.sqrt((x[0] - y[0])**2 + (x[1] - y[1])**2)
manhattan = lambda x,y: abs(x[0] - y[0]) + abs(x[1] - y[1])
for p in puntos:
    d_origen = euclidea(centroides[0], p)
    d_cien = euclidea(centroides[1], p)
    al_origen = d_origen < d_cien
    destino = (al_origen) * "el origen" + (not al_origen) * "el punto 100,40"
    print(f"El punto {tuple(p)} va al cluster con centroide en {destino}")
for p in puntos:
    d_origen = manhattan(centroides[0], p)
    d_cien = manhattan(centroides[1], p)
    al_origen = d_origen < d_cien
    destino = (al_origen) * "el origen" + (not al_origen) * "el punto 100,40"
    print(f"El punto {tuple(p)} va al cluster con centroide en {destino}")<jupyter_output>El punto (53, 15) va al cluster con centroide en el origen
El punto (51, 15) va al cluster con centroide en el origen
El punto (50, 18) va al cluster con centroide en el origen
El punto (52, 13) va al cluster con centroide en el origen<jupyter_text>***5. Dados los siguientes puntos en dos dimensiones: [5 1] [5 3] [4 4] [9 4] [10 3] [11 6] aplicar K-Means comenzando con los centroides [8 1] y [7 5].***<jupyter_code>def kmeans2D(iteraciones, puntos, centroides):
    clusters = [[[],p] for p in centroides]
    for i in range(iteraciones):
        for p in puntos:
            if euclidea(p, clusters[0][1]) < euclidea(p, clusters[1][1]):
                clusters[0][0].append(p)
            else:
                clusters[1][0].append(p)
        if i == iteraciones - 1:
            return clusters
        primer_cluster = clusters[0][0]
        segundo_cluster = clusters[1][0]
        clusters[0][0] = []
        clusters[1][0] = []
        clusters[0][1] = (sum([x[0] for x in primer_cluster])/len(primer_cluster),
                          sum([x[1] for x in primer_cluster])/len(primer_cluster))
        clusters[1][1] = (sum([x[0] for x in segundo_cluster])/len(segundo_cluster),
                          sum([x[1] for x in segundo_cluster])/len(segundo_cluster))    
kmeans2D(5, [[5, 1], [5, 3], [4, 4], [9, 4], [10, 3], [11, 6]], ([8,1],[7,5]))<jupyter_output><empty_output><jupyter_text>Asumo que, como esto está pensado para hacerlo en papel, que va a converger rapidamente. ***6. Dados los siguientes puntos en dos dimensiones: [1 1] [2 1] [4 3] [5 4] aplicar K-Means tomando como centroides [1 1] y [2 1], realizando un desarrollo descriptivo paso a paso del algoritmo, incluyendo representación gráfica e indicando:******a. posición aproximada final de los centroides al converger;******b. clusters finales obtenidos.***<jupyter_code>kmeans2D(100, [[1,1], [2,1], [4,3], [5,4]], ([1,1], [2,1]))<jupyter_output><empty_output><jupyter_text>Los centroides serán $(1.5,1)$ y $(4.5,3.5)$ y sus respectivos puntos asociados a sus clusters son: $(1, 1), (2, 1)$ y $(4, 3), (5, 4)$. Que dios se lo desarrolle el paso a paso; la lógica está en el código jaja. ***4. Se tienen los centroides [0 0] y [100 40]. Dados los siguientes puntos, indicar para cuál de ellos cambiaría el centroide al cual queda asignado según si se usa distancia Manhattan o Euclídea:[53 15] [51 15] [50 18] [52 13]*** ***8. Considerar los siguientes puntos en una dimensión y la clase a la que pertenece cada punto (en formato “(número clase)” ): (5 b) (10 b) (2 b) (6 a) (7 b) (8 b) (0 a) (13 b) (16 b) (1 a) (3 a) (17 b). Se quiere usar KNN para clasificar los puntos con la distancia Manhattan. Con el objetivo de encontrar el valor óptimo de K (cantidad de vecinos), se utiliza Cross-Validation con folds de 4 registros. Considerar los folds en el orden en que fueron presentados los puntos ( Ejemplo: primer fold tiene a (5 b) (10 b) (2 b) (6 a) ).Determinar el valor óptimo de K realizando Grid-Search para tres valores posibles: 1, 3 y 5. Usar comométrica la precisión (accuracy).*** Debo tomar el primer fold y calcular todas las distancias al punto 5. Luego quedarme con los $k = 1$ ítems más cercanos y asignar a mi elemento al conjunto más seleccionado de entre mis k puntos. Si selecciono bien sumo un puntito para mi valor de $k$ que estoy usando.Luego para el segundo fold (del cuarto a octavo elemento) hacemos lo mismo, para cada punto nos quedamos con los $k = 3$ más cercanos y categorizamos a nuestro elemento con los 3 más categorizados. Si lo hace bien le damos puntaje a nuestro valor actual de $k$.Así para los 3 folds y nos quedamos con el $k$ que más puntos haya conseguido. ***10. Dados los siguientes puntos:***```[1 2] [1 3] [1 5] [2 3] [2 8] [3 3] [4 1] [4 9] [7 8] [9 9] [12 2] [13 4]```***agruparlos utilizando Clustering Jerárquico, indicando la cantidad de clusters resultantes, y el criterio utilizado para definir dicho número. Representar el dendrograma mostrando cómo se agrupan los distintos elementos en los clusters obtenidos.***<jupyter_code>def jerarquico(puntos):
    clusters = [[p] for p in puntos]
    while len(clusters) != 1:
        minimal = float('inf')
        for cluster in clusters:
            minimal = mini
    ...
jerarquico([[1, 2], [1, 3], [1, 5], [2, 3], [2, 8], [3, 3],
            [4, 1], [4, 9], [7, 8], [9, 9], [12, 2], [13, 4]])<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13011456628477905, 'fraction_numerical': 0.05272387187280804, 'mean_word_length': 3.5456960680127523, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 7, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '185667', 'license': 'MIT', 'n_tokens_mistral': 3297, 'n_tokens_neox': 3080, 'n_words': 1210, 'path': 'Clustering.ipynb', 'repo_name': 'Jonathan-R0/Final-Organizacion-de-Datos', 'size': '8554'}