Sdílet prostřednictvím


Kurz: Vytvoření, vyhodnocení a hodnocení modelu klasifikace textu

Tento kurz představuje ucelený příklad pracovního postupu Synapse pro datovou vědu, zaměřený na model klasifikace textu, v Microsoft Fabric. Scénář používá slovo2vec a logistickou regresi ve Sparku k určení žánru knihy z datové sady knih British Library, výhradně na základě názvu knihy.

Tento kurz se věnuje těmto krokům:

  • Instalace vlastních knihoven
  • Načtení dat
  • Pochopení a zpracování dat pomocí průzkumné analýzy dat
  • Trénování modelu strojového učení pomocí word2vec a logistické regrese a sledování experimentů pomocí MLflow a funkce automatického logování Fabric.
  • Načtení modelu strojového učení pro bodování a předpovědi

Požadavky

Sledování v poznámkovém bloku

V poznámkovém bloku můžete zvolit jednu z těchto možností:

  • Otevřete a spusťte integrovaný poznámkový blok.
  • Nahrajte poznámkový blok z GitHubu.

Otevření integrovaného poznámkového bloku

Tento tutoriál doprovází ukázkový poznámkový blok klasifikace žánru nadpisu.

  1. Pokud chcete otevřít ukázkový poznámkový blok pro tento kurz, postupujte podle pokynů v Příprava systému na kurzy datových věd.

  2. Než začnete spouštět kód, nezapomeňte k poznámkovému bloku připojit lakehouse.

Import poznámkového bloku z GitHubu

AIsample - Title Žánrová klasifikace.ipynb poznámkový blok, který doprovází tento kurz.

Krok 1: Instalace vlastních knihoven

Pro vývoj modelů strojového učení nebo ad hoc analýzu dat možná budete muset rychle nainstalovat vlastní knihovnu pro relaci Apache Sparku. Máte dvě možnosti instalace knihoven.

  • Pomocí funkcí pro přímou instalaci (%pip nebo %conda) ve vašem poznámkovém bloku nainstalujte knihovnu pouze v aktuálním poznámkovém bloku.
  • Alternativně můžete vytvořit prostředí Fabric, nainstalovat knihovny z veřejných zdrojů nebo do něj nahrát vlastní knihovny a správce pracovního prostoru pak může nastavit toto prostředí jako výchozí pro pracovní prostor. Všechny knihovny v prostředí se pak zpřístupní pro použití v poznámkových blocích a definicích úloh Sparku v pracovním prostoru. Další informace o prostředích najdete v tématu vytvoření, konfigurace a použití prostředí v Microsoft Fabric.

Pro klasifikační model použijte knihovnu wordcloud k reprezentaci četnosti slov v textu, kde velikost slova představuje jeho frekvenci. Pro účely tohoto tutorialu použijte %pip install k instalaci wordcloud v notebooku.

Poznámka

Po spuštění %pip install se jádro PySpark restartuje. Před spuštěním jiných buněk nainstalujte potřebné knihovny.

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

Krok 2: Načtení dat

Datová sada obsahuje metadata o knihách z Britské knihovny, které byly digitalizovány díky spolupráci knihovny se společností Microsoft. Metadata jsou klasifikační informace, které označují, zda je kniha fiktivní nebo nefiction. Cílem této datové sady je vytrénovat klasifikační model, který určuje žánr knihy, pouze na základě jejího názvu.

