Del via


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 både Word2vec NLP (natural language processing) og logistisk regression på Spark til at bestemme genren for en bog fra datasættet for British Library-bogen. Afgørelsen er 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 både Word2vec NLP og logistisk regression, og spor eksperimenter med MLflow og funktionen Fabric autologging
  • Indlæs modellen til maskinel indlæring for at få point og forudsigelser

Forudsætninger

Følg med i en notesbog

Hvis du vil følge med i en notesbog, har du følgende muligheder:

  • Åbn og kør den indbyggede notesbog.
  • Upload din notesbog fra GitHub.

Åbn den indbyggede notesbog

Eksemplet på genreklassificering titel notesbog følger med dette selvstudium.

  1. Hvis du vil åbne eksempelnotesbogen til dette selvstudium, skal du følge vejledningen i Forbered dit system til selvstudier om datavidenskab.

  2. Sørg for at vedhæfte 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.

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 et bibliotek.

  • Hvis du vil installere et bibliotek, skal du kun bruge de indbyggede installationsfunktioner (%pip eller %conda) for din notesbog i din aktuelle notesbog.
  • Alternativt kan du oprette et Fabric-miljø og installere biblioteker fra offentlige kilder eller uploade brugerdefinerede biblioteker til det. Derefter kan administratoren af arbejdsområdet vedhæfte miljøet som standard for arbejdsområdet. På det tidspunkt bliver alle biblioteker i miljøet tilgængelige til brug i alle notesbøger og alle Spark-jobdefinitioner i det pågældende arbejdsområde. Du kan finde flere oplysninger om miljøer ved at gå til opret, konfigurer og brug et miljø i Microsoft Fabric-ressourcen .

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

Seddel

PySpark-kernen genstartes, når %pip install har kørt. Installér de biblioteker, du skal bruge, 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 for British Library-bogen indeholder metadata om bøger fra British Library. Et samarbejde mellem biblioteket og Microsoft digitaliserede de oprindelige ressourcer, der blev til datasættet. Metadataene er klassificeringsoplysninger, der angiver, om en bog er fiktion eller nonfiction. I følgende diagram vises et rækkeeksempel på datasættet.

BL-post-id Ressourcetype Navn Datoer, der er knyttet til navnet Navnstype Rolle Alle navne Titel Varianttitler Serietitel Tal i serier Udgivelsesland Udgivelsessted Forlægger Udgivelsesdato Oplag Fysisk beskrivelse Dewey-klassificering BL-hyldemærke Emner Genre Sprog Noter 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

Med dette datasæt er vores mål at oplære en klassificeringsmodel, der bestemmer genren for en bog, der kun er baseret på bogens titel.

Definer følgende parametre for at 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

Følgende kodestykke downloader en offentligt tilgængelig version af datasættet og gemmer det derefter i et Fabric lakehouse:

Vigtig

Føj et lakehouse- til notesbogen, før du kører den. Hvis du ikke gør det, resulterer det i 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.z13.web.core.windows.net/data/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 de 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

Følgende kodestykke definerer de nødvendige hyperparametre til modeltræning:

Vigtig

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. Du kan finde flere oplysninger om automatisk logning ved at gå til Autologging i Microsoft Fabric-ressourcen .

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

# Set up Mlflow for experiment tracking

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

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 kommandoen display 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

Hvis du vil rense dataene, skal du fjerne dubleterne:

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

Hvis du vil tokenisere datasættet, skal du opdele afsnit og sætninger i mindre enheder. 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). Følgende kodestykke dækker disse trin:

# 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 præsenterer nøgleord, der ofte vises i tekstdata, er en visuelt fremtrædende præsentation. WordCloud-biblioteket er effektivt, fordi gengivelsen af nøgleordet udgør et skylignende farvebillede, så du bedre kan registrere de primære tekstdata på et øjeblik. Besøg denne ressource for at få flere oplysninger om wordcloud.

Følgende kodestykke dækker disse trin:

# 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 NLP til at vektorisere teksten. Word2vec NLP-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. Følgende kodestykke dækker disse trin:

# 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

Følgende kodestykke opdeler datasættet:

# 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

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 og administrere alle de komponenter, som et bestemt maskinlæringseksperiment kræver. Det muliggør også nem reproduktion af tidligere resultater med gemte eksperimenter. Besøg Eksperimenter med maskinel indlæring i Microsoft Fabric for at få flere oplysninger.

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. Følgende kodestykke dækker disse trin:

# 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, som vist i følgende kodestykke:

# 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 veloplært model skal demonstrere høj ydeevne på de relevante målepunkter, når den køres i forhold til validerings- og testdatasættene. Følgende kodestykke dækker disse trin:

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. I arbejdsområdet logføres alle disse oplysninger under eksperimentnavnet. Følgende kodestykke dækker disse trin:

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

Skærmbillede af et eksperiment.

Trin 5: Scor og gem forudsigelsesresultater

Microsoft Fabric giver brugerne mulighed for at anvende modeller til maskinel indlæring med den skalerbare PREDICT funktion. Denne funktion understøtter batchscore (eller batchafledning) i et hvilket som helst beregningsprogram. Du kan oprette batchforudsigelser direkte fra en notesbog eller fra elementsiden for en bestemt model. Du kan finde flere oplysninger om funktionen PREDICT , og hvordan du bruger den i Fabric, ved at gå til Scoring af maskinel indlæringsmodel med PREDICT i Microsoft Fabric.

Fra vores 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.

Den AUC-ROC måling 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 afvejninger mellem sand positiv kurs (TPR) og falsk positiv rate (FPR). AUPRC-kurven kombinerer både præcision (positiv forudsigende værdi eller PPV) og genkaldelse (sand positiv hastighed eller TPR) i en enkelt visualisering. Følgende kodestykker dækker disse trin:

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