Oktatóanyag: Szövegbesorolási modell létrehozása, kiértékelése és pontszáma

Ez az oktatóanyag a Synapse Adattudomány egy szövegbesorolási modellhez készült munkafolyamatának végpontok közötti példáját mutatja be a Microsoft Fabricben. A forgatókönyv a Sparkon a word2vec és logisztikai regresszió használatával határozza meg a British Library könyvadatkészletéből származó könyv műfaját, kizárólag a könyv címe alapján.

Ez az oktatóanyag az alábbi lépéseket ismerteti:

  • Egyéni kódtárak telepítése
  • Az adatok betöltése
  • Az adatok megismerése és feldolgozása feltáró adatelemzéssel
  • Gépi tanulási modell betanítása a Word2vec és a logisztikai regresszió használatával, valamint kísérletek nyomon követése az MLflow és a Fabric automatikus naplózási funkciójával
  • A gépi tanulási modell betöltése pontozáshoz és előrejelzésekhez

Előfeltételek

  • Microsoft Fabric-előfizetés lekérése. Vagy regisztráljon egy ingyenes Microsoft Fabric-próbaverzióra.

  • Jelentkezzen be a Microsoft Fabricbe.

  • A kezdőlap bal oldalán található élménykapcsolóval válthat a Synapse Adattudomány felületre.

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

Követés jegyzetfüzetben

A jegyzetfüzetben az alábbi lehetőségek közül választhat:

  • Nyissa meg és futtassa a beépített jegyzetfüzetet a Synapse Adattudomány felületen
  • Jegyzetfüzet feltöltése a GitHubról a Synapse Adattudomány felületére

A beépített jegyzetfüzet megnyitása

Ez az oktatóanyag a cím műfaji besorolási jegyzetfüzetének mintafüzete.

Az oktatóanyag beépített mintajegyzetfüzetének megnyitása a Synapse Adattudomány felületén:

  1. Nyissa meg a Synapse Adattudomány kezdőlapját.

  2. Válassza a Minta használata lehetőséget.

  3. Válassza ki a megfelelő mintát:

    • Ha a minta Python-oktatóanyaghoz készült, az alapértelmezett Végpontok közötti munkafolyamatok (Python) lapon.
    • A végpontok közötti munkafolyamatok (R) lapról, ha a minta R-oktatóanyaghoz készült.
    • A Gyors oktatóanyagok lapon, ha a minta egy gyors oktatóanyaghoz készült.
  4. A kód futtatása előtt csatoljon egy lakehouse-t a jegyzetfüzethez .

A jegyzetfüzet importálása a GitHubról

AIsample – Title Genre Classification.ipynb az oktatóanyagot kísérő jegyzetfüzet.

Az oktatóanyaghoz mellékelt jegyzetfüzet megnyitásához kövesse a Rendszer előkészítése adatelemzési oktatóanyagokhoz című témakör utasításait, és importálja a jegyzetfüzetet a munkaterületre.

Ha inkább erről a lapról másolja és illessze be a kódot, létrehozhat egy új jegyzetfüzetet.

A kód futtatása előtt mindenképpen csatoljon egy lakehouse-t a jegyzetfüzethez .

1. lépés: Egyéni kódtárak telepítése

A gépi tanulási modell fejlesztéséhez vagy az alkalmi adatelemzéshez előfordulhat, hogy gyorsan telepítenie kell egy egyéni kódtárat az Apache Spark-munkamenethez. A kódtárak telepítéséhez két lehetőség közül választhat.

  • A jegyzetfüzet beágyazott telepítési képességeivel (%pip vagy %conda) csak az aktuális jegyzetfüzetben telepíthet tárat.
  • Másik lehetőségként létrehozhat egy Fabric-környezetet, telepíthet nyilvános forrásokból származó kódtárakat, vagy feltölthet hozzá egyéni kódtárakat, majd a munkaterület rendszergazdája alapértelmezettként csatolhatja a környezetet a munkaterülethez. Ezután a környezet összes kódtára elérhetővé válik a munkaterület bármely jegyzetfüzetében és Spark-feladatdefiníciójában. A környezetekkel kapcsolatos további információkért tekintse meg a Környezetek létrehozását, konfigurálását és használatát a Microsoft Fabricben.

A besorolási modell esetében a wordcloud kódtár használatával jelölheti a szavak gyakoriságát a szövegben, ahol egy szó mérete a gyakoriságát jelöli. Ebben az oktatóanyagban a jegyzetfüzetben való telepítésre wordcloud használható%pip install.

Feljegyzés

A PySpark-kernel futás után %pip install újraindul. Telepítse a szükséges kódtárakat, mielőtt bármilyen más cellát futtatna.

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