ID záznamu BL Typ prostředku Jméno Data přidružená k názvu Typ názvu Role Všechna jména Titul Názvy variant Název řady Číslo v řadě Země publikování Místo publikování Vydavatel Datum zveřejnění Vydání Fyzický popis Klasifikace Dewey Značka police BL Témata Žánr Jazyky Poznámky ID záznamu BL pro fyzický zdroj classification_id uživatelské ID datum_vytvoření identifikátory subjektů datum_zveřejnění_anotátora anotátor_normalizované_datum_publ prohlášení_o_vydání_anotárotora žánr anotátoru annotator_FAST_genre_terms Identifikátor_FAST_předmětové_termy komentáře_annotátora hlavní_jazyk_annotátoru shrnutí pro anotátory jiných jazyků shrnutí_annotátoru_jazyk překlad anotátora anotátor_původní_jazyk annotator_publisher annotator_place_pub anotátor_země název anotátora Odkaz na digitalizovanou knihu okomentováno
014602826 Monografie Yearsley, Ann 1753-1806 osoba More, Hannah, 1745-1833 [person]; Yearsley, Ann, 1753-1806 [person] Básně při různých příležitostech [S úvodním dopisem od Hannah More.] Anglie Londýn 1786 Čtvrtá edice POZNÁMKA K RUKOPISU Digital Store 11644.d.32 Angličtina 003996603 Falešný
014602830 Monografie A, T. osoba Oldham, John, 1653-1683 [osoba]; A, T. [osoba] Satyr proti Vertue. (Báseň: měla být pronesena Town-Hector [Od Johna Oldhama. Předmluva podepsaná: T. A.]) Anglie Londýn 1679 15 stran (4°) Digital Store 11602.ee.10. (2.) Angličtina 000001143 Falešný

Definujte následující parametry, abyste tento poznámkový blok mohli použít u různých datových sad:

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

Stažení datové sady a nahrání do jezera

Tento kód stáhne veřejně dostupnou verzi datové sady a pak ji uloží do objektu Fabric Lakehouse.

Důležitý

Přidejte lakehouse do poznámkového bloku, než jej spustíte. Pokud to neuděláte, dojde k chybě.

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 požadovaných knihoven

Před jakýmkoli zpracováním je potřeba importovat požadované knihovny, včetně knihoven pro Spark a 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

Definování hyperparametrů

Definujte některé hyperparametry pro trénování modelu.

Důležitý

Tyto hyperparametry upravte pouze v případě, že rozumíte jednotlivým parametrům.

# 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

Spusťte záznam času potřebného ke spuštění tohoto poznámkového bloku:

# Record the notebook running time
import time

ts = time.time()

Nastavení sledování experimentů MLflow

Automatické protokolování rozšiřuje možnosti protokolování MLflow. Automatické zachytávání automaticky zaznamenává hodnoty vstupních parametrů a výstupní metriky modelu strojového učení při trénování. Tyto informace pak zapíšete do pracovního prostoru. V pracovním prostoru můžete získat přístup k informacím a vizualizovat je pomocí rozhraní API MLflow nebo odpovídajícího experimentu v pracovním prostoru. Další informace o automatickémlogování najdete v tématu Automatickélogování v Microsoft Fabric.

# Set up Mlflow for experiment tracking

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

Chcete-li v relaci poznámkového bloku zakázat automatické logování Microsoft Fabric, zavolejte mlflow.autolog() a nastavte disable=True:

Číst surová data o datumech z datového jezera

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

Krok 3: Provádění průzkumné analýzy dat

Prozkoumejte datovou sadu pomocí příkazu display, abyste zobrazili statistiky vysoké úrovně datové sady a zobrazili zobrazení grafu:

display(raw_df.limit(20))

Příprava dat

Odstraňte duplicity, ať jsou data čistá.

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

display(df.limit(20))

Použijte vyrovnávání tříd k vyřešení jakéhokoli zkreslení:

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

Rozdělte odstavce a věty do menších jednotek, abyste mohli datovou sadu tokenizovat. Tímto způsobem se snadněji přiřazuje význam. Potom odeberte stopslova, aby se zlepšil výkon systému. Odstranění stopword zahrnuje odebrání slov, která se běžně vyskytují ve všech dokumentech v korpusu. Odebrání stopwordu je jedním z nejčastěji používaných kroků předběžného zpracování v aplikacích pro zpracování přirozeného jazyka (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))

