Zelfstudie: Een model voor tekstclassificatie maken, evalueren en beoordelen
Deze zelfstudie bevat een end-to-end voorbeeld van een Synapse Data Science-werkstroom voor een model voor tekstclassificatie in Microsoft Fabric. In het scenario wordt gebruikgemaakt van word2vec en logistieke regressie, op Spark, om het genre van een boek uit de gegevensset van het British Library-boek te bepalen, uitsluitend op basis van de titel van het boek.
In deze zelfstudie worden de volgende stappen behandeld:
- Aangepaste bibliotheken installeren
- De gegevens laden
- De gegevens begrijpen en verwerken met experimentele gegevensanalyse
- Een machine learning-model trainen met word2vec en logistieke regressie, en experimenten bijhouden met MLflow en de autologgingfunctie van Fabric.
- Het machine learning-model laden voor scoren en voorspellingen
Voorwaarden
Een Microsoft Fabric-abonnementophalen. Of meld u aan voor een gratis microsoft Fabric-proefversie.
Meld u aan bij Microsoft Fabric-.
Gebruik de ervaringswisselaar aan de linkerkant van de startpagina om over te schakelen naar Fabric.
- Als u geen Microsoft Fabric Lakehouse hebt, maakt u er een door de stappen te volgen in Een lakehouse maken in Microsoft Fabric.
Volg mee in een notitieblok
U kunt een van deze opties kiezen om mee te doen in een notitieblok:
- Open en voer het ingebouwde notebook uit.
- Upload uw notebook vanuit GitHub.
Het ingebouwde notebook openen
Het voorbeeld genreclassificatie voor titels notitieboekje begeleidt deze tutorial.
Als u het voorbeeldnotitieblok voor deze zelfstudie wilt openen, volgt u de instructies in Uw systeem voorbereiden op zelfstudies voor gegevenswetenschap.
Zorg ervoor dat u een lakehouse koppelt aan het notebook voordat u begint met het uitvoeren van code.
Het notebook importeren vanuit GitHub
AIsample - Title Genre Classification.ipynb is het notitieboek dat bij deze handleiding hoort.
Als u het bijbehorende notitieblok voor deze zelfstudie wilt openen, volgt u de instructies in Uw systeem voorbereiden op zelfstudies voor gegevenswetenschap om het notebook in uw werkruimte te importeren.
Als u liever de code van deze pagina kopieert en plakt, kunt u een nieuw notitieblok maken.
Zorg ervoor dat een lakehouse aan het notebook koppelen voordat u begint met het uitvoeren van code.
Stap 1: Aangepaste bibliotheken installeren
Voor het ontwikkelen van machine learning-modellen of ad-hocgegevensanalyse moet u mogelijk snel een aangepaste bibliotheek voor uw Apache Spark-sessie installeren. U hebt twee opties om bibliotheken te installeren.
- Gebruik de inline-installatiemogelijkheden (
%pip
of%conda
) van uw notitieblok om alleen een bibliotheek in uw huidige notitieblok te installeren. - U kunt ook een Fabric-omgeving maken, bibliotheken installeren uit openbare bronnen of aangepaste bibliotheken ernaar uploaden. Vervolgens kan uw werkruimtebeheerder de omgeving als standaard voor de werkruimte koppelen. Alle bibliotheken in de omgeving zijn vervolgens beschikbaar voor gebruik in notebooks en Spark-taakdefinities in de werkruimte. Zie een omgeving maken, configureren en gebruiken in Microsoft Fabricvoor meer informatie over omgevingen.
Gebruik voor het classificatiemodel de wordcloud
-bibliotheek om de woordfrequentie in tekst weer te geven, waarbij de grootte van een woord de frequentie aangeeft. Voor deze zelfstudie gebruikt u %pip install
om wordcloud
in uw notebook te installeren.
Notitie
De PySpark-kernel wordt opnieuw opgestart nadat %pip install
wordt uitgevoerd. Installeer de benodigde bibliotheken voordat u andere cellen uitvoert.
# Install wordcloud for text visualization by using pip
%pip install wordcloud
Stap 2: de gegevens laden
De gegevensset bevat metagegevens over boeken uit de British Library die een samenwerking tussen de bibliotheek en Microsoft gedigitaliseerd heeft. De metagegevens zijn classificatie-informatie om aan te geven of een boek fictie of niet-fictie is. Met deze gegevensset is het doel om een classificatiemodel te trainen dat het genre van een boek bepaalt, alleen op basis van de titel ervan.
BL-record-ID | Type van resource | Naam | Datums die zijn gekoppeld aan de naam | Soort naam | Rol | Alle namen | Titel | Variant titels | Titel van reeks | Getal binnen reeks | Land van publicatie | Plaats van publicatie | Uitgever | Datum van publicatie | Uitgave | Fysieke beschrijving | Dewey-classificatie | BL plaatsaanduiding | Onderwerpen | Genre | Talen | Notities | BL-identificatie voor fysieke bron | classificatie_id | user_id | aangemaakt_op | subject_ids | annotator_datum_publicatie | annotator_normalised_date_pub | annotator_editieverklaring | annotator_genre | annotator_FAST_genre_termen | annotator_FAST_subject_terms | annotator_opmerkingen | annotator_main_language | samenvattingen_annotator_voor_andere_talen | annotator_summaries_language | annotator_vertaling | annotator_oorspronkelijke_taal | annotator_publisher | annotator_plaats_pub | annotator_country | annoteerderstitel | Koppeling naar gedigitaliseerd boek | Geannoteerde |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
014602826 | Monografie | Yearsley, Ann | 1753-1806 | persoon | Meer, Hannah, 1745-1833 [persoon]; Yearsley, Ann, 1753-1806 [persoon] | Gedichten bij verschillende gelegenheden [Met een inleidende brief van Hannah More.] | Engeland | Londen | 1786 | Vierde editie MANUSCRIPT-notitie | Digital Store 11644.d.32 | Engels | 003996603 | Vals | |||||||||||||||||||||||||||||||
014602830 | Monografie | A, T. | persoon | Oldham, John, 1653-1683 [persoon]; A, T. [persoon] | Een Satyr tegen Vertue. (Een gedicht: zou gesproken moeten worden door een Town-Hector [Door John Oldham. Het voorwoord ondertekend: T. A.]) | Engeland | Londen | 1679 | 15 pagina's (4°) | Digital Store 11602.ee.10. (2.) | Engels | 000001143 | Vals |
Definieer de volgende parameters, zodat u dit notebook op verschillende gegevenssets kunt toepassen:
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
De gegevensset downloaden en uploaden naar het lakehouse
Met deze code wordt een openbaar beschikbare versie van de gegevensset gedownload en vervolgens opgeslagen in een Fabric Lakehouse.
Belangrijk
Voeg een lakehouse toe aan het notebook voordat je het uitvoert. Als u dit niet doet, treedt er een fout op.
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.")
Vereiste bibliotheken importeren
Voordat u de verwerking verwerkt, moet u vereiste bibliotheken importeren, inclusief de bibliotheken voor Spark- en 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
Hyperparameters definiëren
Definieer enkele hyperparameters voor modeltraining.
Belangrijk
Pas deze hyperparameters alleen aan als u elke parameter begrijpt.
# 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
Begin met het opnemen van de tijd die nodig is om dit notebook uit te voeren:
# Record the notebook running time
import time
ts = time.time()
MLflow-experimenttracking instellen
Autologging breidt de mogelijkheden voor MLflow-logboekregistratie uit. Met automatisch registreren worden automatisch de invoerparameterwaarden en metrische uitvoergegevens van een machine learning-model vastgelegd terwijl u het traint. Vervolgens meldt u deze informatie aan bij de werkruimte. In de werkruimte kunt u de informatie openen en visualiseren met de MLflow-API's of het bijbehorende experiment in de werkruimte. Zie Autologging in Microsoft Fabricvoor meer informatie over automatisch aanmelden.
# Set up Mlflow for experiment tracking
mlflow.set_experiment(EXPERIMENT_NAME)
mlflow.autolog(disable=True) # Disable Mlflow autologging
Als u automatische aanmelding van Microsoft Fabric in een notebooksessie wilt uitschakelen, roept u mlflow.autolog()
aan en stelt u disable=True
in:
Onbewerkte datumgegevens uit lakehouse lezen
raw_df = spark.read.csv(f"{DATA_FOLDER}/raw/{DATA_FILE}", header=True, inferSchema=True)
Stap 3: Verkennende gegevensanalyse uitvoeren
Verken de gegevensset met de opdracht display
om statistieken op hoog niveau voor de gegevensset weer te geven en om de grafiekweergaven weer te geven:
display(raw_df.limit(20))
De gegevens voorbereiden
Verwijder de duplicaten om de gegevens op te schonen:
df = (
raw_df.select([TEXT_COL, LABEL_COL])
.where(F.col(LABEL_COL).isin(LABELS))
.dropDuplicates([TEXT_COL])
.cache()
)
display(df.limit(20))
Pas klasseverdeling toe om eventuele vooroordelen te verhelpen:
# 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))
Splits de alinea's en zinnen in kleinere eenheden om de gegevensset te tokeniseren. Op deze manier wordt het gemakkelijker om betekenis toe te wijzen. Verwijder vervolgens de stopwoorden om de prestaties te verbeteren. Stopword verwijderen omvat het verwijderen van woorden die vaak voorkomen in alle documenten in het corpus. Stopword verwijderen is een van de meest gebruikte voorverwerkingsstappen in NLP-toepassingen (Natural Language Processing).
# 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))
De wordcloud-bibliotheek voor elke klasse weergeven. Een wordcloud-bibliotheek is een visueel prominente presentatie van trefwoorden die regelmatig worden weergegeven in tekstgegevens. De wordcloud-bibliotheek is effectief omdat de weergave van trefwoorden een cloudachtige kleurenafbeelding vormt, om de belangrijkste tekstgegevens in één oogopslag vast te leggen. Meer informatie over wordcloud-.
# 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")
Gebruik ten slotte word2vec om de tekst te vectoriseren. De techniek word2vec maakt een vectorweergave van elk woord in de tekst. Woorden die in vergelijkbare contexten worden gebruikt, of die semantische relaties hebben, worden effectief vastgelegd door hun nabijheid in de vectorruimte. Deze nabijheid geeft aan dat vergelijkbare woorden vergelijkbare woordvectoren hebben.
# 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))
Stap 4: Het model trainen en evalueren
Definieer het model als de gegevens zijn ingesteld. In deze sectie traint u een logistiek regressiemodel om de gevectoriseerde tekst te classificeren.
Trainings- en testgegevenssets voorbereiden
# Split the dataset into training and testing
(train_df, test_df) = vec_df.randomSplit((0.8, 0.2), seed=42)
Machine Learning-experimenten bijhouden
Een machine learning-experiment is de primaire eenheid van de organisatie en controle voor alle gerelateerde machine learning-uitvoeringen. Een uitvoering komt overeen met één uitvoering van modelcode.
Het bijhouden van machine learning-experimenten beheert alle experimenten en hun onderdelen, zoals parameters, metrieke gegevens, modellen en andere artefacten. Bijhouden maakt het mogelijk om alle vereiste onderdelen van een specifiek machine learning-experiment te organiseren. Het maakt ook de eenvoudige reproductie van eerdere resultaten mogelijk met opgeslagen experimenten. Meer informatie over machine learning-experimenten in Microsoft Fabric.
# Build the logistic regression classifier
lr = (
LogisticRegression()
.setMaxIter(max_iter)
.setFeaturesCol("features")
.setLabelCol("labelIdx")
.setWeightCol("weight")
)
Hyperparameters afstemmen
Bouw een raster met parameters om te zoeken over de hyperparameters. Bouw vervolgens een estimator voor meerdere evaluatoren om een CrossValidator
model te produceren:
# 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,
)
Het model evalueren
We kunnen de modellen op de testgegevensset evalueren om ze te vergelijken. Een goed getraind model moet hoge prestaties tonen op de relevante meetcriteria wanneer het wordt toegepast op de validatie- en testsets.
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
Experimenten bijhouden met behulp van MLflow
Start het training- en evaluatieproces. Gebruik MLflow om alle experimenten bij te houden en parameters, metrische gegevens en modellen te registreren. Al deze informatie wordt vastgelegd onder de naam van het experiment in de werkruimte.
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,
}
)
Uw experimenten weergeven:
- Selecteer uw werkruimte in het linkernavigatievenster
- Zoek en selecteer de naam van het experiment. In dit geval sample_aisample-textclassification
Stap 5: Voorspellingsresultaten beoordelen en opslaan
Met Microsoft Fabric kunnen gebruikers machine learning-modellen operationeel maken met de PREDICT
schaalbare functie. Deze functie ondersteunt batchscore (of batchinferentie) in elke rekenkracht. U kunt batchvoorspellingen rechtstreeks vanuit een notebook of de itempagina voor een bepaald model maken. Zie Scoren van Machine Learning-modellen met PREDICT in Microsoft Fabricvoor meer informatie over PREDICT en het gebruik ervan in Fabric.
Uit de voorgaande evaluatieresultaten heeft model 1 de grootste metrische gegevens voor zowel Area Under the Precision-Recall Curve (AUPRC) als voor Area Under the Curve Receiver Operating Characteristic (AUC-ROC). Daarom moet u model 1 gebruiken voor voorspelling.
De AUC-ROC meting wordt veel gebruikt om de prestaties van binaire classificaties te meten. Het is echter soms beter om de classificatie te evalueren op basis van AUPRC-metingen. In de AUC-ROC grafiek wordt de afweging tussen de werkelijke positieve rente (TPR) en het fout-positieve percentage (FPR) gevisualiseerd. De AUPRC-curve combineert precisie (positieve voorspellende waarde of PPV) en herinnering (terugroepingspercentage of TPR) in één visualisatie.
# 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.")