Tutorial: Creación, evaluación y puntuación de un modelo de clasificación de texto
En este tutorial se presenta un ejemplo completo de un flujo de trabajo de ciencia de datos de Synapse para un modelo de clasificación de texto, en Microsoft Fabric. El escenario utiliza word2vec y regresión logística, en Spark, para determinar el género de un libro del conjunto de datos de la Biblioteca Británica, basándose únicamente en el título del libro.
En este tutorial se describen estos pasos:
- Instalación de bibliotecas personalizadas
- Carga de los datos
- Descripción y procesamiento de los datos con análisis de datos exploratorios
- Entrenamiento de un modelo de Machine Learning con word2vec y regresión logística, y seguimiento de experimentos mediante MLflow y la característica de registro automático de Fabric
- Carga del modelo de Machine Learning para la puntuación y las predicciones
Prerrequisitos
Obtenga una suscripción a Microsoft Fabric. También puede registrarse para obtener una evaluación gratuita de Microsoft Fabric.
Inicie sesión en Microsoft Fabric.
Use el conmutador de experiencia en la parte inferior izquierda de la página principal para cambiar a Fabric.
- Si no tiene un almacén de lago de datos en Microsoft Fabric, cree uno siguiendo los pasos de Creación de un almacén de lago de datos en Microsoft Fabric.
Seguimiento en un cuaderno
Puede elegir una de estas opciones para realizar un seguimiento en un cuaderno:
- Abra y ejecute el cuaderno integrado.
- Cargue el cuaderno desde GitHub.
Abra el cuaderno integrado.
El cuaderno de ejemplo Clasificación de género de título acompaña a este tutorial.
Para abrir el cuaderno de ejemplo de este tutorial, siga las instrucciones de Preparar el sistema para tutoriales de ciencia de datos.
Asegúrese de adjuntar un almacén de lago de datos al cuaderno antes de ejecutar el código.
Importación del cuaderno desde GitHub
AIsample- Title Genre Classification.ipynb es el cuaderno que acompaña a este tutorial.
A fin de abrir el cuaderno complementario para este tutorial, siga las instrucciones de Preparación del sistema para los tutoriales de ciencia de datos, para importar el cuaderno al área de trabajo.
Si prefiere copiar y pegar el código de esta página, puede crear un cuaderno nuevo.
Asegúrese de adjuntar un almacén de lago de datos al cuaderno antes de empezar a ejecutar código.
Paso 1: Instalación de bibliotecas personalizadas
Para el desarrollo de modelos de Machine Learning o el análisis de datos ad hoc, es posible que tenga que instalar rápidamente una biblioteca personalizada para la sesión de Apache Spark. Tiene dos opciones para instalar bibliotecas.
- Utiliza las capacidades de instalación en línea (
%pip
o%conda
) de tu notebook para instalar una biblioteca, solo en el notebook actual. - Como alternativa, puede crear un entorno de Fabric, instalar bibliotecas desde orígenes públicos o cargar bibliotecas personalizadas en él y, a continuación, el administrador del área de trabajo puede asociar el entorno como valor predeterminado para el área de trabajo. Todas las bibliotecas del entorno estarán disponibles para su uso en los cuadernos y las definiciones de trabajos de Spark en el área de trabajo. Para obtener más información sobre los entornos, consulte crear, configurar y usar un entorno en Microsoft Fabric.
Para el modelo de clasificación, use la biblioteca wordcloud
para representar la frecuencia de palabras en el texto, donde el tamaño de una palabra representa su frecuencia. Para este tutorial, use %pip install
para instalar wordcloud
en tu portátil.
Nota
El kernel de PySpark se reinicia después de que se ejecute %pip install
. Instale las bibliotecas necesarias antes de ejecutar cualquier otra celda.
# Install wordcloud for text visualization by using pip
%pip install wordcloud
Paso 2: Cargar los datos
El conjunto de datos tiene metadatos sobre los libros de la Biblioteca Británica que una colaboración entre la biblioteca y Microsoft digitalizaron. Los metadatos son información de clasificación para indicar si un libro es ficción o no ficción. Con este conjunto de datos, el objetivo es entrenar un modelo de clasificación que determine el género de un libro, solo en función de su título.
Id. de registro de BL | Tipo de recurso | Nombre | Fechas asociadas con el nombre | Tipo de nombre | Rol | Todos los nombres | Título | Títulos variantes | Título de la serie | Número dentro de la serie | País de publicación | Lugar de publicación | Publicador | Fecha de publicación | Edición | Descripción física | Clasificación de dewey | Signatura topográfica de BL | Temas | Género | Idiomas | Notas | Id. de registro de BL para el recurso físico | classification_id | identificador de usuario | created_at | subject_ids | annotator_date_pub | annotator_normalised_date_pub | annotator_edition_statement | annotator_genre | annotator_FAST_genre_terms | annotator_FAST_subject_terms | comentarios_del_annotador | annotator_main_language | annotator_other_languages_summaries | annotator_summaries_language | annotator_translation | idioma_original_del_annotador | annotator_publisher | annotator_place_pub | país_del_anotador | título del anotador | Vínculo al libro digitalizado | annotated |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
014602826 | Monografía | Yearsley, Ann | 1753-1806 | person | More, Hannah, 1745-1833 [persona]; Yearsley, Ann, 1753-1806 [persona] | Poemas en varias ocasiones [Con una carta preliminar de Hannah More.] | Inglaterra | Londres | 1786 | Cuarta edición de la nota de MANUSCRITO | Digital Store 11644.d.32 | Inglés | 003996603 | Falso | |||||||||||||||||||||||||||||||
014602830 | Monografía | A, T. | person | Oldham, John, 1653-1683 [persona]; A, T. [persona] | Un Satyr contra Vertue. (Un poema: se supone que debe ser recitado por un Town-Hector [Por John Oldham. El prefacio firmado: T. A.]) | Inglaterra | Londres | 1679 | 15 páginas (4°) | Digital Store 11602.ee.10. (2.) | Inglés | 000001143 | Falso |
Defina los parámetros siguientes para que pueda aplicar este cuaderno en diferentes conjuntos de datos:
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
Descarga del conjunto de datos y carga en el almacén de lago de datos
Este código descarga una versión disponible públicamente del conjunto de datos y, a continuación, la almacena en una instancia de Fabric Lakehouse.
Importante
Agregue un almacén de lago de datos al cuaderno antes de ejecutarlo. Si no lo hace, se producirá un error.
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.")
Importación de bibliotecas necesarias
Antes de cualquier procesamiento, debe importar las bibliotecas necesarias, incluidas las bibliotecas de Spark y 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 hiperparámetros
Defina algunos hiperparámetros para el entrenamiento del modelo.
Importante
Modifique estos hiperparámetros solo si comprende 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
Inicie la grabación del tiempo necesario para ejecutar este cuaderno:
# Record the notebook running time
import time
ts = time.time()
Configuración del seguimiento de experimentos de MLflow
El registro automático amplía las funcionalidades de registro de MLflow. El registro automático captura automáticamente los valores de los parámetros de entrada y las métricas de salida de un modelo de Machine Learning a medida que se entrena. A continuación, registre esta información en el área de trabajo. En el área de trabajo, puede acceder a la información y visualizarla con las API de MLflow o el experimento correspondiente en el área de trabajo. Para obtener más información sobre el registro automático, consulte Registro automático en Microsoft Fabric.
# Set up Mlflow for experiment tracking
mlflow.set_experiment(EXPERIMENT_NAME)
mlflow.autolog(disable=True) # Disable Mlflow autologging
Para deshabilitar el registro automático de Microsoft Fabric en una sesión de cuaderno, llame a mlflow.autolog()
y establezca disable=True
:
Lectura de datos sin procesar desde el almacén de lago de datos
raw_df = spark.read.csv(f"{DATA_FOLDER}/raw/{DATA_FILE}", header=True, inferSchema=True)
Paso 3: Realizar análisis de datos exploratorios
Explore el conjunto de datos con el comando display
para ver las estadísticas de alto nivel del conjunto de datos y mostrar las vistas del gráfico:
display(raw_df.limit(20))
Preparación de los datos
Quite los duplicados para limpiar los datos:
df = (
raw_df.select([TEXT_COL, LABEL_COL])
.where(F.col(LABEL_COL).isin(LABELS))
.dropDuplicates([TEXT_COL])
.cache()
)
display(df.limit(20))
Aplique equilibrio de clases para solucionar cualquier sesgo:
# 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 los párrafos y oraciones en unidades más pequeñas para tokenizar el conjunto de datos. De este modo, resulta más fácil asignar significado. Después, quite las palabras irrelevantes para mejorar el rendimiento. La eliminación de palabras irrelevantes implica la eliminación de palabras que suelen aparecer en todos los documentos del corpus. La eliminación de palabras irrelevantes es uno de los pasos de preprocesamiento más usados en las aplicaciones de procesamiento de lenguaje 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))
Muestra la biblioteca de wordcloud para cada clase. Una biblioteca de wordcloud es una presentación visualmente destacada de palabras clave que aparecen con frecuencia en los datos de texto. La biblioteca de wordcloud es eficaz porque la representación de palabras clave forma una imagen de color similar a la nube, para capturar mejor los datos de texto principales de un vistazo. Más información sobre 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")
Por último, use word2vec para vectorizar el texto. La técnica word2vec crea una representación vectorial de cada palabra del texto. Las palabras usadas en contextos similares, o que tienen relaciones semánticas, se capturan de forma eficaz a través de su proximidad en el espacio vectorial. Esta cercanía indica que las palabras similares tienen vectores de palabra similares.
# 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))
Paso 4: Entrenamiento y evaluación del modelo
Con los datos implementados, defina el modelo. En esta sección, entrenará un modelo de regresión logística para clasificar el texto vectorizado.
Preparación de conjuntos de datos de entrenamiento y prueba
# Split the dataset into training and testing
(train_df, test_df) = vec_df.randomSplit((0.8, 0.2), seed=42)
Seguimiento de experimentos de aprendizaje automático
Un experimento de aprendizaje automático es la unidad principal de organización y control para todas las ejecuciones de aprendizaje automático relacionadas. Una ejecución corresponde a una sola ejecución de código de modelo.
El seguimiento de experimentos de aprendizaje automático administra todos los experimentos y sus componentes, por ejemplo, parámetros, métricas, modelos y otros artefactos. El seguimiento permite la organización de todos los componentes necesarios de un experimento de aprendizaje automático específico. También permite la reproducción sencilla de los resultados pasados con experimentos guardados. Obtenga más información sobre los experimentos de aprendizaje automático en Microsoft Fabric.
# Build the logistic regression classifier
lr = (
LogisticRegression()
.setMaxIter(max_iter)
.setFeaturesCol("features")
.setLabelCol("labelIdx")
.setWeightCol("weight")
)
Ajuste de hiperparámetros
Cree una cuadrícula de parámetros para buscar en los hiperparámetros. Después, cree un estimador de evaluador cruzado para generar un modelo de CrossValidator
:
# 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,
)
Evaluación del modelo
Podemos evaluar los modelos en el conjunto de datos de prueba para compararlos. Un modelo bien entrenado debe demostrar un alto rendimiento, en las métricas pertinentes, cuando se ejecuta en los conjuntos de datos de validación y prueba.
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
Seguimiento de experimentos mediante MLflow
Inicie el proceso de entrenamiento y evaluación. Use MLflow para realizar un seguimiento de todos los experimentos y los parámetros de registro, las métricas y los modelos. Toda esta información se registra bajo el nombre del experimento en el área de trabajo.
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 los experimentos:
- Seleccione el área de trabajo en el panel de navegación izquierdo.
- Busque y seleccione el nombre del experimento; en este caso, sample_aisample-textclassification
Paso 5: Puntuación y guardado de resultados de predicción
Microsoft Fabric permite a los usuarios poner en marcha modelos de aprendizaje automático con la función escalable PREDICT
. Esta función admite la puntuación por lotes (o la inferencia por lotes) en cualquier motor de proceso. Puede crear predicciones por lotes directamente desde un cuaderno o la página de elementos de un modelo determinado. Para más información sobre PREDICT y cómo usarlo en Fabric, consulte puntuación de modelos de Machine Learning con PREDICT en Microsoft Fabric.
A partir de los resultados de la evaluación anterior, el modelo 1 tiene las métricas más grandes de área bajo la curva de precisión-coincidencia (AUPRC) y área bajo la curva de característica operativa del receptor (AUC-ROC). Por lo tanto, debe usar el modelo 1 para la predicción.
La medida AUC-ROC se usa ampliamente para medir el rendimiento de los clasificadores binarios. Sin embargo, a veces resulta más adecuado evaluar el clasificador en función de las medidas de AUPRC. El gráfico de AUC-ROC visualiza el equilibrio entre la tasa positiva verdadera (TPR) y la tasa de falsos positivos (FPR). La curva AUPRC combina precisión (valor predictivo positivo o PPV) y recuperación (tasa positiva verdadera o TPR) en una sola visualización.
# 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.")