Introduction
Dans ce laboratoire, nous utiliserons l'algorithme de co-classement spectral sur l'ensemble de données des vingt groupes de news pour effectuer un co-classement bicluster des documents. L'ensemble de données contient 20 catégories de documents et nous exclurons la catégorie "comp.os.ms-windows.misc" car elle contient des messages sans données. Les messages vectorisés TF-IDF forment une matrice de fréquence de mots qui est ensuite co-classée bicluster en utilisant l'algorithme de co-classement spectral de Dhillon. Les co-classements bicluster document-mot résultants indiquent des sous-ensembles de mots utilisés plus fréquemment dans ces sous-ensembles de documents. Nous allons également regrouper les documents en utilisant MiniBatchKMeans pour la comparaison.
Conseils sur la machine virtuelle
Une fois le démarrage de la machine virtuelle terminé, cliquez dans le coin supérieur gauche pour basculer vers l'onglet Notebook pour accéder à Jupyter Notebook pour la pratique.
Parfois, vous devrez peut-être attendre quelques secondes pour que Jupyter Notebook ait fini de charger. La validation des opérations ne peut pas être automatisée en raison des limitations de Jupyter Notebook.
Si vous rencontrez des problèmes pendant l'apprentissage, n'hésitez pas à demander à Labby. Donnez votre feedback après la session et nous réglerons rapidement le problème pour vous.
Importation des bibliothèques
Nous allons importer les bibliothèques nécessaires pour ce laboratoire.
from collections import defaultdict
import operator
from time import time
import numpy as np
from sklearn.cluster import SpectralCoclustering
from sklearn.cluster import MiniBatchKMeans
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.cluster import v_measure_score
Définir le normalisateur de nombres
Nous allons définir une fonction number_normalizer() pour mapper tous les jetons numériques à un emplacement réservé. Cela est utilisé pour la réduction de la dimensionalité.
def number_normalizer(tokens):
"""Map all numeric tokens to a placeholder.
For many applications, tokens that begin with a number are not directly
useful, but the fact that such a token exists can be relevant. By applying
this form of dimensionality reduction, some methods may perform better.
"""
return ("#NUMBER" if token[0].isdigit() else token for token in tokens)
Définir NumberNormalizingVectorizer
Nous allons définir une classe NumberNormalizingVectorizer() qui hérite de TfidfVectorizer() pour construire un tokenizer qui utilise la fonction number_normalizer() que nous avons définie précédemment.
class NumberNormalizingVectorizer(TfidfVectorizer):
def build_tokenizer(self):
tokenize = super().build_tokenizer()
return lambda doc: list(number_normalizer(tokenize(doc)))
Charger et préparer les données
Nous allons charger l'ensemble de données des vingt groupes de news et exclure la catégorie "comp.os.ms-windows.misc". Nous allons également définir le vectorizer.
categories = [
"alt.atheism",
"comp.graphics",
"comp.sys.ibm.pc.hardware",
"comp.sys.mac.hardware",
"comp.windows.x",
"misc.forsale",
"rec.autos",
"rec.motorcycles",
"rec.sport.baseball",
"rec.sport.hockey",
"sci.crypt",
"sci.electronics",
"sci.med",
"sci.space",
"soc.religion.christian",
"talk.politics.guns",
"talk.politics.mideast",
"talk.politics.misc",
"talk.religion.misc",
]
newsgroups = fetch_20newsgroups(categories=categories)
y_true = newsgroups.target
vectorizer = NumberNormalizingVectorizer(stop_words="english", min_df=5)
Vectoriser les données
Nous allons vectoriser les données à l'aide du vectorizer que nous avons défini précédemment.
X = vectorizer.fit_transform(newsgroups.data)
Biclustering à l'aide de l'algorithme de co-clustering spectral
Nous allons effectuer un biclustering à l'aide de l'algorithme de co-clustering spectral en définissant le co-cluster et en l'ajustant aux données.
cocluster = SpectralCoclustering(
n_clusters=len(categories), svd_method="arpack", random_state=0
)
cocluster.fit(X)
y_cocluster = cocluster.row_labels_
Effectuer un clustering avec MiniBatchKMeans
Nous allons effectuer un clustering des données à l'aide de MiniBatchKMeans.
kmeans = MiniBatchKMeans(
n_clusters=len(categories), batch_size=20000, random_state=0, n_init=3
)
y_kmeans = kmeans.fit_predict(X)
Trouver les meilleurs biclusters
Nous allons trouver les meilleurs biclusters en calculant leur coupe normalisée et en sélectionnant les cinq premiers.
feature_names = vectorizer.get_feature_names_out()
document_names = list(newsgroups.target_names[i] for i in newsgroups.target)
def bicluster_ncut(i):
rows, cols = cocluster.get_indices(i)
if not (np.any(rows) and np.any(cols)):
import sys
return sys.float_info.max
row_complement = np.nonzero(np.logical_not(cocluster.rows_[i]))[0]
col_complement = np.nonzero(np.logical_not(cocluster.columns_[i]))[0]
weight = X[rows][:, cols].sum()
cut = X[row_complement][:, cols].sum() + X[rows][:, col_complement].sum()
return cut / weight
bicluster_ncuts = list(bicluster_ncut(i) for i in range(len(newsgroups.target_names)))
best_idx = np.argsort(bicluster_ncuts)[:5]
Afficher les résultats
Nous allons afficher les résultats des meilleurs biclusters trouvés à l'étape 8.
for idx, cluster in enumerate(best_idx):
n_rows, n_cols = cocluster.get_shape(cluster)
cluster_docs, cluster_words = cocluster.get_indices(cluster)
if not len(cluster_docs) or not len(cluster_words):
continue
## catégories
counter = defaultdict(int)
for i in cluster_docs:
counter[document_names[i]] += 1
cat_string = ", ".join(
"{:.0f}% {}".format(float(c) / n_rows * 100, name)
for name, c in most_common(counter)[:3]
)
## mots
out_of_cluster_docs = cocluster.row_labels_!= cluster
out_of_cluster_docs = np.where(out_of_cluster_docs)[0]
word_col = X[:, cluster_words]
word_scores = np.array(
word_col[cluster_docs, :].sum(axis=0)
- word_col[out_of_cluster_docs, :].sum(axis=0)
)
word_scores = word_scores.ravel()
important_words = list(
feature_names[cluster_words[i]] for i in word_scores.argsort()[:-11:-1]
)
print("bicluster {} : {} documents, {} mots".format(idx, n_rows, n_cols))
print("catégories : {}".format(cat_string))
print("mots : {}\n".format(", ".join(important_words)))
Sommaire
Dans ce laboratoire, nous avons appris à effectuer un biclustering à l'aide de l'algorithme de co-clustering spectral sur l'ensemble de données des vingt groupes de news. Nous avons également appris à effectuer un clustering des données à l'aide de MiniBatchKMeans pour la comparaison. Enfin, nous avons trouvé les meilleurs biclusters en calculant leur coupe normalisée et en sélectionnant les cinq premiers.