Estoy trabajando con una data diferente a la presentada y creo que esto podría servir. En algunos casos por la disposición de los datapoints, puede que el DBSCAN solo genere un cluster, lo que va generar un error en el loop donde se evalua multiples parámetros.
Esta es la solución:
<code> dbscan_paramns =list(product(eps_values,min_samples))sil_scores =[]labels =0for p indbscan_paramns: y_pred =DBSCAN(eps= p[0], min_samples=p[1]).fit_predict(X), y_pred = np.array(y_pred).ravel()iflen(np.unique(y_pred))<2:print(f'Parameters: {p[0]} and {p[1]}')else: sil_scores.append(silhouette_score(X,y_pred))
Hoy he aprendido que también existe una técnica de la rodilla 😎
JAJAJAJ see
Hola! Tengo una duda sobre los hiper-parámetros. Realicé todo el procedimiento con una base de datos que tenía, varié el epsilon y los min_samples según la escala del ejemplo (junto con el procedimiento de kneighbors y el mapa de calor para ver cuáles valores serían mejores), cuando corrí el resultado solo me salían dos clusters {0,-1}. luego decidí cambiar el epsilon manualmente, para que en lugar de empezar en 0.25, empezara en 0.001, y ahí ya empezó a aumentar el número de clusters. No me queda claro uno cómo puede saber desde qué valor puede empezar a variar el epsilon, no se si es según el tipo de datos que se tienen (en mi caso eran coordenadas geográficas) o si hay alguna guía adicional para definir los valores. Me queda esa duda.
Muchas gracias!
Alguien sabe si estos hiperparametros se pueden encontrar con gridsearch?
from itertools import product
params = pd.DataFrame({'epsilon':[],'min_samples':[],'silhouette_score':[]})for eps, n in product(np.linspace(.2,.4,10), np.arange(2,10)): y_pred = DBSCAN(eps=eps, min_samples=n).fit_predict(X) params.loc[len(params)]=[eps, n, silhouette_score(X, y_pred)]
¿Porque se analizó con distances[:,1] y no con distances[:2]?
Adicionalmente se supone que se eligen 3 vecimos pero la primera distancia de cada uno de estos resulta 0, entonces ¿El algortimo NearestNeighbors considera su propio valor como su propio vecino?
se quiere para este caso el mas cercano
Puedes realizar la visualización con los tres vecinos mas cercanos y te puedes dar cuenta que el mas cercano es el de la posición 0 y están tan cerca que llegan a traslaparse y dar casi una distancia de 0.
La linea azul es la distancia del datapoint con su 1er vecino mas cercano, el naranja con el 2do y finalmente el verde con el 3ro.
from sklearn.neighborsimportNearestNeighborsneighbors =NearestNeighbors(n_neighbors=3)neighbors_fit = neighbors.fit(X)distances, index = neighbors_fit.kneighbors()distances = np.sort(distances, axis=0)distances_most_nearest = distances[:,0]plt.plot(distances)
Me surgió la duda de como determinaba el profe el rango indicado de eps\_values y min\_sample\_values. Entonces hablando con mi pana chat_gpt rehice el codigo para que sea un poco más a prueba de balas y siempre me traiga las mejores combinaciones independientemente de mi rango de eps y samples:
eps_values = np.arange(0.20,1.1,0.05)min_samples_values = np.arange(2,10)results =[]dbscan_params =product(eps_values, min_samples_values)for eps, min_samples indbscan_params: y_pred =DBSCAN(eps=eps, min_samples=min_samples).fit_predict(X) # Número de clusters sin contar el ruido(-1) unique_clusters =set(y_pred) unique_clusters_no_noise = unique_clusters -{-1} # silhouette ∈ solo si hay al menos 2 clusters
iflen(unique_clusters_no_noise)>=2: score =silhouette_score(X, y_pred) results.append({"eps": eps,"min_samples": min_samples,"n_clusters":len(unique_clusters_no_noise),"silhouette_score": score
})sil_scores_df = pd.DataFrame(results)# Top resultados válidos
best = sil_scores_df.sort_values("silhouette_score", ascending=False)# Obtener los mejores parámetros
eps_best = best["eps"].head(1).values[0]min_samples_best = best["min_samples"].head(1).values[0]print(f"Mejor eps: {eps_best}, mejor min_samples: {min_samples_best}")best.head(5)
¿De qué sirvió el grafico de rodilla?
Al final el se tomaron en cuenta solo los valores que vimos en el HeatMap
no entendi porque min_samples va de 2 a 10, si tendría 200 000 registros, ¿igual el seria de 2 a 10 en min_samples ?
El rango de min_samples de 2 a 10 es solo un ejemplo. En tu caso, con 200,000 registros, puedes ajustar el valor de min_samples según tus necesidades y el tamaño de tu muestra. No hay una regla fija, depende del contexto y los objetivos del análisis.
los registros creo que no importan sino lo que importan son las dimensiones en este caso los features*2 es un buen numero para empezar
Cuando buscamos los mejores hiper-parámetros me sale este error
eps_values = np.arange(0.3,0.6,0.1)min_samples = np.arange(2,10)dbscan_params =list(product(eps_values, min_samples))sil_scores =[]for param indbscan_params: model =DBSCAN(eps=param[0], min_samples=param[1]) y_pred = model.fit_predict(X) sil_scores.append(silhouette_score(X, y_pred, metric='euclidean'))ValueError:Numberof labels is 1.Valid values are 2 to n_samples -1(inclusive)````Investigué y ocurre cuando el numero de clusters es 1 ¿Alguna idea para arreglar el error?Yo intente agregar este código
```if np.unique(model.labels_).size == 1:
continue
```Pero entonces hay combinaciones de parametros sin sil score asociado... qué hacer? ¿Poner un -1 para descartarlo?
Puedes darle un valor NaN, pd.nan, np.nan o cualquier nulo y después un dorpnan() para eliminar esos values del sil_score ya en la pivot table.
¡Hola!
Cuál sería la rodilla en esta gráfica?
Sería entre 0.4 a 0.65 la iteración.
Ya que escogiendo 0.4 estas capturando aprox 175 datos de los 200 que tienes.
Y si eres mas laxo y escoges 0.65 entonces capturas el de 190 datos aprox.
Es decir, con un cambio grande de Eps solo estas capturando 15 datapoints mas, esos quizás ya serian ruido.
Que es min_samples?
Que pasa si mis mejores parametros me dan como mejor resultado un solo cluster?
no entendi porque min_samples va de 2 a 10, si veo que en la grafica la rodilla en el eje x tiene valores de 0 a 500
Del grafico de rodilla tomamos unicamente el valor para el epsilon. min_samples es el valor que le damos a criterio para la cantidad de muestras.
min_muestras int, por defecto=5El número de muestras(o peso total) en una vecindad para que un punto se considere un punto central.Esto incluye el punto en sí.
# metodo para sintonizar los hiperparametros que mejor se ajusten para dbscan# se usara el conjunto de datos X# Parameter grideps_values = np.arange(0.2, 0.8, 0.1)min_samples = np.arange(2, 10)sil_scores = np.zeros((len(min_samples), len(eps_values)))# Compute silhouette scoresfor i, m in enumerate(min_samples): for j, e in enumerate(eps_values): model = DBSCAN(eps=e, min_samples=m) labels = model.fit_predict(X) score = silhouette_score(X, labels) sil_scores[i, j] = score# Display heatmapplt.figure(figsize=(8, 6))sns.heatmap(sil_scores, annot=True, fmt=".2f", xticklabels=np.round(eps_values,2), yticklabels=min_samples, cmap="coolwarm")plt.xlabel("eps values")plt.ylabel("min_samples")plt.title("Silhouette Score Heatmap for DBSCAN Parameters")plt.show()
Gracias a Chat GPT:
La diferencia entre parámetros e hiperparámetros en el contexto del aprendizaje automático es la siguiente:
- **Parámetros:** Son valores internos del modelo que se aprenden directamente a partir de los datos durante el proceso de entrenamiento. Por ejemplo, en una regresión lineal, los coeficientes de la ecuación son parámetros del modelo.
- **Hiperparámetros:** Son configuraciones externas al modelo que se establecen antes del proceso de entrenamiento y no se aprenden directamente de los datos. Los hiperparámetros controlan el proceso de aprendizaje y la estructura del modelo. En el caso de DBSCAN, eps y min\_samples son hiperparámetros porque se deben definir antes de entrenar el modelo y afectan cómo se identifican los clusters en los datos.
En resumen, los **parámetros** son ajustados por el modelo durante el entrenamiento, mientras que los **hiperparámetros** son configuraciones establecidas por el usuario para guiar el proceso de aprendizaje del modelo.
A mi me salió este error: ---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
Cell In[21], line 2
1 distances = np.sort(distances,axis=0)
----> 2 distances = distances[:,1]
3 plt.plot(distances)
IndexError: too many indices for array: array is 1-dimensional, but 2 were indexed lo resolví de esta manera para que apareciera el gráfico del minuto 3:35 distances = np.sort(distances)second_element = distances[1]plt.plot(distances)
Probando hiperparámetros al azar, no tuve buenos resultados:
Iterando para conocer los mejores hiperparámetros:
Obteniendo un mejor resultado conociendo que hiperparámetros probar:
¡Excelente sesión!
No parece muy buena idea aplicar clustering al set de datos que estas usando.
Es importante aclarar que la técnica de la "rodilla" no es específica de DBSCAN, sino que se refiere a un método utilizado para determinar el valor óptimo de un parámetro en diversos algoritmos o análisis. En el contexto de DBSCAN, el parámetro que a menudo se ajusta es el "epsilon", que representa el radio máximo de vecindad para considerar que dos puntos pertenecen al mismo cluster.