Zobrazí knihovnu wordcloudu pro každou třídu. Knihovna wordcloudu je vizuálně významná prezentace klíčových slov, která se často zobrazují v textových datech. Knihovna wordcloud je efektivní, protože vykreslování klíčových slov tvoří oblačný barevný obrázek, aby bylo lepší zachytit hlavní textová data na první pohled. Další informace owordcloudu

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

Nakonec použijte word2vec k vektorizaci textu. Technika word2vec vytvoří vektorové znázornění každého slova v textu. Slova použitá v podobných kontextech nebo která mají sémantické vztahy, jsou efektivně zachycena prostřednictvím jejich blízkosti ve vektorovém prostoru. Tato blízkost označuje, že podobná slova mají podobné vektory slov.

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

Krok 4: Trénování a vyhodnocení modelu

S daty připravenými definujte model. V této části natrénujete logistický regresní model pro klasifikaci vektorizovaného textu.

Příprava trénovacích a testovacích datových sad

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

Sledování experimentů strojového učení

Experiment strojového učení je primární jednotkou organizace a kontrolou pro všechna související spuštění strojového učení. Spuštění odpovídá jedinému spuštění kódu modelu.

Sledování experimentů strojového učení spravuje všechny experimenty a jejich komponenty, například parametry, metriky, modely a další artefakty. Sledování umožňuje organizaci všech požadovaných komponent konkrétního experimentu strojového učení. Umožňuje také snadnou reprodukci minulých výsledků pomocí uložených experimentů. Další informace o experimentech strojového učení v Microsoft Fabric.

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

Ladění hyperparametrů

Vytvořte mřížku parametrů pro vyhledávání hyperparametrů. Potom vytvořte estimátor křížového vyhodnocení, který vytvoří model 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,
)

Vyhodnocení modelu

Modely testovací datové sady můžeme vyhodnotit a porovnat je. Dobře vytrénovaný model by měl při spuštění na ověřovacích a testovacích datových sadách ukázat vysoký výkon na relevantních metrikách.

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

Sledování experimentů pomocí MLflow

Spusťte proces trénování a vyhodnocení. Pomocí MLflow můžete sledovat všechny experimenty a zaznamenávat parametry, metriky a modely. Všechny tyto informace se protokolují pod názvem experimentu v pracovním prostoru.

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

Pro zobrazení vašich experimentů:

  1. Výběr pracovního prostoru v levém navigačním panelu
  2. Vyhledejte a vyberte název experimentu – v tomto případě sample_aisample-textclassification

snímek obrazovky experimentu

Krok 5: Určení skóre a uložení výsledků předpovědi

Microsoft Fabric umožňuje uživatelům zprovoznit modely strojového učení pomocí PREDICT škálovatelné funkce. Tato funkce podporuje dávkové bodování (nebo dávkové odvozování) v jakémkoli výpočetním modulu. Dávkové předpovědi můžete vytvořit přímo z notebooku nebo ze stránky položky týkající se konkrétního modelu. Další informace o PREDICT a jeho použití v Microsoft Fabric najdete v tématu bodování modelu strojového učení pomocí PREDICT v Microsoft Fabric.

Z předchozích výsledků vyhodnocení má model 1 největší metriky pro oblast pod křivkou Precision-Recall (AUPRC) a pro oblast pod provozní charakteristikou přijímače křivky (AUC-ROC). Proto byste k predikci měli použít model 1.

Míra AUC-ROC se běžně používá k měření výkonu binárních klasifikátorů. Někdy je ale vhodnější klasifikátor vyhodnotit na základě měření AUPRC. Graf AUC-ROC vizualizuje kompromis mezi skutečnou kladnou mírou (TPR) a falešně pozitivní mírou (FPR). Křivka AUPRC kombinuje přesnost (pozitivní prediktivní hodnota nebo PPV) a úplnost (senzitivita nebo TPR) v jedné vizualizaci.

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