Esercitazione: creare, valutare e assegnare un punteggio a un modello di classificazione testo
Questa esercitazione presenta un esempio end-to-end di un flusso di lavoro di data science Synapse per un modello di classificazione testo in Microsoft Fabric. Lo scenario usa word2vec e la regressione logistica, in Spark, per determinare il genere di un libro dal set di dati dei libri della British Library, esclusivamente in base al titolo del libro.
L'esercitazione illustra questi passaggi:
- Installare librerie personalizzate
- Caricare i dati
- Comprendere ed elaborare i dati con l'analisi esplorativa dei dati
- Eseguire il training di un modello di Machine Learning con word2vec e regressione logistica e tenere traccia degli esperimenti con MLflow e la funzionalità di assegnazione automatica di Fabric
- Caricare il modello di Machine Learning per l'assegnazione di punteggi e previsioni
Prerequisiti
Ottenere una sottoscrizione di Microsoft Fabric. In alternativa, iscriversi per ottenere una versione di valutazione di Microsoft Fabric gratuita.
Accedere a Microsoft Fabric.
Usare il selettore dell'esperienza nell'angolo inferiore sinistro della homepage per passare a Fabric.
- Se non si ha un lakehouse di Microsoft Fabric, crearne uno seguendo la procedura descritta in Creare un lakehouse in Microsoft Fabric.
Seguire la procedura in un notebook
È possibile scegliere una di queste opzioni per seguire la procedura in un notebook:
- Aprire ed eseguire il notebook predefinito.
- Carica il tuo notebook da GitHub.
Aprire il notebook predefinito
Il notebook di esempio per la classificazione dei generi del titolo accompagna questa esercitazione.
Per aprire il notebook di esempio per questa esercitazione, seguire le istruzioni riportate in Preparare il sistema per le esercitazioni sull'analisi scientifica dei dati.
Assicurarsi di collegare una lakehouse al notebook prima di iniziare a eseguire il codice.
Importare il notebook da GitHub
AIsample - Title Genre Classification.ipynb è il notebook che accompagna questa esercitazione.
Per aprire il notebook di accompagnamento per questa esercitazione, seguire le istruzioni riportate in Preparare il sistema per le esercitazioni di data science per importare il notebook nell'area di lavoro.
Se si preferisce copiare e incollare il codice da questa pagina, è possibile creare un nuovo notebook.
Assicurarsi di collegare un lakehouse al notebook prima di iniziare a eseguire il codice.
Passaggio 1: installare librerie personalizzate
Per lo sviluppo di modelli di Machine Learning o l'analisi dei dati ad hoc, potrebbe essere necessario installare rapidamente una libreria personalizzata per la sessione di Apache Spark. Sono disponibili due opzioni per installare le librerie.
- Usare le funzionalità di installazione inline (
%pip
o%conda
) del notebook per installare una libreria solo nel notebook corrente. - In alternativa, è possibile creare un ambiente Fabric, installare librerie da origini pubbliche o caricarvi librerie personalizzate e quindi l'amministratore dell'area di lavoro può collegare l'ambiente come predefinito per l'area di lavoro. Tutte le librerie nell'ambiente diventano quindi disponibili per l'uso in qualsiasi notebook e definizioni di processo Spark nell'area di lavoro. Per altre informazioni sugli ambienti, vedere creare, configurare e usare un ambiente in Microsoft Fabric.
Per il modello di classificazione, usare la libreria wordcloud
per rappresentare la frequenza delle parole nel testo, in cui la dimensione di una parola rappresenta la sua frequenza. Per questa esercitazione, usare %pip install
per installare wordcloud
nel notebook.
Nota
Il kernel PySpark viene riavviato dopo l'esecuzione di %pip install
. Installare le librerie necessarie prima di eseguire qualsiasi altra cella.
# Install wordcloud for text visualization by using pip
%pip install wordcloud
Passaggio 2: caricare i dati
Il set di dati contiene i metadati relativi ai libri della British Library, digitalizzati in seguito a una collaborazione tra la libreria e Microsoft. I metadati sono informazioni di classificazione per indicare se un libro è di narrativa o di saggistica. Con questo set di dati, l'obiettivo è eseguire il training di un modello di classificazione che determina il genere di un libro, solo in base al titolo.
BL record ID | Tipo di risorsa | Nome | Date associate al nome | Tipo di nome | Ruolo | Tutti i nomi | Title | Titoli variante | Titolo serie | Numero all'interno della serie | Paese di pubblicazione | Luogo di pubblicazione | Publisher | Data di pubblicazione | Edition | Descrizione fisica | Classificazione dewey | Segnaposto BL | Argomenti | Genre | Lingue | Note | ID del record BL per la risorsa fisica | 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 | Collegamento a un libro digitalizzato | Annotato |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
014602826 | Monografia | Ann Yearsley | 1753-1806 | person | More, Hannah, 1745-1833 [person]; Yearsley, Ann, 1753-1806 [person] | Poems on several occasions [With a prefatory letter by Hannah More.] | England | Londra | 1786 | Fourth edition MANUSCRIPT note | Digital Store 11644.d.32 | italiano | 003996603 | Falso | |||||||||||||||||||||||||||||||
014602830 | Monografia | A, T. | person | Oldham, John, 1653-1683 [person]; A, T. [person] | A Satyr against Vertue. (A poem: supposed to be spoken by a Town-Hector [By John Oldham. The preface signed: T. A.]) | England | Londra | 1679 | 15 pages (4°) | Digital Store 11602.ee.10. (2) | italiano | 000001143 | Falso |
Definire i parametri seguenti in modo da poter applicare questo notebook in set di dati diversi:
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
Scaricare il set di dati e caricarlo nel lakehouse
Questo codice scarica una versione disponibile pubblicamente del set di dati e la archivia in un lakehouse di Fabric.
Importante
Aggiungere una lakehouse al notebook prima di eseguirlo. In caso contrario, verrà generato un errore.
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.")
Importare le librerie obbligatorie
Prima di qualsiasi elaborazione, è necessario importare le librerie necessarie, incluse le librerie per 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
Definire gli iperparametri
Definire gli iperparametri per il training dei modelli.
Importante
Modificare questi iperparametri solo se si comprende ogni parametro.
# 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
Avviare la registrazione del tempo necessario per eseguire questo notebook:
# Record the notebook running time
import time
ts = time.time()
Configurare il rilevamento dell'esperimento di MLflow
La registrazione automatica estende le funzionalità di registrazione di MLflow. La registrazione automatica acquisisce automaticamente i valori dei parametri di input e le metriche di output di un modello di Machine Learning durante il training. Si registrano quindi queste informazioni nell'area di lavoro. Nell'area di lavoro è possibile accedere e visualizzare le informazioni con le API MLflow o l'esperimento corrispondente nell'area di lavoro. Per altre informazioni sulla registrazione automatica, vedere Registrazione automatica in Microsoft Fabric.
# Set up Mlflow for experiment tracking
mlflow.set_experiment(EXPERIMENT_NAME)
mlflow.autolog(disable=True) # Disable Mlflow autologging
Per disabilitare la registrazione automatica di tag di Microsoft Fabric in una sessione del notebook, chiamare mlflow.autolog()
e impostare disable=True
:
Leggere i dati non elaborati di data dal lakehouse
raw_df = spark.read.csv(f"{DATA_FOLDER}/raw/{DATA_FILE}", header=True, inferSchema=True)
Passaggio 3: eseguire l'analisi esplorativa dei dati
Esplorare il set di dati con il comando display
per visualizzare le statistiche di alto livello per il set di dati e visualizzare le visualizzazioni del grafico:
display(raw_df.limit(20))
Preparare i dati
Rimuovere i duplicati per pulire i dati:
df = (
raw_df.select([TEXT_COL, LABEL_COL])
.where(F.col(LABEL_COL).isin(LABELS))
.dropDuplicates([TEXT_COL])
.cache()
)
display(df.limit(20))
Applicare il bilanciamento della classe per risolvere eventuali distorsioni:
# 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))
Suddividere i paragrafi e le frasi in unità più piccole per tokenizzare il set di dati. In questo modo, diventa più facile assegnare significato. Rimuovere quindi le parole non significative per migliorare le prestazioni. La rimozione delle parole non significative comporta la rimozione di parole che compaiono comunemente in tutti i documenti del corpus. La rimozione delle parole non significative è uno dei passaggi di pre-elaborazione usati più comunemente nelle applicazioni di elaborazione del linguaggio naturale (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))
Visualizzare la libreria wordcloud per ogni classe. Una libreria wordcloud è una presentazione visivamente prominente delle parole chiave che vengono visualizzate di frequente nei dati di testo. La libreria wordcloud è efficace perché il rendering delle parole chiave costituisce un'immagine a colori cloudlike, per acquisire meglio i dati di testo principali a colpo d'occhio. Altre informazioni sul 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")
Usare infine word2vec per vettorizzare il testo. La tecnica word2vec crea una rappresentazione vettoriale di ogni parola nel testo. Le parole usate in contesti simili, o che hanno relazioni semantiche, vengono acquisite in modo efficace attraverso la loro vicinanza nello spazio vettoriale. Questa vicinanza indica che parole simili hanno vettori di parole simili.
# 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))
Passaggio 4: eseguire il training e valutare il modello
Con i dati disponibili, definire il modello. In questa sezione viene eseguito il training di un modello di regressione logistica per classificare il testo vettorializzato.
Preparare i set di dati di training e di test
# Split the dataset into training and testing
(train_df, test_df) = vec_df.randomSplit((0.8, 0.2), seed=42)
Rilevamento degli esperimenti di Machine Learning
Un esperimento di Machine Learning è l'unità primaria di organizzazione e controllo per tutte le esecuzioni di Machine Learning correlate. Un'esecuzione corrisponde a una singola esecuzione del codice dei modelli.
Il rilevamento degli esperimenti di Machine Learning gestisce tutti gli esperimenti e i relativi componenti, ad esempio parametri, metriche, modelli e altri artefatti. Il rilevamento consente l'organizzazione di tutti i componenti necessari di un esperimento di Machine Learning specifico. Consente inoltre di riprodurre facilmente i risultati precedenti con esperimenti salvati. Altre informazioni sugli esperimenti di Machine Learning in Microsoft Fabric.
# Build the logistic regression classifier
lr = (
LogisticRegression()
.setMaxIter(max_iter)
.setFeaturesCol("features")
.setLabelCol("labelIdx")
.setWeightCol("weight")
)
Ottimizzare gli iperparametri
Creare una griglia di parametri per eseguire la ricerca sugli iperparametri. Compilare quindi uno strumento di stima incrociato per produrre un modello 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,
)
Valutare il modello
È possibile valutare i modelli nel set di dati di test per confrontarli. Un modello con training corretto deve dimostrare prestazioni elevate, sulle metriche pertinenti, quando vengono eseguite sui set di dati di convalida e test.
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
Rilevamento degli esperimenti tramite MLflow
Avviare il processo di training e valutazione. Usare MLflow per rilevare tutti gli esperimenti e registrare parametri, metriche e modelli. Tutte queste informazioni vengono registrate sotto il nome dell'esperimento nell'area di lavoro.
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,
}
)
Per visualizzare gli esperimenti:
- Selezionare un'area di lavoro nel riquadro di spostamento a sinistra
- Trovare e selezionare il nome dell'esperimento, in questo caso sample_aisample-textclassification
Passaggio 5: assegnare un punteggio e salvare i risultati della previsione
Microsoft Fabric consente agli utenti di rendere operativi i modelli di Machine Learning con la funzione scalabile PREDICT
. Questa funzione supporta l'assegnazione dei punteggi batch (o l'inferenza batch) in qualsiasi motore di calcolo. È possibile creare previsioni batch direttamente da un notebook o dalla pagina degli elementi per un determinato modello. Per altre informazioni su PREDICT e su come usarlo in Fabric, vedere Assegnazione dei punteggi dei modelli di Machine Learning con PREDICT in Microsoft Fabric.
Dai risultati di valutazione precedenti, il modello 1 ha i valori più alti sia per l'Area sotto la curva Precision-Recall (AUPRC) che per l'Area sotto la curva Receiver Operating Characteristic (AUC-ROC). Pertanto, è consigliabile usare il modello 1 per la previsione.
La misura AUC-ROC viene ampiamente usata per misurare le prestazioni dei classificatori binari. Tuttavia, a volte diventa più appropriato valutare il classificatore in base alle misurazioni AUPRC. Il grafico AUC-ROC visualizza il compromesso tra il tasso positivo reale (TPR) e il tasso falso positivo (FPR). La curva AUPRC combina la precisione (valore predittivo positivo o PPV) e il richiamo (tasso positivo reale o TPR) in una singola visualizzazione.
# 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.")