Freigeben über


Lernprogramm: Erstellen, Auswerten und Bewerten eines Textklassifizierungsmodells

Dieses Lernprogramm zeigt ein End-to-End-Beispiel eines Synapse Data Science-Workflows für ein Textklassifizierungsmodell in Microsoft Fabric. Das Szenario verwendet word2vec und logistische Regression, auf Spark, um das Genre eines Buchs aus dem British Library-Buch-Dataset zu bestimmen, ausschließlich basierend auf dem Titel des Buchs.

In diesem Lernprogramm werden die folgenden Schritte behandelt:

  • Installieren von benutzerdefinierten Bibliotheken
  • Laden der Daten
  • Verstehen und Verarbeiten der Daten mit explorativer Datenanalyse
  • Trainieren eines Machine Learning-Modells mit word2vec und logistischer Regression und Verfolgen von Experimenten mit MLflow und der Fabric-Autologging-Funktion
  • Laden des Machine Learning-Modells zum Bewerten und Vorhersagen

Voraussetzungen

Notebook für das Tutorial

Sie können eine der folgenden Optionen auswählen, um in einem Notizbuch mitzuarbeiten:

  • Öffnen sie das integrierte Notizbuch, und führen Sie es aus.
  • Laden Sie Ihr Notizbuch von GitHub hoch.

Öffnen des integrierten Notizbuchs

Das Beispiel-Notizbuch zur Titel-Genre-Klassifizierung begleitet dieses Lernprogramm.

  1. Um das Beispielnotizbuch für dieses Lernprogramm zu öffnen, befolgen Sie die Anweisungen in Vorbereiten Ihres Systems für Data Science-Lernprogramme.

  2. Fügen Sie ein Lakehouse an das Notebook an, bevor Sie mit der Ausführung von Code beginnen.

Importieren des Notizbuchs aus GitHub

In diesem Tutorial wird das Notebook AIsample – Title Genre Classification.ipynb verwendet.

Schritt 1: Installieren von benutzerdefinierten Bibliotheken

Für die Entwicklung von Machine Learning-Modell oder ad-hoc-Datenanalysen müssen Sie möglicherweise schnell eine benutzerdefinierte Bibliothek für Ihre Apache Spark-Sitzung installieren. Sie haben zwei Optionen zum Installieren von Bibliotheken.

  • Verwenden Sie die Inlineinstallationsfunktionen (%pip oder %conda) Ihres Notizbuchs, um eine Bibliothek nur in Ihrem aktuellen Notizbuch zu installieren.
  • Alternativ können Sie eine Fabric-Umgebung erstellen, Bibliotheken aus öffentlichen Quellen installieren oder benutzerdefinierte Bibliotheken darauf hochladen, und dann kann Ihr Arbeitsbereichsadministrator die Umgebung als Standard für den Arbeitsbereich anfügen. Alle Bibliotheken in der Umgebung werden dann für die Verwendung in allen Notizbüchern und Spark-Auftragsdefinitionen im Arbeitsbereich verfügbar. Weitere Informationen zu Umgebungen finden Sie unter Erstellen, Konfigurieren und Verwenden einer Umgebung in Microsoft Fabric.

Verwenden Sie für das Klassifizierungsmodell die wordcloud Bibliothek, um die Worthäufigkeit im Text darzustellen, wobei die Größe eines Worts seine Häufigkeit darstellt. Verwenden Sie für dieses Tutorial %pip install, um wordcloud in Ihrem Notizbuch zu installieren.

Anmerkung

Der PySpark-Kernel wird neu gestartet, nachdem %pip install ausgeführt wurde. Installieren Sie die erforderlichen Bibliotheken, bevor Sie andere Zellen ausführen.

# Install wordcloud for text visualization by using pip
%pip install wordcloud

Schritt 2: Laden der Daten

Das Dataset verfügt über Metadaten zu Büchern aus der British Library, die eine Zusammenarbeit zwischen der Bibliothek und Microsoft digitalisiert haben. Die Metadaten sind Klassifizierungsinformationen, um anzugeben, ob ein Buch Fiktion oder Nonfiction ist. Mit diesem Dataset soll ein Klassifizierungsmodell trainiert werden, das das Genre eines Buchs bestimmt, nur basierend auf seinem Titel.

