Cómo trazar la matriz de confusión / similitud de un algoritmo de media K

Aplico un algoritmo K-mean para clasificar algunos documentos de texto usando scikit learn y mostrar el resultado del agrupamiento. Me gustaría mostrar la similitud de mi grupo en una matriz de similitud. No vi ninguna herramienta en la biblioteca de aprendizaje de scikit que permita hacerlo.

# headlines type:  tf-idf vectors pca = PCA(n_components=2).fit(headlines) data2D = pca.transform(to_headlines) pl.scatter(data2D[:, 0], data2D[:, 1]) km = KMeans(n_clusters=4, init='k-means++', max_iter=300, n_init=3, random_state=0) km.fit(headlines) 

¿Hay alguna forma / biblioteca que me permita dibujar fácilmente esta matriz de similitud de coseno?

Si lo entiendo bien, le gustaría producir una matriz de confusión similar a la que se muestra aquí . Sin embargo, esto requiere una truth y una prediction que puedan compararse entre sí. Suponiendo que tiene algún estándar de oro para la clasificación de sus titulares en k grupos (la truth ), podría comparar esto con la agrupación de KMeans (la prediction ).

El único problema con esto es que la agrupación de KMeans es ajena a su truth , lo que significa que las tags de agrupación que produce no coincidirán con las tags de los grupos estándar de oro. Sin embargo, hay una kmeans labels para esto, que es hacer coincidir las kmeans labels con las truth labels basadas en la mejor coincidencia posible.

Aquí hay un ejemplo de cómo podría funcionar esto.


Primero, generemos algunos datos de ejemplo : en este caso 100 muestras con 50 características cada una, muestreadas a partir de 4 distribuciones normales diferentes (y ligeramente superpuestas). Los detalles son irrelevantes; Todo lo que se supone que debe hacer es imitar el tipo de conjunto de datos con el que podría estar trabajando. La truth en este caso es la media de la distribución normal a partir de la cual se generó una muestra.

 # User input n_samples = 100 n_features = 50 # Prep truth = np.empty(n_samples) data = np.empty((n_samples, n_features)) np.random.seed(42) # Generate for i,mu in enumerate(np.random.choice([0,1,2,3], n_samples, replace=True)): truth[i] = mu data[i,:] = np.random.normal(loc=mu, scale=1.5, size=n_features) # Show plt.imshow(data, interpolation='none') plt.show() 

datos de ejemplo


A continuación, podemos aplicar el PCA y KMeans .

Tenga en cuenta que no estoy seguro de cuál es exactamente el punto de la PCA en su ejemplo, ya que en realidad no está utilizando las PC para su KMeans, además de que no está claro cuál es el conjunto de datos de to_headlines , qué transforma.

Aquí, estoy transformando los datos de entrada en sí mismos y luego utilizo las PC para el agrupamiento de KMeans. También estoy usando la salida para ilustrar la visualización que Saikat Kumar Dey sugirió en un comentario a su pregunta: un diagtwig de dispersión con puntos coloreados por etiqueta de grupo.

 # PCA pca = PCA(n_components=2).fit(data) data2D = pca.transform(data) # Kmeans km = KMeans(n_clusters=4, init='k-means++', max_iter=300, n_init=3, random_state=0) km.fit(data2D) # Show plt.scatter(data2D[:, 0], data2D[:, 1], c=km.labels_, edgecolor='') plt.xlabel('PC1') plt.ylabel('PC2') plt.show() 

pca kmeans


A continuación, tenemos que encontrar los pares que mejor se correspondan entre las truth labels que generamos al principio (aquí el mu de las distribuciones normales muestreadas) y las kmeans labels generadas por el agrupamiento.

En este ejemplo, simplemente los comparo de tal manera que se maximice el número de predicciones verdaderas positivas. ¡Tenga en cuenta que esta es una solución simplista, rápida y sucia!

Si sus predicciones son bastante buenas en general y si cada grupo está representado por un número similar de muestras en su conjunto de datos, probablemente funcionará según lo previsto. De lo contrario, puede producir desajustes / fusiones y puede sobreestimar un poco la calidad de su agrupación como resultado.

Sugerencias para mejores soluciones son bienvenidas.

 # Prep k_labels = km.labels_ # Get cluster labels k_labels_matched = np.empty_like(k_labels) # For each cluster label... for k in np.unique(k_labels): # ...find and assign the best-matching truth label match_nums = [np.sum((k_labels==k)*(truth==t)) for t in np.unique(truth)] k_labels_matched[k_labels==k] = np.unique(truth)[np.argmax(match_nums)] 

Ahora que hemos comparado truths y predictions , finalmente podemos calcular y trazar la matriz de confusión .

 # Compute confusion matrix from sklearn.metrics import confusion_matrix cm = confusion_matrix(truth, k_labels_matched) # Plot confusion matrix plt.imshow(cm,interpolation='none',cmap='Blues') for (i, j), z in np.ndenumerate(cm): plt.text(j, i, z, ha='center', va='center') plt.xlabel("kmeans label") plt.ylabel("truth label") plt.show() 

matriz de confusión


¡Espero que esto ayude!