Tutorial: Creación, evaluación y puntuación de un modelo de clasificación de texto
Este tutorial presenta un ejemplo de extremo a extremo de un flujo de trabajo de ciencia de datos de Synapse para un modelo de clasificación de texto en Microsoft Fabric. El escenario usa word2vec y la regresión logística en Spark para determinar el género de un libro del conjunto de datos de libros de la Biblioteca Británica en función únicamente del título del libro.
En este tutorial se describen estos pasos:
- Instalación de bibliotecas personalizadas
- Carga de los datos
- Comprender y procesar los datos a través de un análisis de datos exploratorio
- Entrenamiento de un modelo de Machine Learning mediante word2vec y una regresión logística, y seguimiento de experimentos mediante la característica de registro automático de MLflow y Fabric
- Carga del modelo de Machine Learning para puntuar y realizar predicciones
Requisitos previos
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.
Cambie a la experiencia de ciencia de datos de Synapse mediante el conmutador de experiencia en el lado izquierdo de la página principal.
- Si no tiene una casa del lago en Microsoft Fabric, crea una siguiendo los pasos de Crear un lago de datos en Microsoft Fabric.
Seguir en un cuaderno
Puede elegir una de estas opciones para seguir en un cuaderno:
- Abra y ejecute el cuaderno integrado en la experiencia de ciencia de datos de Synapse.
- Cargue su cuaderno desde GitHub a la experiencia de ciencia de datos de Synapse.
Abrir el cuaderno de notas integrado
El cuaderno de notas de muestra Clasificación de género del título acompaña a este tutorial.
Para abrir el cuaderno de muestra integrado en el tutorial en la experiencia de ciencia de datos de Synapse:
Vaya a la página principal de ciencia de datos de Synapse.
Seleccione Utilizar una muestra.
Seleccione la muestra correspondiente:
- Desde la pestaña predeterminada Flujos de trabajo de un extremo a otro (Python), si la muestra es para un tutorial de Python.
- Desde la pestaña Flujos de trabajo de un extremo a otro (R), si la muestra es para un tutorial de R.
- En la pestaña Tutoriales rápidos, si la muestra es para un tutorial rápido.
Adjunte una instancia de LakeHouse al cuaderno antes de empezar a ejecutar código.
Importación del cuaderno desde GitHub
AIsample- Title Genre Classification.ipynb es el cuaderno que acompaña a este tutorial.
Para abrir el cuaderno complementario para este tutorial, siga las instrucciones en Preparación del sistema para los tutoriales de ciencia de datos para importar el cuaderno en el área de trabajo.
Si prefiere copiar y pegar el código de esta página, puede crear un cuaderno nuevo.
Asegúrese de adjuntar una instancia de LakeHouse al cuaderno antes de empezar a ejecutar código.
Paso 1: Instalación de bibliotecas personalizadas
Para desarrollar modelos de Machine Learning o realizar 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.
- Use las funcionalidades de instalación insertadas (
%pip
o%conda
) del cuaderno para instalar una biblioteca solo en el cuaderno actual. - Como alternativa, puede crear un entorno de Fabric, instalar bibliotecas desde orígenes públicos o cargar bibliotecas personalizadas en él y, después, 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 trabajo de Spark del área de trabajo. Para obtener más información sobre los entornos, consulte Creación, configuración y uso de un entorno en Microsoft Fabric.
Para el modelo de clasificación, use la biblioteca wordcloud
para representar la frecuencia de las palabras en un texto, donde el tamaño de una palabra representa su frecuencia. En este tutorial, usará %pip install
para instalar wordcloud
en el cuaderno.
Nota:
El kernel de PySpark se reiniciará después de %pip install
ejecuciones. Si lo necesita, instale bibliotecas antes de ejecutar cualquier otra celda.
# Install wordcloud for text visualization by using pip
%pip install wordcloud
Paso 2: Carga de los datos
El conjunto de datos consta de metadatos sobre libros de la Biblioteca Británica que se han digitalizado a través de la colaboración entre la Biblioteca Británica y Microsoft. Los metadatos son información de clasificación para indicar si un libro es de 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 | Role | Todos los nombres | Título | Títulos variantes | Título de 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 Dewey | Signatura topográfica de BL | Temas | Género | Idiomas | Notas | Id. de registro de BL para el 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 | Vínculo al libro digitalizado | anotado |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
014602826 | Monografía | Yearsley, Ann | 1753-1806 | persona | More, Hannah, 1745-1833 [persona]; Yearsley, Ann, 1753-1806 [persona] | Poems on several occasions [With a prefatory letter by Hannah More.] | Inglaterra | London | 1786 | Cuarta edición de la nota de MANUSCRITO | Digital Store 11644.d.32 | English | 003996603 | False | |||||||||||||||||||||||||||||||
014602830 | Monografía | A, T. | persona | Oldham, John, 1653-1683 [persona]; A, T. [persona] | A Satyr against Vertue. (A poem: supposed to be spoken by a Town-Hector [By John Oldham. The preface signed: T. A.]) | Inglaterra | London | 1679 | 15 páginas (4°) | Digital Store 11602.ee.10. (2.) | English | 000001143 | False |
Defina los parámetros siguientes para aplicar este cuaderno a 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 un almacén de lago de datos
El código siguiente descarga una versión disponible públicamente del conjunto de datos y, a continuación, la almacena en un almacén de Fabric lakehouse.
Importante
Agregue un almacén de lago al cuaderno antes de ejecutarlo. De lo contrario, 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 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
Definición de hiperparámetros
Defina algunos hiperparámetros para el entrenamiento de un 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 del experimento 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 entrene. 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
raw_df = spark.read.csv(f"{DATA_FOLDER}/raw/{DATA_FILE}", header=True, inferSchema=True)
Paso 3: Realiza un análisis exploratorio de los datos
Explore el conjunto de datos mediante 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
Elimine 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 el equilibrio de clases para abordar 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. A continuación, 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 del 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))
Muestre la biblioteca wordcloud para cada clase. Una biblioteca wordcloud es una presentación visualmente destacada de palabras clave que aparecen con frecuencia en datos de texto. La biblioteca wordcloud es eficaz porque la representación de palabras clave forma una imagen de color similar a una nube para capturar mejor los datos de texto principales a simple vista. Más información sobre wordlcloud.
# 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 proximidad 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, entrene 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 Machine Learning
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 única ejecución del código del modelo.
El seguimiento de experimentos de aprendizaje automático administra todos los experimentos y sus componentes, como parámetros, métricas, modelos y otros artefactos. El seguimiento permite organizar 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. A continuación, cree un estimador de evaluador cruzado para generar un modelo 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. Si un modelo se ha entrenado bien, debe demostrar un alto rendimiento en las métricas pertinentes al ejecutarlo con respecto a 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
Uso de MLflow para realizar un seguimiento de los experimentos
Inicie el proceso de entrenamiento y evaluación. Use MLflow para hacer un seguimiento de todos los experimentos y parámetros de registro, métricas y 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:
- En el navegador izquierdo, seleccione su área de trabajo.
- Busque y seleccione el nombre del experimento, en este caso sample_aisample-textclassification
Paso 5: puntuación y guardado de los resultados de predicción
Microsoft Fabric permite a los usuarios poner en marcha modelos de aprendizaje automático mediante una 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 acerca de PREDICT y su uso 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 es más adecuado evaluar el clasificador en función de las mediciones de AUPRC. El gráfico AUC-ROC muestra un gráfico que muestra el equilibrio entre la tasa de verdaderos positivos (TPR) y la tasa de falsos positivos (FPR). La curva AUPRC combina precisión (valor predictivo positivo o PPV) y coincidencia (tasa de verdaderos positivos 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.")