BL-Datensatz-ID Ressourcentyp Name Datumsangaben, die dem Namen zugeordnet sind Nametyp Rolle Alle Namen Titel Variantentitel Titel der Reihe Zahl innerhalb von Datenreihen Veröffentlichungsland Ort der Veröffentlichung Verlag Datum der Veröffentlichung Edition Physische Beschreibung Dewey-Klassifizierung BL-Signatur Themen Genre Sprachen Notizen BL-Datensatz-ID für physische Ressource Klassifizierungs-ID Benutzer-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 Anmerkungen des Annotators 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 zum digitalisierten Buch Annotiert
014602826 Monographie Yearsley, Ann 1753-1806 person Mehr, Hannah, 1745-1833 [Person]; Yearsley, Ann, 1753-1806 [Person] Gedichte zu verschiedenen Anlässen [Mit einem Vorwort von Hannah More.] England London 1786 Fourth edition MANUSCRIPT note Digital Store 11644.d.32 Englisch 003996603 Falsch
014602830 Monographie A, T. person Oldham, John, 1653-1683 [person]; A, T. [person] Ein Satyr gegen Vertue. (A poem: supposed to be spoken by a Town-Hector [By John Oldham. The preface signed: T. A.]) England London 1679 15 Seiten (4°) Digital Store 11602.ee.10. (2.) Englisch 000001143 Falsch

Definieren Sie die folgenden Parameter, damit Sie dieses Notizbuch auf verschiedene Datasets anwenden können:

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

Laden Sie das Dataset herunter und laden Sie es in das Seehaus hoch.

Dieser Code lädt eine öffentlich verfügbare Version des Datasets herunter und speichert sie dann in einem Fabric Lakehouse.

Wichtig

Fügen Sie ein Lakehouse zum Notebook hinzu, bevor Sie es ausführen. Andernfalls tritt ein Fehler auf.

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.")

Importieren erforderlicher Bibliotheken

Vor einer Verarbeitung müssen Sie erforderliche Bibliotheken importieren, einschließlich der Bibliotheken für Spark und 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

Definieren von Hyperparametern

Definieren Sie einige Hyperparameter für die Modellschulung.

Wichtig

Ändern Sie diese Hyperparameter nur, wenn Sie jeden Parameter verstehen.

# 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

Starten Sie die Aufzeichnung der Zeit, die zum Ausführen dieses Notizbuchs erforderlich ist:

# Record the notebook running time
import time

ts = time.time()

Einrichten der MLflow-Experimentnachverfolgung

Die automatische Protokollierung erweitert die MLflow-Protokollierungsfunktionen. Die automatische Erfassung erfasst automatisch die Eingabeparameterwerte und Ausgabemetriken eines Machine Learning-Modells, während Sie es trainieren. Anschließend protokollieren Sie diese Informationen im Arbeitsbereich. Im Arbeitsbereich können Sie auf die Informationen mit den MLflow-APIs oder dem entsprechenden Experiment im Arbeitsbereich zugreifen und visualisieren. Weitere Informationen zum automatischen Logging finden Sie unter Autologging in Microsoft Fabric.

# Set up Mlflow for experiment tracking

mlflow.set_experiment(EXPERIMENT_NAME)
mlflow.autolog(disable=True)  # Disable Mlflow autologging

Rufen Sie mlflow.autolog() auf, und legen Sie disable=True fest, um die automatische Microsoft Fabric-Protokollierung in einer Notebooksitzung zu deaktivieren:

Lesen von Rohdatumsdaten aus dem Lakehouse

raw_df = spark.read.csv(f"{DATA_FOLDER}/raw/{DATA_FILE}", header=True, inferSchema=True)

Schritt 3: Durchführen einer explorativen Datenanalyse

Erkunden Sie das Dataset mit dem Befehl display, um allgemeine Statistiken für das Dataset anzuzeigen und die Diagrammansichten anzuzeigen:

display(raw_df.limit(20))

Vorbereiten der Daten

Entfernen Sie die Duplikate, um die Daten zu bereinigen:

df = (
    raw_df.select([TEXT_COL, LABEL_COL])
    .where(F.col(LABEL_COL).isin(LABELS))
    .dropDuplicates([TEXT_COL])
    .cache()
)

display(df.limit(20))

Wenden Sie den Klassenausgleich an, um alle Verzerrungen zu beheben:

# 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))

Teilen Sie die Absätze und Sätze in kleinere Einheiten auf, um das Dataset zu tokenisieren. Auf diese Weise wird es einfacher, Bedeutung zuzuweisen. Entfernen Sie dann die Stoppwörter, um die Leistung zu verbessern. Das Entfernen von Stoppwörtern umfasst das Entfernen von Wörtern, die häufig in allen Dokumenten im Korpus auftreten. Das Entfernen von Stoppwörtern ist eine der am häufigsten verwendeten Vorverarbeitungsschritte in Anwendungen für die Verarbeitung natürlicher Sprachen (Natural Language Processing, 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))

Zeigen Sie die Wordcloud-Bibliothek für jede Klasse an. Eine Wordcloud-Bibliothek ist eine visuell prominente Darstellung von Schlüsselwörtern, die häufig in Textdaten angezeigt werden. Die Wordcloud-Bibliothek ist effektiv, da das Rendern von Schlüsselwörtern ein cloudähnliches Farbbild bildet, um die Haupttextdaten auf einen Blick besser zu erfassen. Erfahren Sie mehr über 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")

