es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Manejo de conjuntos de datos grandes en HDBSCAN

Estoy intentando implementar un agrupamiento en un conjunto de datos grande que consta de 146,000 observaciones, utilizando el algoritmo HDBSCAN. Cuando agrupo estas observaciones con la medida de distancia Minkowski/Euclidiana (por defecto), el agrupamiento de todos los datos funciona bien y solo tarda 8 segundos. Sin embargo, estoy intentando realizar el agrupamiento con mi propia métrica. Esto funciona bien cuando se opera en un subconjunto de los datos, aunque es mucho más lento. Sin embargo, cuando intento implementarlo en el conjunto de datos completo, inmediatamente obtengo un error de memoria. Esto tiene sentido, dado que debido al tamaño del conjunto de datos, una matriz de distancia por pares ocuparía alrededor de 150GB. Sin embargo, esto me hace preguntarme por qué no hay tal problema al usar la métrica por defecto, mientras que al mirar el código fuente de HDBSCAN veo que en ese caso también se llama a las distancias por pares de Sklearn, que devolverá la matriz completa. Además, me pregunto si habría una solución para mi métrica o si la única solución es tener acceso a +- 150GB de RAM.

El código para mi métrica y algunos resultados:

import hdbscan
import pandas as pd
import time
import numpy as np
from numpy.linalg import norm

def spex_distance(a, b):
    euclidean = norm(a[:2] - b[:2])
    exp_vec_a, exp_vec_b = a[2:], b[2:]
    cos_sim = np.dot(exp_vec_a, exp_vec_b) / (norm(exp_vec_a) * norm(exp_vec_b))
    if cos_sim > 0:
        return euclidean / cos_sim
    else:
        return np.inf

def main():
    data = pd.read_pickle(file_location)
    small_data = data[:1000]

t0 = time.time()
hdb_custom = hdbscan.HDBSCAN(metric=spex_distance)
hdb_custom.fit(small_data)
print(f"Tiempo necesario para agrupar un subconjunto con la métrica personalizada: {time.time()-t0}") # 10 sec

t0 = time.time()
hdb_default = hdbscan.HDBSCAN()
hdb_default.fit(small_data)
print(f"Tiempo necesario para agrupar un subconjunto con la métrica por defecto: {time.time()-t0}") # 0.03 sec

t0 = time.time()
hdb_default.fit(data)
print(f"Tiempo necesario para agrupar el conjunto completo con la métrica por defecto: {time.time()-t0}") # 9 sec

hdb_custom.fit(data) # falla con error de memoria
Tags:  , ,

Answer

  1. Avatar for davy.ai

    La dificultad que se enfrenta es que, al realizar el agrupamiento con una métrica personalizada en todo el conjunto de datos de 146,000 observaciones, se encuentra un error de memoria debido a que la matriz de distancia por pares ocupa aproximadamente 150 GB de memoria. Sin embargo, no hay tal problema de memoria cuando se utiliza la métrica por defecto. Esto parece contradictorio, dado que el algoritmo HDBSCAN llama a las distancias por pares de Sklearn en ambos casos.

    Una posible explicación podría ser que la métrica por defecto, es decir, la distancia Minkowski/Euclidiana, es una matriz de distancia precalculada que se está utilizando en lugar de una matriz de distancia por pares. En cambio, la métrica personalizada se está calculando por pares, lo que conduce al error de memoria.

    Una posible solución temporal podría ser utilizar un número menor de observaciones como punto de partida y luego filtrar los resultados utilizando un criterio apropiado. Este enfoque se conoce como “agrupamiento aproximado” y se podría implementar utilizando un método de submuestreo que proporcione una muestra representativa de los datos que se pueden agrupar sin quedarse sin memoria. Estas submuestras podrían ser agrupadas con la métrica personalizada, y los resultados se pueden refinar utilizando varios criterios de agrupamiento. Otro enfoque podría ser utilizar un algoritmo de agrupamiento diferente que no dependa de las métricas de distancia por pares, como K-means o agrupamiento jerárquico.

    En general, la solución más eficiente y escalable sería utilizar un entorno de informática distribuida, como Apache Spark, para realizar el agrupamiento. Con este sistema, sería posible dividir el conjunto de datos en múltiples nodos y realizar el agrupamiento en paralelo mientras se evitan los problemas de memoria encontrados con una sola máquina.

Comments are closed.