sklearn scikit medoids learn clusters clusterization clustering cluster scikit-learn cluster-analysis data-mining predict dbscan

scikit-learn - scikit - k medoids sklearn



Scikit-Learn: Predicción de nuevos puntos con DBSCAN (3)

Aquí una implementación ligeramente diferente y más eficiente. Además, en lugar de tomar el primer mejor punto central que está dentro del radio de eps, se toma el punto central más cercano a la muestra.

def dbscan_predict(model, X): nr_samples = X.shape[0] y_new = np.ones(shape=nr_samples, dtype=int) * -1 for i in range(nr_samples): diff = model.components_ - X[i, :] # NumPy broadcasting dist = np.linalg.norm(diff, axis=1) # Euclidean distance shortest_dist_idx = np.argmin(dist) if dist[shortest_dist_idx] < model.eps: y_new[i] = model.labels_[model.core_sample_indices_[shortest_dist_idx]] return y_new

Estoy usando DBSCAN para agrupar algunos datos usando Scikit-Learn (Python 2.7):

from sklearn.cluster import DBSCAN dbscan = DBSCAN(random_state=0) dbscan.fit(X)

Sin embargo, descubrí que no había una función integrada (aparte de "fit_predict") que pudiera asignar los nuevos puntos de datos, Y, a los grupos identificados en los datos originales, X. El método K-means tiene una "predicción" Funciona pero quiero poder hacer lo mismo con DBSCAN. Algo como esto:

dbscan.predict(X, Y)

De modo que la densidad se puede inferir de X pero los valores de retorno (asignaciones de clúster / etiquetas) son solo para Y. Por lo que puedo decir, esta capacidad está disponible en R, por lo que supongo que también está disponible de alguna manera en Python. Simplemente no puedo encontrar ninguna documentación para esto.

Además, he intentado buscar razones por las cuales DBSCAN no se puede usar para etiquetar nuevos datos, pero no he encontrado ninguna justificación.


La agrupación no es clasificación.

La agrupación es sin etiqueta. Si desea integrarlo en una mentalidad de predicción (que no es la mejor idea), entonces predice esencialmente sin aprendizaje . Porque no hay datos de entrenamiento etiquetados disponibles para la agrupación. Debe crear nuevas etiquetas para los datos, en función de lo que ve. Pero no puede hacer esto en una sola instancia, solo puede "predecir en masa".

Pero hay algo mal con scipys DBSCAN:

random_state : numpy.RandomState, opcional:

El generador utilizado para inicializar los centros. Por defecto es numpy.random.

DBSCAN no "inicializa los centros", porque no hay centros en DBSCAN.

Más o menos, el único algoritmo de agrupación en clúster en el que puede asignar nuevos puntos a los clústeres anteriores es k-means (y sus numerosas variaciones). Debido a que realiza una "clasificación 1NN" utilizando los centros de agrupaciones de iteraciones anteriores, a continuación, actualiza los centros. Pero la mayoría de los algoritmos no funcionan como k-means, por lo que no puedes copiar esto.

Si desea clasificar los puntos nuevos, es mejor entrenar un clasificador en el resultado de su agrupación.

Lo que tal vez esté haciendo la versión R, es usar un clasificador 1NN para la predicción; quizás con la regla adicional de que a los puntos se les asigna la etiqueta de ruido, si su distancia de 1NN es mayor que épsilon, mabye también usa solo los puntos centrales. Tal vez no.

Obtenga el documento DBSCAN, no discute la "predicción" IIRC.


Si bien Anony-Mousse tiene algunos puntos buenos (la agrupación no está clasificando) creo que la capacidad de asignar nuevos puntos tiene su utilidad. *

Basándome en el documento original sobre DBSCAN y las ideas de github.com/scikit-learn en github.com/scikit-learn , sugiero que se ejecute a través de los puntos centrales y se asigne al grupo del primer punto central que se encuentra dentro de eps de su nuevo punto. Entonces se garantiza que su punto será al menos un punto de borde del clúster asignado de acuerdo con las definiciones utilizadas para el clúster. (Tenga en cuenta que su punto podría considerarse ruido y no asignarse a un grupo)

He hecho una implementación rápida:

import numpy as np import scipy as sp def dbscan_predict(dbscan_model, X_new, metric=sp.spatial.distance.cosine): # Result is noise by default y_new = np.ones(shape=len(X_new), dtype=int)*-1 # Iterate all input samples for a label for j, x_new in enumerate(X_new): # Find a core sample closer than EPS for i, x_core in enumerate(dbscan_model.components_): if metric(x_new, x_core) < dbscan_model.eps: # Assign label of x_core to x_new y_new[j] = dbscan_model.labels_[dbscan_model.core_sample_indices_[i]] break return y_new

Las etiquetas obtenidas por agrupamiento ( dbscan_model = DBSCAN(...).fit(X) y las etiquetas obtenidas del mismo modelo en los mismos datos ( dbscan_predict(dbscan_model, X) ) a veces difieren. No estoy seguro si esto Es un error en algún lugar o un resultado de aleatoriedad.

EDITAR: Creo que el problema anterior de los diferentes resultados de predicción podría surgir de la posibilidad de que un punto de borde pueda estar cerca de múltiples agrupaciones. Por favor, actualice si prueba esto y encuentra una respuesta. La ambigüedad se puede resolver mezclando los puntos centrales cada vez o seleccionando el más cercano en lugar del primer punto central.

*) Caso en cuestión: me gustaría evaluar si los grupos obtenidos de un subconjunto de mis datos tienen sentido para otro subconjunto o es simplemente un caso especial. Si se generaliza, es compatible con la validez de los clústeres y los pasos anteriores del preprocesamiento aplicado.