Selvstudium: Opret, evaluer og scor en tekstklassificeringsmodel

I dette selvstudium præsenteres et samlet eksempel på en Synapse Data Science-arbejdsproces for en model til tekstklassificering i Microsoft Fabric. Scenariet bruger word2vec og logistisk regression på Spark til at bestemme genren for en bog fra British Library-bogdatasættet udelukkende baseret på bogens titel.

I dette selvstudium beskrives disse trin:

  • Installér brugerdefinerede biblioteker
  • Indlæs dataene
  • Forstå og behandl dataene med sonderende dataanalyse
  • Oplær en model til maskinel indlæring med word2vec og logistisk regression, og spor eksperimenter ved hjælp af MLflow og funktionen Fabric autologging
  • Indlæs modellen til maskinel indlæring for at få point og forudsigelser

Forudsætninger

  • Få et Microsoft Fabric-abonnement. Du kan også tilmelde dig en gratis Prøveversion af Microsoft Fabric.

  • Log på Microsoft Fabric.

  • Brug oplevelsesskifteren i venstre side af startsiden til at skifte til Synapse Data Science-oplevelsen.

    Screenshot of the experience switcher menu, showing where to select Data Science.

Følg med i en notesbog

Du kan vælge en af disse indstillinger for at følge med i en notesbog:

  • Åbn og kør den indbyggede notesbog i Synapse Data Science-oplevelsen
  • Upload din notesbog fra GitHub til Synapse Data Science-oplevelsen

Åbn den indbyggede notesbog

Notesbogen titelgenreklassificering følger med dette selvstudium.

Sådan åbner du selvstudiets indbyggede eksempelnotesbog i Synapse Data Science-oplevelsen:

  1. Gå til startsiden Synapse Data Science.

  2. Vælg Brug et eksempel.

  3. Vælg det tilsvarende eksempel:

    • Fra standardfanen End-to-end-arbejdsprocesser (Python), hvis eksemplet er til et Python-selvstudium.
    • Fra fanen Komplette arbejdsprocesser (R), hvis eksemplet er til et R-selvstudium.
    • Fra fanen Hurtige selvstudier , hvis eksemplet er til et hurtigt selvstudium.
  4. Vedhæft et lakehouse til notesbogen , før du begynder at køre kode.

Importér notesbogen fra GitHub

AIsample – Title Genre Classification.ipynb er den notesbog, der følger med dette selvstudium.

Hvis du vil åbne den medfølgende notesbog til dette selvstudium, skal du følge vejledningen i Forbered dit system til selvstudier om datavidenskab for at importere notesbogen til dit arbejdsområde.

Hvis du hellere vil kopiere og indsætte koden fra denne side, kan du oprette en ny notesbog.

Sørg for at vedhæfte et lakehouse til notesbogen , før du begynder at køre kode.

Trin 1: Installér brugerdefinerede biblioteker

I forbindelse med udvikling af modeller til maskinel indlæring eller ad hoc-dataanalyse skal du muligvis hurtigt installere et brugerdefineret bibliotek til din Apache Spark-session. Du har to muligheder for at installere biblioteker.

  • Brug funktionerne til indbygget installation (%pip eller %conda) i notesbogen til at installere et bibliotek, kun i din aktuelle notesbog.
  • Du kan også oprette et Fabric-miljø, installere biblioteker fra offentlige kilder eller uploade brugerdefinerede biblioteker til det, og derefter kan administratoren af arbejdsområdet vedhæfte miljøet som standard for arbejdsområdet. Alle biblioteker i miljøet bliver derefter tilgængelige til brug i alle notesbøger og Spark-jobdefinitioner i arbejdsområdet. Du kan få flere oplysninger om miljøer under Opret, konfigurer og brug et miljø i Microsoft Fabric.

I klassificeringsmodellen skal du bruge wordcloud biblioteket til at repræsentere ordets hyppighed i tekst, hvor størrelsen på et ord repræsenterer dets hyppighed. I dette selvstudium skal du bruge %pip install til at installere wordcloud i din notesbog.

Bemærk