Verwenden Sie schließlich word2vec, um den Text zu vektorisieren. Die Word2vec-Technik erstellt eine Vektordarstellung jedes Worts im Text. Wörter, die in ähnlichen Kontexten verwendet werden oder über semantische Beziehungen verfügen, werden effektiv durch ihre Nähe im Vektorraum erfasst. Diese Nähe weist darauf hin, dass ähnliche Wörter ähnliche Wortvektoren haben.

# 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))

Schritt 4: Trainieren und Bewerten des Modells

Definieren Sie das Modell, nachdem die Daten vorhanden sind. In diesem Abschnitt trainieren Sie ein logistisches Regressionsmodell, um den vektorisierten Text zu klassifizieren.

Vorbereiten von Schulungs- und Testdatensätzen

# Split the dataset into training and testing
(train_df, test_df) = vec_df.randomSplit((0.8, 0.2), seed=42)

Nachverfolgen von Machine Learning-Experimenten

Ein Machine Learning-Experiment ist die primäre Einheit der Organisation und Kontrolle für alle zugehörigen Machine Learning-Ausführungen. Eine Ausführung entspricht einer einzelnen Ausführung von Modellcode.

Die Überwachung des Maschinellen Lernens verwaltet alle Experimente und deren Komponenten, z. B. Parameter, Metriken, Modelle und andere Artefakte. Die Nachverfolgung ermöglicht die Organisation aller erforderlichen Komponenten eines bestimmten Maschinellen Lernexperiments. Es ermöglicht auch die einfache Reproduktion vergangener Ergebnisse mit gespeicherten Experimenten. Erfahren Sie mehr über Maschinelle Lernexperimente in Microsoft Fabric.

# Build the logistic regression classifier
lr = (
    LogisticRegression()
    .setMaxIter(max_iter)
    .setFeaturesCol("features")
    .setLabelCol("labelIdx")
    .setWeightCol("weight")
)

Optimieren von Hyperparametern

Erstellen Sie ein Raster mit Parametern, um über die Hyperparameter zu suchen. Erstellen Sie dann einen Cross-Evaluator-Schätzer, um ein CrossValidator-Modell zu generieren:

# 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,
)

Auswerten des Modells

Wir können die Modelle im Testdatensatz auswerten, um sie zu vergleichen. Ein gut trainiertes Modell sollte bei der Ausführung mit den Validierungs- und Testdatensätzen eine hohe Leistung bei den relevanten Metriken demonstrieren.

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

Nachverfolgen von Experimenten mithilfe von MLflow

Starten Sie den Schulungs- und Evaluierungsprozess. Verwenden Sie MLflow, um alle Experimente nachzuverfolgen und Parameter, Metriken und Modelle zu protokollieren. Alle diese Informationen werden unter dem Namen des Experiments im Arbeitsbereich protokolliert.

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,
        }
    )

Zeigen Sie Ihre Experimente wie folgt an:

  1. Wählen Sie ihren Arbeitsbereich im linken Navigationsbereich aus.
  2. Suchen Sie den Experimentnamen, und wählen Sie ihn aus (in diesem Fall sample_aisample-textclassification).

Screenshot eines Experiments.

Schritt 5: Bewertung und Speichern von Vorhersageergebnissen

Microsoft Fabric ermöglicht Es Benutzern, Machine Learning-Modelle mit der PREDICT skalierbaren Funktion zu operationalisieren. Diese Funktion unterstützt die Batchbewertung (oder den Batchrückschluss) in jeder Compute-Engine. Sie können Batchvorhersagen direkt aus einem Notizbuch oder der Elementseite für ein bestimmtes Modell erstellen. Weitere Informationen zu PREDICT und deren Verwendung in Fabric finden Sie unter Machine Learning-Modellbewertung mit PREDICT in Microsoft Fabric.

Aus den vorherigen Auswertungsergebnissen weist Modell 1 die höchsten Werte sowohl für die "Area Under the Precision-Recall Curve (AUPRC)" als auch für die "Area Under the Curve Receiver Operating Characteristic" (AUC-ROC) auf. Daher sollten Sie Modell 1 für die Vorhersage verwenden.

Das AUC-ROC Measure wird häufig verwendet, um die Leistung binärer Klassifizierer zu messen. Es ist jedoch manchmal besser geeignet, den Klassifizierer basierend auf AUPRC-Messungen zu bewerten. Das AUC-ROC Diagramm visualisiert den Kompromiss zwischen wahrer positiver Rate (TPR) und falsch positiver Rate (FPR). Die AUPRC-Kurve kombiniert Genauigkeit (positiver Vorhersagewert (Positive Predictive Value, PPV)) und Abruf (wahre positive Rate (True Positive Rate, TPR)) in einer einzigen Visualisierung.

# 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.")