2. lépés: Az adatok betöltése

Az adatkészlet metaadatait a British Library könyveiről, amelyeket a könyvtár és a Microsoft digitalizált. A metaadatok besorolási információk, amely azt jelzi, hogy egy könyv fikció vagy nem fikció. Ezzel az adatkészlettel a cél egy olyan besorolási modell betanítása, amely csak a címe alapján határozza meg a könyv műfaját.

BL-rekord azonosítója Erőforrás típusa Név Névvel társított dátumok Név típusa Szerepkör Minden név Cím Változatcímek Sorozat címe Sorozaton belüli szám A közzététel országa A közzététel helye Kiadó A közzététel dátuma Kiadás Fizikai leírás Dewey-besorolás BL-polcjel Témakörök Műfaj Nyelvek Jegyzetek A fizikai erőforrás BL-rekordazonosítója 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 Hivatkozás digitalizált könyvre széljegyzetes
014602826 Monográfia Yearsley, Ann 1753-1806 személy Egyebek, Hannah, 1745-1833 [személy]; Yearsley, Ann, 1753-1806 [személy] Versek több alkalommal [Az előkészületi levél Hannah More.] Anglia London 1786 Negyedik kiadású MANUSCRIPT jegyzet Digital Store 11644.d.32 Angol 003996603 Hamis
014602830 Monográfia A, T. személy Oldham, John, 1653-1683 [személy]; A, T. [személy] Egy Satyr Vertue ellen. (Egy vers: állítólag egy Town-Hector [John Oldham. Az előszó aláírta: T. A.]) Anglia London 1679 15 oldal (4°) Digital Store 11602.ee.10. (2.) Angol 000001143 Hamis

Adja meg a következő paramétereket, hogy ezt a jegyzetfüzetet különböző adathalmazokra alkalmazza:

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

Töltse le az adathalmazt, és töltse fel a lakehouse-ba

Ez a kód letölti az adathalmaz nyilvánosan elérhető verzióját, majd egy Fabric lakehouse-ban tárolja.

Fontos

A futtatás előtt vegyen fel egy lakehouse-t a jegyzetfüzetbe. Ennek elmulasztása hibát fog eredményezni.

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

Szükséges kódtárak importálása

A feldolgozás előtt importálnia kell a szükséges kódtárakat, beleértve a Spark és a SynapseML kódtárait is:

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

Hiperparaméterek definiálása

Definiáljon néhány hiperparamétert a modell betanításához.

Fontos

Ezeket a hiperparamétereket csak akkor módosítsa, ha ismeri az egyes paramétereket.

# 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

Kezdje el rögzíteni a jegyzetfüzet futtatásához szükséges időt:

# Record the notebook running time
import time

ts = time.time()

MLflow-kísérletkövetés beállítása

Az automatikus naplózás kibővíti az MLflow naplózási képességeit. Az automatikus betanítás automatikusan rögzíti a gépi tanulási modell bemeneti paraméterértékeit és kimeneti metrikáit a betanítás során. Ezután naplózza ezeket az adatokat a munkaterületen. A munkaterületen az MLflow API-kkal vagy a megfelelő kísérlettel érheti el és jelenítheti meg az információkat a munkaterületen. Az automatikus kereséssel kapcsolatos további információkért tekintse meg az Automatikus keresés a Microsoft Fabricben című témakört.

# Set up Mlflow for experiment tracking

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

Ha le szeretné tiltani a Microsoft Fabric automatikus használatát egy jegyzetfüzet-munkamenetben, hívja meg mlflow.autolog() és állítsa be a következőt disable=True:

Nyers dátumadatok olvasása a lakehouse-ból

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

3. lépés: Feltáró adatelemzés végrehajtása

Az adathalmazt a display paranccsal ismerheti meg, megtekintheti az adathalmaz magas szintű statisztikáit, és megjelenítheti a diagramnézeteket:

display(raw_df.limit(20))

Az adatok előkészítése

Távolítsa el az ismétlődéseket az adatok törléséhez:

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

display(df.limit(20))

Osztályelosztás alkalmazása az esetleges torzítás kezelésére:

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

Ossza fel a bekezdéseket és a mondatokat kisebb egységekre az adathalmaz tokenizálásához. Így könnyebben hozzárendelhető a jelentés. Ezután távolítsa el a stopwords a teljesítmény javítása érdekében. A stopword eltávolítása magában foglalja a korpusz összes dokumentumában gyakran előforduló szavak eltávolítását. A stopword eltávolítása az egyik leggyakrabban használt előfeldolgozási lépés a természetes nyelvi feldolgozás (NLP) alkalmazásokban.

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

