Gráfico de extracción de temas con NMF y LDA

Machine LearningMachine LearningBeginner
Practicar Ahora

This tutorial is from open-source community. Access the source code

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, aplicaremos la Factorización de Matriz No Negativa (NMF, por sus siglas en inglés) y la Asignación Latente de Dirichlet (LDA, por sus siglas en inglés) en un corpus de documentos para extraer modelos aditivos de la estructura temática del corpus. La salida será una gráfica de temas, cada uno representado como un gráfico de barras utilizando las primeras palabras basadas en los pesos.

Consejos sobre la VM

Una vez que se haya iniciado la VM, haga clic en la esquina superior izquierda para cambiar a la pestaña Cuaderno y acceder a Jupyter Notebook para practicar.

A veces, es posible que tenga que esperar unos segundos para que Jupyter Notebook termine de cargarse. La validación de las operaciones no se puede automatizar debido a las limitaciones de Jupyter Notebook.

Si tiene problemas durante el aprendizaje, no dude en preguntar a Labby. Deje sus comentarios después de la sesión y lo resolveremos rápidamente para usted.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL sklearn(("Sklearn")) -.-> sklearn/DataPreprocessingandFeatureEngineeringGroup(["Data Preprocessing and Feature Engineering"]) sklearn(("Sklearn")) -.-> sklearn/AdvancedDataAnalysisandDimensionalityReductionGroup(["Advanced Data Analysis and Dimensionality Reduction"]) sklearn(("Sklearn")) -.-> sklearn/UtilitiesandDatasetsGroup(["Utilities and Datasets"]) ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) sklearn/DataPreprocessingandFeatureEngineeringGroup -.-> sklearn/feature_extraction("Feature Extraction") sklearn/AdvancedDataAnalysisandDimensionalityReductionGroup -.-> sklearn/decomposition("Matrix Decomposition") sklearn/UtilitiesandDatasetsGroup -.-> sklearn/datasets("Datasets") ml/FrameworkandSoftwareGroup -.-> ml/sklearn("scikit-learn") subgraph Lab Skills sklearn/feature_extraction -.-> lab-49319{{"Gráfico de extracción de temas con NMF y LDA"}} sklearn/decomposition -.-> lab-49319{{"Gráfico de extracción de temas con NMF y LDA"}} sklearn/datasets -.-> lab-49319{{"Gráfico de extracción de temas con NMF y LDA"}} ml/sklearn -.-> lab-49319{{"Gráfico de extracción de temas con NMF y LDA"}} end

Cargar el Conjunto de Datos

Cargaremos el conjunto de datos 20 newsgroups y lo vectorizaremos. Utilizamos algunas heurísticas para filtrar términos inútiles desde el principio: se eliminan los encabezados, pies de página y respuestas citadas de los mensajes, y se eliminan las palabras comunes en inglés, las palabras que aparecen en solo un documento o en al menos el 95% de los documentos.

from sklearn.datasets import fetch_20newsgroups

n_samples = 2000
n_features = 1000

print("Loading dataset...")
data, _ = fetch_20newsgroups(
    shuffle=True,
    random_state=1,
    remove=("headers", "footers", "quotes"),
    return_X_y=True,
)
data_samples = data[:n_samples]

Extraer Características

Extraeremos las características del conjunto de datos utilizando características tf-idf para NMF y características de recuento de términos brutos para LDA.

from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer

## Utilizar características tf-idf para NMF.
print("Extracting tf-idf features for NMF...")
tfidf_vectorizer = TfidfVectorizer(
    max_df=0.95, min_df=2, max_features=n_features, stop_words="english"
)
tfidf = tfidf_vectorizer.fit_transform(data_samples)

## Utilizar características de recuento de términos brutos para LDA.
print("Extracting tf features for LDA...")
tf_vectorizer = CountVectorizer(
    max_df=0.95, min_df=2, max_features=n_features, stop_words="english"
)
tf = tf_vectorizer.fit_transform(data_samples)

Aplicar NMF

Aplicaremos NMF con dos funciones objetivo diferentes: la norma de Frobenius y la divergencia generalizada de Kullback-Leibler. Esta última es equivalente a la Indexación Semántica Latente Probabilística.

from sklearn.decomposition import NMF

n_components = 10
n_top_words = 20
init = "nndsvda"

## Ajustar el modelo NMF
print(
    "Ajustando el modelo NMF (norma de Frobenius) con características tf-idf, "
    "n_samples=%d y n_features=%d..." % (n_samples, n_features)
)
nmf = NMF(
    n_components=n_components,
    random_state=1,
    init=init,
    beta_loss="frobenius",
    alpha_W=0.00005,
    alpha_H=0.00005,
    l1_ratio=1,
).fit(tfidf)