PySpark-kernen genstartes efter %pip install kørsler. Installer de nødvendige biblioteker, før du kører andre celler.

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

Trin 2: Indlæs dataene

Datasættet har metadata om bøger fra British Library, som et samarbejde mellem biblioteket og Microsoft digitaliserede. Metadataene er klassificeringsoplysninger, der angiver, om en bog er fiktion eller nonfiction. Med dette datasæt er målet at oplære en klassificeringsmodel, der bestemmer genren for en bog, kun baseret på dens titel.

BL-post-id Ressourcetype Navn Datoer, der er knyttet til navnet Navnstype Role Alle navne Titel Varianttitler Serietitel Tal i serier Udgivelsesland Udgivelsessted Udgiver Udgivelsesdato Edition. Fysisk beskrivelse Dewey-klassificering BL-hyldemærke Emner Genre Sprog Bemærkninger BL-post-id for fysisk ressource 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 til digitaliseret bog Kommenteret
014602826 Monografi Yearsley, Ann 1753-1806 Person Mere, Hannah, 1745-1833 [person]; Yearsley, Ann, 1753-1806 [person] Digte ved flere lejligheder [Med en prefatory brev af Hannah More.] England London 1786 4. udgave MANUSKRIPT note Digital Store 11644.d.32 Engelsk 003996603 Falsk
014602830 Monografi A, T. Person Oldham, John, 1653-1683 [person]; A, T. [person] En Satyr mod Vertue. (Et digt: formodes at blive talt af en Town-Hector [Af John Oldham. Forordet signeret: T. A.]) England London 1679 15 sider (4°) Digital Store 11602.ee.10. (2.) Engelsk 000001143 Falsk

Definer følgende parametre, så du kan anvende denne notesbog på forskellige datasæt:

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

Download datasættet, og upload det til lakehouse

Denne kode downloader en offentligt tilgængelig version af datasættet og gemmer den derefter i et Fabric lakehouse.

Vigtigt

Føj et lakehouse til notesbogen, før du kører den. Hvis du ikke gør det, medfører det en fejl.

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

Importér påkrævede biblioteker

Før du behandler dem, skal du importere påkrævede biblioteker, herunder bibliotekerne til Spark og 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

Definer hyperparametre

Definer nogle hyperparametre til modeltræning.

Vigtigt

Rediger kun disse hyperparametre, hvis du forstår hver parameter.

# 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

Begynd at optage den tid, det kræver at køre denne notesbog:

# Record the notebook running time
import time

ts = time.time()

Konfigurer sporing af MLflow-eksperiment

Automatisk logføring udvider MLflow-logføringsfunktionerne. Automatisk logning registrerer automatisk inputparameterværdierne og outputmetrikværdierne for en model til maskinel indlæring, når du oplærer den. Du logfører derefter disse oplysninger til arbejdsområdet. I arbejdsområdet kan du få adgang til og visualisere oplysningerne med MLflow-API'erne eller det tilsvarende eksperiment i arbejdsområdet. Hvis du vil vide mere om automatisk logning, skal du se Automatisklogning i Microsoft Fabric.

# Set up Mlflow for experiment tracking

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

Hvis du vil deaktivere automatisk logning af Microsoft Fabric i en notesbogsession, skal du ringe mlflow.autolog() og angive disable=True:

Læs rådata fra lakehouse

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

Trin 3: Udfør udforskning af dataanalyse

Udforsk datasættet med display kommandoen for at få vist statistikker på højt niveau for datasættet og for at få vist diagramvisninger:

display(raw_df.limit(20))

Forbered dataene

Fjern dubleterne for at rense dataene:

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

display(df.limit(20))

Anvend klassejustering for at løse eventuelle forskelle:

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

Opdel afsnit og sætninger i mindre enheder for at tokenisere datasættet. På den måde bliver det nemmere at tildele betydning. Fjern derefter stopordene for at forbedre ydeevnen. Fjernelse af stopord omfatter fjernelse af ord, der ofte forekommer på tværs af alle dokumenter i corpus. Fjernelse af Stopword er et af de mest anvendte forbehandlingstrin i NLP-programmer (Natural Language Processing).

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

