Extração e Avaliação de Recursos Textuais

Beginner

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

Introdução

A biblioteca scikit-learn fornece ferramentas para extração e avaliação de características de texto. Neste laboratório, utilizaremos o conjunto de dados 20newsgroups para demonstrar como extrair características de dados textuais, construir um pipeline e avaliar o desempenho do modelo utilizando a afinação de hiperparâmetros.

Dicas da Máquina Virtual

Após o arranque da máquina virtual, clique no canto superior esquerdo para mudar para a aba Notebook para aceder ao Jupyter Notebook para a prática.

Por vezes, pode ser necessário esperar alguns segundos para o Jupyter Notebook terminar o carregamento. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.

Se tiver problemas durante o aprendizado, não hesite em contactar o Labby. Forneça feedback após a sessão e resolveremos o problema rapidamente para si.

Carregar Dados

Vamos carregar o conjunto de dados 20newsgroups, que é uma coleção de aproximadamente 20.000 documentos de grupos de notícias em 20 categorias diferentes. Neste laboratório, iremos concentrar-nos em duas categorias: alt.atheism e talk.religion.misc.

from sklearn.datasets import fetch_20newsgroups

categories = [
    "alt.atheism",
    "talk.religion.misc",
]

data_train = fetch_20newsgroups(
    subset="train",
    categories=categories,
    shuffle=True,
    random_state=42,
    remove=("headers", "footers", "quotes"),
)

data_test = fetch_20newsgroups(
    subset="test",
    categories=categories,
    shuffle=True,
    random_state=42,
    remove=("headers", "footers", "quotes"),
)

print(f"Carregando conjunto de dados 20 newsgroups para {len(data_train.target_names)} categorias:")
print(data_train.target_names)
print(f"{len(data_train.data)} documentos")

Definir Pipeline com Ajuste de Hiperparâmetros

Definimos um pipeline que combina um vetorizador de características de texto com um classificador simples para classificação de texto. Usaremos o Complement Naive Bayes como classificador e o TfidfVectorizer para extração de características.

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import ComplementNB
from sklearn.pipeline import Pipeline
import numpy as np

pipeline = Pipeline(
    [
        ("vect", TfidfVectorizer()),
        ("clf", ComplementNB()),
    ]
)

parameter_grid = {
    "vect__max_df": (0.2, 0.4, 0.6, 0.8, 1.0),
    "vect__min_df": (1, 3, 5, 10),
    "vect__ngram_range": ((1, 1), (1, 2)),  ## unigramas ou bigramas
    "vect__norm": ("l1", "l2"),
    "clf__alpha": np.logspace(-6, 6, 13),
}

Ajuste de Hiperparâmetros

Utilizamos RandomizedSearchCV para explorar a grade de hiperparâmetros e encontrar a melhor combinação de hiperparâmetros para o pipeline. Neste caso, definimos n_iter=40 para limitar o espaço de busca. Podemos aumentar n_iter para obter uma análise mais informativa, mas isso aumentará o tempo de computação.

from pprint import pprint
from sklearn.model_selection import RandomizedSearchCV

random_search = RandomizedSearchCV(
    estimator=pipeline,
    param_distributions=parameter_grid,
    n_iter=40,
    random_state=0,
    n_jobs=2,
    verbose=1,
)

print("Executando busca em grade...")
print("Hiperparâmetros a serem avaliados:")
pprint(parameter_grid)

random_search.fit(data_train.data, data_train.target)

test_accuracy = random_search.score(data_test.data, data_test.target)

Visualização de Resultados

Podemos visualizar os resultados do ajuste de hiperparâmetros usando plotly.express. Usamos um gráfico de dispersão para visualizar o trade-off entre o tempo de pontuação e a média da pontuação de teste. Também podemos usar coordenadas paralelas para visualizar ainda mais a média da pontuação de teste em função dos hiperparâmetros ajustados.

import pandas as pd
import plotly.express as px
import math

def shorten_param(param_name):
    """Remove os prefixos dos componentes em param_name."""
    if "__" in param_name:
        return param_name.rsplit("__", 1)[1]
    return param_name

cv_results = pd.DataFrame(random_search.cv_results_)
cv_results = cv_results.rename(shorten_param, axis=1)

param_names = [shorten_param(name) for name in parameter_grid.keys()]
labels = {
    "mean_score_time": "Tempo de Pontuação CV (s)",
    "mean_test_score": "Pontuação CV (precisão)",
}
fig = px.scatter(
    cv_results,
    x="mean_score_time",
    y="mean_test_score",
    error_x="std_score_time",
    error_y="std_test_score",
    hover_data=param_names,
    labels=labels,
)

fig.update_layout(
    title={
        "text": "trade-off entre tempo de pontuação e média da pontuação de teste",
        "y": 0.95,
        "x": 0.5,
        "xanchor": "center",
        "yanchor": "top",
    }
)

column_results = param_names + ["mean_test_score", "mean_score_time"]

transform_funcs = dict.fromkeys(column_results, lambda x: x)
## Usando uma escala logarítmica para alpha
transform_funcs["alpha"] = math.log10
## As normas L1 são mapeadas para o índice 1, e as normas L2 para o índice 2
transform_funcs["norm"] = lambda x: 2 if x == "l2" else 1
## Unigramas são mapeados para o índice 1 e bigramas para o índice 2
transform_funcs["ngram_range"] = lambda x: x[1]

fig = px.parallel_coordinates(
    cv_results[column_results].apply(transform_funcs),
    color="mean_test_score",
    color_continuous_scale=px.colors.sequential.Viridis_r,
    labels=labels,
)
fig.update_layout(
    title={
        "text": "Gráfico de coordenadas paralelas do pipeline do classificador de texto",
        "y": 0.99,
        "x": 0.5,
        "xanchor": "center",
        "yanchor": "top",
    }
)

Resumo

Neste laboratório, demonstramos como extrair recursos de dados textuais, construir um pipeline e avaliar o desempenho do modelo usando ajuste de hiperparâmetros. Utilizamos o conjunto de dados 20newsgroups para mostrar como usar RandomizedSearchCV para encontrar a melhor combinação de hiperparâmetros para o pipeline e visualizar os resultados usando plotly.express.