Cambios en los resultados de agrupamiento después de cada ejecución en Python scikit-learn

Tengo un montón de oraciones y quiero agruparlas usando el agrupamiento espectral de scikit-learn. He ejecutado el código y obtuve los resultados sin ningún problema. Pero, cada vez que lo ejecuto obtengo diferentes resultados. Sé que este es el problema con la iniciación, pero no sé cómo solucionarlo. Esta es mi parte de mi código que se ejecuta en oraciones:

vectorizer = TfidfVectorizer(norm='l2',sublinear_tf=True,tokenizer=tokenize,stop_words='english',charset_error="ignore",ngram_range=(1, 5),min_df=1) X = vectorizer.fit_transform(data) # connectivity matrix for structured Ward connectivity = kneighbors_graph(X, n_neighbors=5) # make connectivity symmetric connectivity = 0.5 * (connectivity + connectivity.T) distances = euclidean_distances(X) spectral = cluster.SpectralClustering(n_clusters=number_of_k,eigen_solver='arpack',affinity="nearest_neighbors",assign_labels="discretize") spectral.fit(X) 

Los datos son una lista de oraciones. Cada vez que se ejecuta el código, mis resultados de agrupamiento difieren. ¿Cómo puedo obtener resultados consistentes utilizando la agrupación espectral? También tengo el mismo problema con Kmean. Este es mi código para Kmean:

 vectorizer = TfidfVectorizer(sublinear_tf=True,stop_words='english',charset_error="ignore") X_data = vectorizer.fit_transform(data) km = KMeans(n_clusters=number_of_k, init='k-means++', max_iter=100, n_init=1,verbose=0) km.fit(X_data) 

Aprecio tu ayuda.

Al usar k-means, desea establecer el parámetro KMeans en KMeans (consulte la documentación ). Establézcalo en una instancia int o en una instancia de RandomState .

 km = KMeans(n_clusters=number_of_k, init='k-means++', max_iter=100, n_init=1, verbose=0, random_state=3425) km.fit(X_data) 

Esto es importante porque k-means no es un algoritmo determinista. Por lo general, comienza con algún procedimiento de inicialización aleatoria, y esta aleatoriedad significa que diferentes ejecuciones comenzarán en diferentes puntos. La siembra del generador de números pseudoaleatorios garantiza que esta aleatoriedad siempre será la misma para las semillas idénticas.

Sin embargo, no estoy seguro del ejemplo del agrupamiento espectral. De la documentación en el parámetro random_state : “Un generador de números pseudoaleatorios utilizado para la inicialización de la descomposición de vectores de eigen eigen_solver == 'amg' cuando eigen_solver == 'amg' y por la inicialización K-Means”. El código de OP no parece estar contenido en esos casos, aunque la configuración del parámetro podría valer la pena.

Como los otros ya han señalado, k-means se implementa generalmente con inicialización aleatoria . Es intencional que puedas obtener diferentes resultados.

El algoritmo es sólo una heurística. Puede producir resultados subóptimos. Si lo ejecuta varias veces, tendrá más posibilidades de encontrar un buen resultado.

En mi opinión, cuando los resultados varían mucho de una ejecución a otra, esto indica que los datos simplemente no se agrupan bien con k-means en absoluto. Sus resultados no son mucho mejores que los aleatorios en tal caso. Si los datos son realmente adecuados para el agrupamiento de k-means, ¡los resultados serán bastante estables! Si varían, los grupos pueden no tener el mismo tamaño, o pueden no estar bien separados; y otros algoritmos pueden dar mejores resultados.

Tuve un problema similar, pero es que quería que el conjunto de datos de otra distribución se agrupara de la misma manera que el conjunto de datos original. Por ejemplo, todas las imágenes en color del conjunto de datos original estaban en el cluster 0 y todas las imágenes en gris del conjunto de datos original estaban en el cluster 1 . Para otro conjunto de datos, quiero que las imágenes en color / gris estén en el cluster 0 y en el cluster 1 también.

Aquí está el código que robé de un Kaggler. Además de establecer random_state en una semilla, usas el modelo k-mean devuelto por KMeans para agrupar el otro conjunto de datos. Esto funciona razonablemente bien. Sin embargo, no puedo encontrar el documento oficial de scikit-Learn diciendo eso.

 # reference - https://www.kaggle.com/kmader/normalizing-brightfield-stained-and-fluorescence from sklearn.cluster import KMeans seed = 42 def create_color_clusters(img_df, cluster_count = 2, cluster_maker=None): if cluster_maker is None: cluster_maker = KMeans(cluster_count, random_state=seed) cluster_maker.fit(img_df[['Green', 'Red-Green', 'Red-Green-Sd']]) img_df['cluster-id'] = np.argmin(cluster_maker.transform(img_df[['Green', 'Red-Green', 'Red-Green-Sd']]),-1) return img_df, cluster_maker # Now K-Mean your images `img_df` to two clusters img_df, cluster_maker = create_color_clusters(img_df, 2) # Cluster another set of images using the same kmean-model another_img_df, _ = create_color_clusters(another_img_df, 2, cluster_maker) 

Sin embargo, incluso establecer random_state en un valor int seed no puede garantizar que los mismos datos siempre se agruparán en el mismo orden en todas las máquinas. Los mismos datos pueden agruparse como group 0 en una máquina y agruparse como group 1 en otra máquina. Pero al menos con el mismo modelo K-Means ( cluster_maker en mi código) nos aseguramos de que los datos de otra distribución se agrupen de la misma manera que el conjunto de datos original.

Normalmente, cuando se ejecutan algoritmos con muchos mínimos locales, es común adoptar un enfoque estocástico y ejecutar el algoritmo muchas veces con diferentes estados iniciales. Esto le dará múltiples resultados, y el que tenga el error más bajo generalmente se elige como el mejor resultado.

Cuando uso K-Means siempre lo ejecuto varias veces y uso el mejor resultado.