Vis wordcloud-biblioteket for hver klasse. Et wordcloud-bibliotek er en visuelt fremtrædende præsentation af nøgleord, der ofte vises i tekstdata. WordCloud-biblioteket er effektivt, fordi gengivelsen af nøgleord udgør et skylignende farvebillede, så du bedre kan registrere de primære tekstdata på et øjeblik. Få mere at vide om 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")

Til sidst skal du bruge word2vec til at vektorisere teksten. Word2vec-teknikken opretter en vektorrepræsentation af hvert ord i teksten. Ord, der bruges i lignende kontekster, eller som har semantiske relationer, registreres effektivt via deres nærhed i vektorområdet. Denne nærhed angiver, at lignende ord har lignende ordvektorer.

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

Trin 4: Oplær og evaluer modellen

Med dataene på plads skal du definere modellen. I dette afsnit oplærer du en logistisk regressionsmodel til at klassificere den vektoriserede tekst.

Forbered oplærings- og testdatasæt

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

Spor eksperimenter med maskinel indlæring

Et maskinel indlæringseksperiment er den primære enhed for organisation og kontrol for alle relaterede machine learning-kørsler. En kørsel svarer til en enkelt udførelse af modelkoden.

Sporing af eksperimenter med maskinel indlæring administrerer alle eksperimenter og deres komponenter, f.eks. parametre, målepunkter, modeller og andre artefakter. Sporing gør det muligt at organisere alle de påkrævede komponenter i et bestemt maskinel indlæringseksperiment. Det muliggør også nem reproduktion af tidligere resultater med gemte eksperimenter. Få mere at vide om eksperimenter med maskinel indlæring i Microsoft Fabric.

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

Juster hyperparametre

Opret et gitter med parametre for at søge efter hyperparametrene. Opret derefter en vurdering på tværs af evaluatoren for at oprette en CrossValidator model:

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

Evaluer modellen

Vi kan evaluere modellerne i testdatasættet for at sammenligne dem. En veltrænet model skal demonstrere høj ydeevne på de relevante målepunkter, når den køres i forhold til validerings- og testdatasættene.

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

Spor eksperimenter ved hjælp af MLflow

Start oplærings- og evalueringsprocessen. Brug MLflow til at spore alle eksperimenter og logføre parametre, målepunkter og modeller. Alle disse oplysninger logføres under eksperimentnavnet i arbejdsområdet.

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

Sådan får du vist dine eksperimenter:

  1. Vælg dit arbejdsområde i venstre navigationsrude
  2. Find og vælg eksperimentnavnet – i dette tilfælde sample_aisample-tekstklassificering

Screenshot of an experiment.

Trin 5: Scor og gem forudsigelsesresultater

Microsoft Fabric giver brugerne mulighed for at anvende modeller til maskinel indlæring med den PREDICT skalerbare funktion. Denne funktion understøtter batchscore (eller batchafledning) i et hvilket som helst beregningsprogram. Du kan oprette batchforudsigelser direkte fra en notesbog eller elementsiden for en bestemt model. Hvis du vil vide mere om PREDICT, og hvordan du bruger den i Fabric, skal du se Scoring af model til maskinel indlæring med PREDICT i Microsoft Fabric.

Fra de foregående evalueringsresultater har model 1 de største målepunkter for både Area Under the Precision-Recall Curve (AUPRC) og Area Under the Curve Receiver Operating Characteristic (AUC-ROC). Derfor skal du bruge model 1 til forudsigelse.

AUC-ROC-målingen bruges i vid udstrækning til at måle ydeevnen for binære klassificeringer. Det bliver dog nogle gange mere hensigtsmæssigt at evaluere klassificeringen baseret på AUPRC-målinger. Diagrammet AUC-ROC visualiserer afvejning mellem true positive rate (TPR) og false positive rate (FPR). AUPRC-kurven kombinerer præcision (positiv forudsigende værdi eller PPV) og genkaldelse (sand positiv hastighed eller TPR) i en enkelt visualisering.

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