Tutorial: Criar, avaliar e pontuar um modelo de classificação de texto
Este tutorial apresenta um exemplo completo de um fluxo de trabalho Synapse Data Science para um modelo de classificação de texto, no Microsoft Fabric. O cenário usa word2vec e regressão logística, no Spark, para determinar o gênero de um livro do conjunto de dados de livros da Biblioteca Britânica, apenas com base no título do livro.
Este tutorial aborda estas etapas:
- Instalar bibliotecas personalizadas
- Carregar os dados
- Compreender e processar os dados com análise exploratória de dados
- Treine um modelo de aprendizado de máquina com word2vec e regressão logística e acompanhe experimentos com MLflow e o recurso de registro automático de malha
- Carregue o modelo de aprendizado de máquina para pontuações e previsões
Pré-requisitos
Obtenha uma assinatura do Microsoft Fabric. Ou inscreva-se para uma avaliação gratuita do Microsoft Fabric.
Entre no Microsoft Fabric.
Use o seletor de experiência no lado esquerdo da sua página inicial para alternar para a experiência Synapse Data Science.
- Se você não tiver uma casa de lago do Microsoft Fabric, crie uma seguindo as etapas em Criar uma casa de lago no Microsoft Fabric.
Acompanhe num caderno
Você pode escolher uma destas opções para acompanhar em um bloco de anotações:
- Abra e execute o bloco de anotações integrado na experiência Synapse Data Science
- Carregue seu notebook do GitHub para a experiência Synapse Data Science
Abra o bloco de notas incorporado
O bloco de anotações de classificação de gênero Título de exemplo acompanha este tutorial.
Para abrir o bloco de anotações de exemplo integrado do tutorial na experiência Synapse Data Science:
Vá para a página inicial do Synapse Data Science.
Selecione Usar uma amostra.
Selecione a amostra correspondente:
- Na guia padrão End-to-end workflows (Python), se o exemplo for para um tutorial do Python.
- Na guia Fluxos de trabalho de ponta a ponta (R), se o exemplo for para um tutorial R.
- Na guia Tutoriais rápidos, se o exemplo for para um tutorial rápido.
Anexe um lakehouse ao bloco de anotações antes de começar a executar o código.
Importar o bloco de anotações do GitHub
AIsample - Title Genre Classification.ipynb é o caderno que acompanha este tutorial.
Para abrir o bloco de anotações que acompanha este tutorial, siga as instruções em Preparar seu sistema para tutoriais de ciência de dados, para importar o bloco de anotações para seu espaço de trabalho.
Se preferir copiar e colar o código desta página, pode criar um novo bloco de notas.
Certifique-se de anexar um lakehouse ao bloco de anotações antes de começar a executar o código.
Etapa 1: Instalar bibliotecas personalizadas
Para desenvolvimento de modelo de aprendizado de máquina ou análise de dados ad-hoc, talvez seja necessário instalar rapidamente uma biblioteca personalizada para sua sessão do Apache Spark. Você tem duas opções para instalar bibliotecas.
- Utilize as capacidades de instalação em linha (
%pip
ou%conda
) do seu bloco de notas para instalar uma biblioteca, apenas no seu bloco de notas atual. - Como alternativa, você pode criar um ambiente de malha, instalar bibliotecas de fontes públicas ou carregar bibliotecas personalizadas para ele e, em seguida, o administrador do espaço de trabalho pode anexar o ambiente como padrão para o espaço de trabalho. Todas as bibliotecas no ambiente ficarão disponíveis para uso em quaisquer blocos de anotações e definições de trabalho do Spark no espaço de trabalho. Para obter mais informações sobre ambientes, consulte criar, configurar e usar um ambiente no Microsoft Fabric.
Para o modelo de classificação, use a biblioteca para representar a wordcloud
frequência da palavra no texto, onde o tamanho de uma palavra representa sua frequência. Para este tutorial, use %pip install
para instalar wordcloud
em seu notebook.
Nota
O kernel do PySpark é reiniciado após %pip install
as execuções. Instale as bibliotecas necessárias antes de executar quaisquer outras células.
# Install wordcloud for text visualization by using pip
%pip install wordcloud
Passo 2: Carregue os dados
O conjunto de dados tem metadados sobre livros da Biblioteca Britânica que uma colaboração entre a biblioteca e a Microsoft digitalizou. Os metadados são informações de classificação para indicar se um livro é ficção ou não-ficção. Com este conjunto de dados, o objetivo é treinar um modelo de classificação que determine o género de um livro, apenas com base no seu título.
ID do registo BL | Tipo de recurso | Nome | Datas associadas ao nome | Tipo de nome | Role | Todos os nomes | Cargo | Títulos variantes | Título da série | Número dentro da série | País de publicação | Local de publicação | Publisher | Data de publicação | Edição | Descrição física | Classificação de Dewey | Código BL | Tópicos | Género | Idiomas | Notas | ID de registro BL para recurso físico | classification_id | user_id | created_at | subject_ids | annotator_date_pub | annotator_normalised_date_pub | annotator_edition_statement | annotator_genre | annotator_FAST_genre_terms | annotator_FAST_subject_terms | annotator_comments | annotator_main_language | annotator_other_languages_summaries | annotator_summaries_language | annotator_translation | annotator_original_language | annotator_publisher | annotator_place_pub | annotator_country | annotator_title | Link para livro digitalizado | anotado |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
014602826 | Monografia | Yearsley, Ana | 1753-1806 | pessoa | More, Hannah, 1745-1833 [pessoa]; Yearsley, Ann, 1753-1806 [pessoa] | Poemas em várias ocasiões [Com uma carta preliminar de Hannah More.] | Inglaterra | Londres | 1786 | Quarta edição NOTA MANUSCRITA | Loja Digital 11644.d.32 | Português | 003996603 | False | |||||||||||||||||||||||||||||||
014602830 | Monografia | A, T. | pessoa | Oldham, John, 1653-1683 [pessoa]; A, T. [pessoa] | Um sátiro contra Vertue. (Um poema: supostamente falado por um Heitor da Cidade [Por John Oldham. O prefácio assinado: T. A.]) | Inglaterra | Londres | 1679 | 15 páginas (4°) | Loja Digital 11602.ee.10. (2.) | Português | 000001143 | False |
Defina os seguintes parâmetros para que você possa aplicar este bloco de anotações em diferentes conjuntos de dados:
IS_CUSTOM_DATA = False # If True, the user must manually upload the dataset
DATA_FOLDER = "Files/title-genre-classification"
DATA_FILE = "blbooksgenre.csv"
# Data schema
TEXT_COL = "Title"
LABEL_COL = "annotator_genre"
LABELS = ["Fiction", "Non-fiction"]
EXPERIMENT_NAME = "sample-aisample-textclassification" # MLflow experiment name
Faça o download do conjunto de dados e faça o upload para a casa do lago
Esse código baixa uma versão disponível publicamente do conjunto de dados e, em seguida, armazena-o em uma casa de lago de malha.
Importante
Adicione uma casa de lago ao bloco de anotações antes de executá-lo. Se não o fizer, haverá um erro.
if not IS_CUSTOM_DATA:
# Download demo data files into the lakehouse, if they don't exist
import os, requests
remote_url = "https://synapseaisolutionsa.blob.core.windows.net/public/Title_Genre_Classification"
fname = "blbooksgenre.csv"
download_path = f"/lakehouse/default/{DATA_FOLDER}/raw"
if not os.path.exists("/lakehouse/default"):
# Add a lakehouse, if no default lakehouse was added to the notebook
# A new notebook won't link to any lakehouse by default
raise FileNotFoundError(
"Default lakehouse not found, please add a lakehouse and restart the session."
)
os.makedirs(download_path, exist_ok=True)
if not os.path.exists(f"{download_path}/{fname}"):
r = requests.get(f"{remote_url}/{fname}", timeout=30)
with open(f"{download_path}/{fname}", "wb") as f:
f.write(r.content)
print("Downloaded demo data files into lakehouse.")
Importar bibliotecas necessárias
Antes de qualquer processamento, você precisa importar as bibliotecas necessárias, incluindo as bibliotecas para Spark e SynapseML:
import numpy as np
from itertools import chain
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import seaborn as sns
import pyspark.sql.functions as F
from pyspark.ml import Pipeline
from pyspark.ml.feature import *
from pyspark.ml.tuning import CrossValidator, ParamGridBuilder
from pyspark.ml.classification import LogisticRegression
from pyspark.ml.evaluation import (
BinaryClassificationEvaluator,
MulticlassClassificationEvaluator,
)
from synapse.ml.stages import ClassBalancer
from synapse.ml.train import ComputeModelStatistics
import mlflow
Definir hyperparameters
Defina alguns hiperparâmetros para o treinamento do modelo.
Importante
Modifique esses hiperparâmetros somente se você entender cada parâmetro.
# Hyperparameters
word2vec_size = 128 # The length of the vector for each word
min_word_count = 3 # The minimum number of times that a word must appear to be considered
max_iter = 10 # The maximum number of training iterations
k_folds = 3 # The number of folds for cross-validation
Comece a registar o tempo necessário para executar este bloco de notas:
# Record the notebook running time
import time
ts = time.time()
Configurar o rastreamento de experimentos MLflow
O registro automático estende os recursos de log do MLflow. O registro automático captura automaticamente os valores dos parâmetros de entrada e as métricas de saída de um modelo de aprendizado de máquina à medida que você o treina. Em seguida, registre essas informações no espaço de trabalho. No espaço de trabalho, você pode acessar e visualizar as informações com as APIs MLflow, ou o experimento correspondente, no espaço de trabalho. Para saber mais sobre o registro automático, consulte Registro automático no Microsoft Fabric.
# Set up Mlflow for experiment tracking
mlflow.set_experiment(EXPERIMENT_NAME)
mlflow.autolog(disable=True) # Disable Mlflow autologging
Para desativar o registro automático do Microsoft Fabric em uma sessão de bloco de anotações, chame mlflow.autolog()
e defina disable=True
:
Leia os dados brutos de data da casa do lago
raw_df = spark.read.csv(f"{DATA_FOLDER}/raw/{DATA_FILE}", header=True, inferSchema=True)
Etapa 3: Executar a análise exploratória de dados
Explore o conjunto de dados com o comando, para exibir estatísticas de alto nível para o display
conjunto de dados e mostrar as exibições do gráfico:
display(raw_df.limit(20))
Preparar os dados
Remova as duplicatas para limpar os dados:
df = (
raw_df.select([TEXT_COL, LABEL_COL])
.where(F.col(LABEL_COL).isin(LABELS))
.dropDuplicates([TEXT_COL])
.cache()
)
display(df.limit(20))
Aplique o balanceamento de classes para resolver qualquer viés:
# Create a ClassBalancer instance, and set the input column to LABEL_COL
cb = ClassBalancer().setInputCol(LABEL_COL)
# Fit the ClassBalancer instance to the input DataFrame, and transform the DataFrame
df = cb.fit(df).transform(df)
# Display the first 20 rows of the transformed DataFrame
display(df.limit(20))
Divida os parágrafos e frases em unidades menores, para tokenizar o conjunto de dados. Desta forma, torna-se mais fácil atribuir significado. Em seguida, remova as palavras de parada para melhorar o desempenho. A remoção de palavras paradas envolve a remoção de palavras que normalmente ocorrem em todos os documentos do corpus. A remoção de palavras paradas é uma das etapas de pré-processamento mais usadas em aplicativos de processamento de linguagem natural (NLP).
# Text transformer
tokenizer = Tokenizer(inputCol=TEXT_COL, outputCol="tokens")
stopwords_remover = StopWordsRemover(inputCol="tokens", outputCol="filtered_tokens")
# Build the pipeline
pipeline = Pipeline(stages=[tokenizer, stopwords_remover])
token_df = pipeline.fit(df).transform(df)
display(token_df.limit(20))
Exiba a biblioteca wordcloud para cada classe. Uma biblioteca de nuvem de palavras é uma apresentação visualmente proeminente de palavras-chave que aparecem frequentemente em dados de texto. A biblioteca wordcloud é eficaz porque a renderização de palavras-chave forma uma imagem colorida semelhante a uma nuvem, para capturar melhor os principais dados de texto em um piscar de olhos. Saiba mais sobre o wordcloud.
# WordCloud
for label in LABELS:
tokens = (
token_df.where(F.col(LABEL_COL) == label)
.select(F.explode("filtered_tokens").alias("token"))
.where(F.col("token").rlike(r"^\w+$"))
)
top50_tokens = (
tokens.groupBy("token").count().orderBy(F.desc("count")).limit(50).collect()
)
# Generate a wordcloud image
wordcloud = WordCloud(
scale=10,
background_color="white",
random_state=42, # Make sure the output is always the same for the same input
).generate_from_frequencies(dict(top50_tokens))
# Display the generated image by using matplotlib
plt.figure(figsize=(10, 10))
plt.title(label, fontsize=20)
plt.axis("off")
plt.imshow(wordcloud, interpolation="bilinear")
Finalmente, use word2vec para vetorizar o texto. A técnica word2vec cria uma representação vetorial de cada palavra no texto. Palavras usadas em contextos semelhantes, ou que têm relações semânticas, são capturadas efetivamente através de sua proximidade no espaço vetorial. Esta proximidade indica que palavras semelhantes têm vetores de palavras semelhantes.
# Label transformer
label_indexer = StringIndexer(inputCol=LABEL_COL, outputCol="labelIdx")
vectorizer = Word2Vec(
vectorSize=word2vec_size,
minCount=min_word_count,
inputCol="filtered_tokens",
outputCol="features",
)
# Build the pipeline
pipeline = Pipeline(stages=[label_indexer, vectorizer])
vec_df = (
pipeline.fit(token_df)
.transform(token_df)
.select([TEXT_COL, LABEL_COL, "features", "labelIdx", "weight"])
)
display(vec_df.limit(20))
Passo 4: Treinar e avaliar o modelo
Com os dados em vigor, defina o modelo. Nesta seção, você treina um modelo de regressão logística para classificar o texto vetorizado.
Preparar conjuntos de dados de treinamento e teste
# Split the dataset into training and testing
(train_df, test_df) = vec_df.randomSplit((0.8, 0.2), seed=42)
Rastreie experimentos de aprendizado de máquina
Um experimento de aprendizado de máquina é a principal unidade de organização e controle para todas as execuções de aprendizado de máquina relacionadas. Uma execução corresponde a uma única execução do código do modelo.
O rastreamento de experimentos de aprendizado de máquina gerencia todos os experimentos e seus componentes, por exemplo, parâmetros, métricas, modelos e outros artefatos. O rastreamento permite a organização de todos os componentes necessários de um experimento específico de aprendizado de máquina. Ele também permite a reprodução fácil de resultados passados com experimentos salvos. Saiba mais sobre experimentos de aprendizado de máquina no Microsoft Fabric.
# Build the logistic regression classifier
lr = (
LogisticRegression()
.setMaxIter(max_iter)
.setFeaturesCol("features")
.setLabelCol("labelIdx")
.setWeightCol("weight")
)
Otimizar hiperparâmetros
Crie uma grade de parâmetros para pesquisar sobre os hiperparâmetros. Em seguida, construa um estimador de avaliador cruzado, para produzir um CrossValidator
modelo:
# Build a grid search to select the best values for the training parameters
param_grid = (
ParamGridBuilder()
.addGrid(lr.regParam, [0.03, 0.1])
.addGrid(lr.elasticNetParam, [0.0, 0.1])
.build()
)
if len(LABELS) > 2:
evaluator_cls = MulticlassClassificationEvaluator
evaluator_metrics = ["f1", "accuracy"]
else:
evaluator_cls = BinaryClassificationEvaluator
evaluator_metrics = ["areaUnderROC", "areaUnderPR"]
evaluator = evaluator_cls(labelCol="labelIdx", weightCol="weight")
# Build a cross-evaluator estimator
crossval = CrossValidator(
estimator=lr,
estimatorParamMaps=param_grid,
evaluator=evaluator,
numFolds=k_folds,
collectSubModels=True,
)
Avaliar o modelo
Podemos avaliar os modelos no conjunto de dados de teste, para compará-los. Um modelo bem treinado deve demonstrar alto desempenho, nas métricas relevantes, quando executado em relação aos conjuntos de dados de validação e teste.
def evaluate(model, df):
log_metric = {}
prediction = model.transform(df)
for metric in evaluator_metrics:
value = evaluator.evaluate(prediction, {evaluator.metricName: metric})
log_metric[metric] = value
print(f"{metric}: {value:.4f}")
return prediction, log_metric
Rastreie experimentos usando MLflow
Iniciar o processo de formação e avaliação. Use o MLflow para controlar todos os experimentos e registrar parâmetros, métricas e modelos. Todas essas informações são registradas sob o nome do experimento no espaço de trabalho.
with mlflow.start_run(run_name="lr"):
models = crossval.fit(train_df)
best_metrics = {k: 0 for k in evaluator_metrics}
best_index = 0
for idx, model in enumerate(models.subModels[0]):
with mlflow.start_run(nested=True, run_name=f"lr_{idx}") as run:
print("\nEvaluating on test data:")
print(f"subModel No. {idx + 1}")
prediction, log_metric = evaluate(model, test_df)
if log_metric[evaluator_metrics[0]] > best_metrics[evaluator_metrics[0]]:
best_metrics = log_metric
best_index = idx
print("log model")
mlflow.spark.log_model(
model,
f"{EXPERIMENT_NAME}-lrmodel",
registered_model_name=f"{EXPERIMENT_NAME}-lrmodel",
dfs_tmpdir="Files/spark",
)
print("log metrics")
mlflow.log_metrics(log_metric)
print("log parameters")
mlflow.log_params(
{
"word2vec_size": word2vec_size,
"min_word_count": min_word_count,
"max_iter": max_iter,
"k_folds": k_folds,
"DATA_FILE": DATA_FILE,
}
)
# Log the best model and its relevant metrics and parameters to the parent run
mlflow.spark.log_model(
models.subModels[0][best_index],
f"{EXPERIMENT_NAME}-lrmodel",
registered_model_name=f"{EXPERIMENT_NAME}-lrmodel",
dfs_tmpdir="Files/spark",
)
mlflow.log_metrics(best_metrics)
mlflow.log_params(
{
"word2vec_size": word2vec_size,
"min_word_count": min_word_count,
"max_iter": max_iter,
"k_folds": k_folds,
"DATA_FILE": DATA_FILE,
}
)
Para ver as suas experiências:
- Selecione seu espaço de trabalho no painel de navegação esquerdo
- Localizar e selecionar o nome do experimento - neste caso, sample_aisample-textclassification
Etapa 5: Marcar e salvar os resultados da previsão
O Microsoft Fabric permite que os usuários operacionalizem modelos de aprendizado de máquina com a PREDICT
função escalável. Esta função suporta pontuação em lote (ou inferência em lote) em qualquer mecanismo de computação. Você pode criar previsões em lote diretamente de um bloco de anotações ou da página do item para um modelo específico. Para saber mais sobre o PREDICT e como usá-lo no Fabric, consulte Pontuação do modelo de aprendizado de máquina com o PREDICT no Microsoft Fabric.
A partir dos resultados da avaliação anterior, o modelo 1 tem as maiores métricas tanto para a Área Sob a Curva de Precisão-Recordação (AUPRC) quanto para a Área Sob a Característica de Operação do Recetor de Curva (AUC-ROC). Portanto, você deve usar o modelo 1 para previsão.
A medida AUC-ROC é amplamente utilizada para medir o desempenho de classificadores binários. No entanto, por vezes torna-se mais apropriado avaliar o classificador com base nas medições AUPRC. O gráfico AUC-ROC visualiza o trade-off entre a taxa de verdadeiro positivo (TPR) e a taxa de falso positivo (FPR). A curva AUPRC combina precisão (valor preditivo positivo ou VPP) e recordação (taxa positiva verdadeira ou TPR) em uma única visualização.
# Load the best model
model_uri = f"models:/{EXPERIMENT_NAME}-lrmodel/1"
loaded_model = mlflow.spark.load_model(model_uri, dfs_tmpdir="Files/spark")
# Verify the loaded model
batch_predictions = loaded_model.transform(test_df)
batch_predictions.show(5)
# Code to save userRecs in the lakehouse
batch_predictions.write.format("delta").mode("overwrite").save(
f"{DATA_FOLDER}/predictions/batch_predictions"
)
# Determine the entire runtime
print(f"Full run cost {int(time.time() - ts)} seconds.")