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
Získejte předplatné Microsoft Fabric. Nebo si zaregistrujte bezplatnou zkušební verzi Microsoft Fabricu.
Přihlaste se k Microsoft Fabric.
Pomocí přepínače prostředí na levé straně domovské stránky přepněte na prostředí Synapse Datová Věda.
- Pokud nemáte Microsoft Fabric Lakehouse, vytvořte ho podle pokynů v tématu Vytvoření jezera v Microsoft Fabric.
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:
Přejděte na domovskou stránku Synapse Datová Věda.
Vyberte Použít ukázku.
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 .
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.
Důležité
Před spuštěním poznámkového bloku přidejte do poznámkového bloku lakehouse . 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é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ů:
- Výběr pracovního prostoru v levém navigačním panelu
- Vyhledání a výběr názvu experimentu – v tomto případě sample_aisample-textclassification
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.")