Az egyes osztályok wordcloud-kódtárának megjelenítése. A wordcloud-kódtár a szöveges adatokban gyakran megjelenő kulcsszavak vizuálisan kiemelt megjelenítése. A WordCloud-kódtár azért hatékony, mert a kulcsszavak renderelése felhőszerű színes képet alkot, hogy jobban rögzítse a fő szöveges adatokat egy pillantással. További információ a wordcloudról.

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

Végül a word2vec használatával vektorizálja a szöveget. A word2vec technika vektoros ábrázolásokat hoz létre a szövegben lévő egyes szavakról. A hasonló kontextusokban használt vagy szemantikai kapcsolatokkal rendelkező szavakat a vektortérben való közelségükkel hatékonyan rögzítik. Ez a közelség azt jelzi, hogy a hasonló szavak hasonló szóvektorokkal rendelkeznek.

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

4. lépés: A modell betanítása és kiértékelése

Ha az adatok a helyén adhatók meg, határozza meg a modellt. Ebben a szakaszban egy logisztikai regressziós modellt tanít be a vektorizált szöveg besorolásához.

Adathalmazok betanítása és tesztelése

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

Gépi tanulási kísérletek nyomon követése

A gépi tanulási kísérlet az összes kapcsolódó gépi tanulási futtatás szervezetének és vezérlésének elsődleges egysége. A futtatás a modellkód egyetlen végrehajtásának felel meg.

A gépi tanulási kísérletkövetés kezeli az összes kísérletet és azok összetevőit, például paramétereket, metrikákat, modelleket és egyéb összetevőket. A nyomon követés lehetővé teszi egy adott gépi tanulási kísérlet összes szükséges összetevőjének rendszerezését. Emellett lehetővé teszi a múltbeli eredmények egyszerű reprodukálását mentett kísérletekkel. További információ a Microsoft Fabric gépi tanulási kísérleteiről.

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

Hiperparaméterek hangolása

Hozzon létre egy paraméterrácsot a hiperparaméterek kereséséhez. Ezután hozzon létre egy kereszt-kiértékelő becslést egy modell létrehozásához 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,
)

A modell értékelése

Kiértékelhetjük a tesztadatkészlet modelljeit, hogy összehasonlíthassuk őket. Egy jól betanított modellnek nagy teljesítményt kell mutatnia a megfelelő metrikákon, amikor az érvényesítési és tesztelési adatkészleteken fut.

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

Kísérletek nyomon követése az MLflow használatával

Indítsa el a betanítási és kiértékelési folyamatot. Az MLflow használatával nyomon követheti az összes kísérletet, valamint naplóparamétereket, metrikákat és modelleket. Ezt az információt a rendszer a munkaterület kísérletneve alatt naplózza.

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

A kísérletek megtekintése:

  1. A munkaterület kiválasztása a bal oldali navigációs sávon
  2. Keresse meg és válassza ki a kísérlet nevét – ebben az esetben sample_aisample-textclassification

Screenshot of an experiment.

5. lépés: Előrejelzési eredmények pontszáma és mentése

A Microsoft Fabric lehetővé teszi a felhasználók számára a gépi tanulási modellek skálázható funkcióval történő PREDICT üzembe helyezéset. Ez a függvény támogatja a kötegelt pontozást (vagy kötegelt következtetést) bármely számítási motorban. Kötegelt előrejelzéseket közvetlenül egy jegyzetfüzetből vagy egy adott modell elemlapjáról hozhat létre. Ha többet szeretne megtudni a PREDICT-ről és annak a Fabricben való használatáról, olvassa el a Gépi tanulási modell pontozása a PREDICT használatával a Microsoft Fabricben című témakört.

Az előző kiértékelési eredmények közül az 1. modell rendelkezik a legnagyobb metrikákkal mind a Precision-Recall Curve (AUPRC) területhez, mind a görbevevő működési jellemzőjéhez (AUC-ROC) tartozó területhez. Ezért az előrejelzéshez az 1. modellt kell használnia.

Az AUC-ROC mértéket széles körben használják a bináris osztályozók teljesítményének mérésére. Néha azonban az AUPRC-mérések alapján célszerűbb kiértékelni az osztályozót. Az AUC-ROC diagram a valódi pozitív ráta (TPR) és a hamis pozitív ráta (FPR) közötti kompromisszumot jeleníti meg. Az AUPRC-görbe egyetlen vizualizációban egyesíti a pontosságot (pozitív prediktív érték vagy PPV) és a visszahívást (valódi pozitív arány vagy TPR).

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