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 Datová Věda pro 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í slov2vec a logistické regrese a sledování experimentů pomocí MLflow a funkce automatickéhologování prostředků infrastruktury
  • 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ření a spuštění integrovaného poznámkového bloku v prostředí Datová Věda Synapse
  • Nahrání poznámkového bloku z GitHubu do prostředí synapse Datová Věda

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

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

Otevření integrovaného ukázkového poznámkového bloku kurzu v prostředí Datová Věda Synapse:

  1. Přejděte na domovskou stránku Synapse Datová Věda.

  2. Vyberte Použít ukázku.

  3. Vyberte odpovídající ukázku:

    • Pokud je ukázka pro kurz Pythonu, na výchozí kartě Kompletní pracovní postupy (Python ).
    • Pokud je ukázka kurzu jazyka R, na kartě Kompletní pracovní postupy (R).
    • Pokud je ukázka pro rychlý kurz, na kartě Rychlé kurzy .
  4. Než začnete spouštět kód, připojte k poznámkovému bloku lakehouse.

Import poznámkového bloku z GitHubu

AIsample - Title Žánr Classification.ipynb je poznámkový blok, který doprovází tento kurz.

Pokud chcete otevřít doprovodný poznámkový blok pro tento kurz, postupujte podle pokynů v části Příprava systému na kurzy datových věd a importujte poznámkový blok do pracovního prostoru.

Pokud byste raději zkopírovali a vložili kód z této stránky, můžete vytvořit nový poznámkový blok.

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

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í vložené instalace (%pip nebo %conda) poznámkového bloku nainstalujte knihovnu jenom v aktuálním poznámkovém bloku.
  • Alternativně můžete vytvořit prostředí Infrastruktury, nainstalovat knihovny z veřejných zdrojů nebo do něj nahrát vlastní knihovny a správce pracovního prostoru pak může prostředí připojit 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 wordcloud knihovnu k reprezentaci četnosti slov v textu, kde velikost slova představuje jeho frekvenci. Pro účely tohoto kurzu použijte %pip install instalaci wordcloud do poznámkového bloku.

Poznámka:

Po spuštění se jádro PySpark restartuje %pip install . 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é spolupracují mezi knihovnou a digitalizovaným Microsoftem. 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 zdroje Název Data přidružená k názvu Typ názvu Role Všechna jména Nadpis Názvy variant Název řady Číslo v řadě Země publikování Místo publikování Publisher Datum zveřejnění Vydání Fyzický popis Klasifikace Dewey Značka police BL Témata Genre Jazyky Notes ID záznamu BL pro fyzický prostředek 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 Odkaz na digitalizovanou knihu S poznámkami
014602826 Monografie Yearsley, Ann 1753-1806 person More, Hannah, 1745-1833 [person]; Yearsley, Ann, 1753-1806 [person] Básně na několika příležitostech [S prefatorním dopisem Hannah More.] Anglie Londýn 1786 Čtvrtá edice POZNÁMKY NA RUKOPIS Digital Store 11644.d.32 Angličtina 003996603 False
014602830 Monografie A, T. person Oldham, John, 1653-1683 [person]; A, T. [osoba] Satyr proti Vertue. (Báseň: měla být mluvená město-Hector [John Oldham. Předmluva podepsaná: T. A.]) Anglie Londýn 1679 15 stran (4°) Digital Store 11602.ee.10. (2.) Angličtina 000001143 False

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.

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ém přihlašová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

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

Čtení nezpracovaných dat kalendářních dat z 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í display příkazu, abyste zobrazili statistiky vysoké úrovně datové sady a zobrazili zobrazení grafu:

display(raw_df.limit(20))

Příprava dat

Odeberte duplicity, abyste data vyčistili:

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

display(df.limit(20))

Použití vyrovnávání tříd k vyřešení jakýchkoli předsudků:

# 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 stopwords, aby se zlepšil výkon. 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. Přečtěte si další informace o wordcloudu.

# 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 sémantických relací 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 na místě 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 řízením 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ů. Přečtěte si 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ů. Pak vytvořte estimátor křížového vyhodnocení, který vytvoří 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,
)

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

Zobrazení experimentů:

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

Screenshot of an experiment.

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 PREDICT učení pomocí š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 poznámkového bloku nebo stránky položky pro konkrétní model. Další informace o funkci PREDICT a jejím použití v Prostředcích infrastruktury najdete v tématu Bodování modelu strojového učení pomocí funkce PREDICT v Microsoft Fabric.

Z předchozích výsledků vyhodnocení má model 1 největší metriky pro oblast pod křivkou přesnosti (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í sazbou (FPR). Křivka AUPRC kombinuje přesnost (kladné prediktivní hodnoty nebo PPV) a úplnost (pravdivá kladná rychlost 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.")