## Graficar las principales palabras para el modelo NMF
def plot_top_words(model, feature_names, n_top_words, title):
    fig, axes = plt.subplots(2, 5, figsize=(30, 15), sharex=True)
    axes = axes.flatten()
    for topic_idx, topic in enumerate(model.components_):
        top_features_ind = topic.argsort()[: -n_top_words - 1 : -1]
        top_features = [feature_names[i] for i in top_features_ind]
        weights = topic[top_features_ind]

        ax = axes[topic_idx]
        ax.barh(top_features, weights, height=0.7)
        ax.set_title(f"Tema {topic_idx +1}", fontdict={"fontsize": 30})
        ax.invert_yaxis()
        ax.tick_params(axis="both", which="major", labelsize=20)
        for i in "top right left".split():
            ax.spines[i].set_visible(False)
        fig.suptitle(title, fontsize=40)

    plt.subplots_adjust(top=0.90, bottom=0.05, wspace=0.90, hspace=0.3)
    plt.show()

tfidf_feature_names = tfidf_vectorizer.get_feature_names_out()
plot_top_words(
    nmf, tfidf_feature_names, n_top_words, "Temas en el modelo NMF (norma de Frobenius)"
)

## Ajustar el modelo NMF con la divergencia generalizada de Kullback-Leibler
print(
    "\n" * 2,
    "Ajustando el modelo NMF (divergencia generalizada de Kullback-Leibler "
    "divergencia) con características tf-idf, n_samples=%d y n_features=%d..."
    % (n_samples, n_features),
)
nmf = NMF(
    n_components=n_components,
    random_state=1,
    init=init,
    beta_loss="kullback-leibler",
    solver="mu",
    max_iter=1000,
    alpha_W=0.00005,
    alpha_H=0.00005,
    l1_ratio=0.5,
).fit(tfidf)

## Graficar las principales palabras para el modelo NMF con la divergencia generalizada de Kullback-Leibler
tfidf_feature_names = tfidf_vectorizer.get_feature_names_out()
plot_top_words(
    nmf,
    tfidf_feature_names,
    n_top_words,
    "Temas en el modelo NMF (divergencia generalizada de Kullback-Leibler divergencia)",
)

## Ajustar el modelo MiniBatchNMF
from sklearn.decomposition import MiniBatchNMF

batch_size = 128

print(
    "\n" * 2,
    "Ajustando el modelo MiniBatchNMF (norma de Frobenius) con tf-idf "
    "características, n_samples=%d y n_features=%d, batch_size=%d..."
    % (n_samples, n_features, batch_size),
)
mbnmf = MiniBatchNMF(
    n_components=n_components,
    random_state=1,
    batch_size=batch_size,
    init=init,
    beta_loss="frobenius",
    alpha_W=0.00005,
    alpha_H=0.00005,
    l1_ratio=0.5,
).fit(tfidf)

## Graficar las principales palabras para el modelo MiniBatchNMF con la norma de Frobenius
tfidf_feature_names = tfidf_vectorizer.get_feature_names_out()
plot_top_words(
    mbnmf,
    tfidf_feature_names,
    n_top_words,
    "Temas en el modelo MiniBatchNMF (norma de Frobenius)",
)

## Ajustar el modelo MiniBatchNMF con la divergencia generalizada de Kullback-Leibler
print(
    "\n" * 2,
    "Ajustando el modelo MiniBatchNMF (divergencia generalizada de Kullback-Leibler "
    "divergencia) con características tf-idf, n_samples=%d y n_features=%d, "
    "batch_size=%d..." % (n_samples, n_features, batch_size),
)
mbnmf = MiniBatchNMF(
    n_components=n_components,
    random_state=1,
    batch_size=batch_size,
    init=init,
    beta_loss="kullback-leibler",
    alpha_W=0.00005,
    alpha_H=0.00005,
    l1_ratio=0.5,
).fit(tfidf)

## Graficar las principales palabras para el modelo MiniBatchNMF con la divergencia generalizada de Kullback-Leibler
tfidf_feature_names = tfidf_vectorizer.get_feature_names_out()
plot_top_words(
    mbnmf,
    tfidf_feature_names,
    n_top_words,
    "Temas en el modelo MiniBatchNMF (divergencia generalizada de Kullback-Leibler divergencia)",
)

Aplicar LDA

Aplicaremos modelos LDA con características tf.

from sklearn.decomposition import LatentDirichletAllocation

print(
    "\n" * 2,
    "Ajustando modelos LDA con características tf, n_samples=%d y n_features=%d..."
    % (n_samples, n_features),
)
lda = LatentDirichletAllocation(
    n_components=n_components,
    max_iter=5,
    learning_method="online",
    learning_offset=50.0,
    random_state=0,
)
t0 = time()
lda.fit(tf)
print("hecho en %0.3fs." % (time() - t0))

tf_feature_names = tf_vectorizer.get_feature_names_out()
plot_top_words(lda, tf_feature_names, n_top_words, "Temas en el modelo LDA")

Resumen

En este laboratorio, hemos aprendido cómo aplicar la Factorización de Matriz No Negativa y la Asignación Latente de Dirichlet en un corpus de documentos para extraer modelos aditivos de la estructura temática del corpus. También hemos aprendido cómo graficar los temas, cada uno representado como un gráfico de barras utilizando las primeras palabras basadas en los pesos.