Opplæring: Opprette, evaluere og få en tekstklassifiseringsmodell
Denne opplæringen presenterer et ende-til-ende-eksempel på en Synapse Data Science-arbeidsflyt for en tekstklassifiseringsmodell i Microsoft Fabric. Scenarioet bruker word2vec og logistisk regresjon, på Spark, til å bestemme sjangeren til en bok fra British Library bokdatasett, utelukkende basert på bokens tittel.
Denne opplæringen dekker disse trinnene:
- Installere egendefinerte biblioteker
- Laste inn dataene
- Forstå og behandle dataene med utforskende dataanalyse
- Kalibrer en maskinlæringsmodell med word2vec og logistisk regresjon, og spor eksperimenter etter med MLflow og fabric autologging-funksjonen
- Last inn maskinlæringsmodellen for poengsummer og prognoser
Forutsetninger
Få et Microsoft Fabric-abonnement. Eller registrer deg for en gratis Prøveversjon av Microsoft Fabric.
Logg på Microsoft Fabric.
Bruk opplevelsesbryteren nederst til venstre på hjemmesiden for å bytte til Fabric.
- Hvis du ikke har et Microsoft Fabric lakehouse, kan du opprette et ved å følge trinnene i Opprette et lakehouse i Microsoft Fabric.
Følg med i en notatblokk
Du kan velge ett av disse alternativene for å følge med i en notatblokk:
- Åpne og kjør den innebygde notatblokken.
- Last opp notatblokken fra GitHub.
Åpne den innebygde notatblokken
Eksemplet på tittelsjangerklassifisering notatblokk følger med denne opplæringen.
Hvis du vil åpne eksempelnotatblokken for denne opplæringen, følger du instruksjonene i Klargjør systemet for.
Pass på å feste et lakehouse til notatblokken før du begynner å kjøre kode.
Importere notatblokken fra GitHub
AIsample – Title Genre Classification.ipynb er notatblokken som følger med denne opplæringen.
Hvis du vil åpne den medfølgende notatblokken for denne opplæringen, følger du instruksjonene i Klargjøre systemet for opplæringer om datavitenskap importere notatblokken til arbeidsområdet.
Hvis du heller vil kopiere og lime inn koden fra denne siden, kan du opprette en ny notatblokk.
Pass på å feste et lakehouse til notatblokken før du begynner å kjøre kode.
Trinn 1: Installere egendefinerte biblioteker
For utvikling av maskinlæringsmodeller eller ad hoc-dataanalyse, må du kanskje raskt installere et egendefinert bibliotek for Apache Spark-økten. Du har to alternativer for å installere biblioteker.
- Bruk de innebygde installasjonsfunksjonene (
%pip
eller%conda
) i notatblokken til å installere et bibliotek, bare i gjeldende notatblokk. - Alternativt kan du opprette et stoffmiljø, installere biblioteker fra offentlige kilder eller laste opp egendefinerte biblioteker til det, og deretter kan administratoren for arbeidsområdet legge ved miljøet som standard for arbeidsområdet. Alle bibliotekene i miljøet blir da tilgjengelige for bruk i alle notatblokker og Spark-jobbdefinisjoner i arbeidsområdet. Hvis du vil ha mer informasjon om miljøer, kan du se opprette, konfigurere og bruke et miljø i Microsoft Fabric.
For klassifiseringsmodellen bruker du biblioteket wordcloud
til å representere ordfrekvensen i tekst, der størrelsen på et ord representerer hyppigheten. For denne opplæringen kan du bruke %pip install
til å installere wordcloud
i notatblokken.
Notat
PySpark-kjernen starter på nytt etter at %pip install
kjører. Installer de nødvendige bibliotekene før du kjører andre celler.
# Install wordcloud for text visualization by using pip
%pip install wordcloud
Trinn 2: Laste inn dataene
Datasettet har metadata om bøker fra British Library som et samarbeid mellom biblioteket og Microsoft digitalisert. Metadataene er klassifiseringsinformasjon som angir om en bok er fiksjon eller sakprosa. Med dette datasettet er målet å lære opp en klassifiseringsmodell som bestemmer sjangeren til en bok, bare basert på tittelen.
BL-post-ID | Type ressurs | Navn | Datoer knyttet til navn | Navnetype | Rolle | Alle navn | Tittel | Varianttitler | Serietittel | Tall i serien | Publiseringsland | Publiseringssted | Forlag | Publiseringsdato | Utgave | Fysisk beskrivelse | Dewey-klassifisering | BL-hyllemerke | Emner | Sjanger | Språk | Notater | BL-post-ID for fysisk ressurs | 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 | Kobling til digitalisert bok | Kommenterte |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
014602826 | Monografi | Yearsley, Ann | 1753-1806 | person | Mer, Hannah, 1745-1833 [person]; Yearsley, Ann, 1753-1806 [person] | Dikt ved flere anledninger [Med et prefatory brev av Hannah More.] | England | London | 1786 | Manuskriptnotat for fjerde utgave | Digital Store 11644.d.32 | Engelsk | 003996603 | Falsk | |||||||||||||||||||||||||||||||
014602830 | Monografi | A, T. | person | Oldham, John, 1653-1683 [person]; A, T. [person] | En Satyr mot Vertue. (Et dikt: ment å bli talt av en Town-Hector [Av John Oldham. Forordet signert: T. A.]) | England | London | 1679 | 15 sider (4°) | Digital Store 11602.ee.10. (2.) | Engelsk | 000001143 | Falsk |
Definer følgende parametere slik at du kan bruke denne notatblokken på forskjellige datasett:
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
Last ned datasettet og last opp til lakehouse
Denne koden laster ned en offentlig tilgjengelig versjon av datasettet, og lagrer den deretter i et Fabric Lakehouse.
Viktig
Legg til et lakehouse- i notatblokken før du kjører den. Hvis du ikke gjør dette, vil det føre til en feil.
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.")
Importer nødvendige biblioteker
Før en behandling må du importere nødvendige biblioteker, inkludert bibliotekene for Spark- og 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
Definer hyperparametere
Definer noen hyperparametere for modellopplæring.
Viktig
Endre disse hyperparameterne bare hvis du forstår hver parameter.
# 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
Start innspillingen av tiden som trengs for å kjøre denne notatblokken:
# Record the notebook running time
import time
ts = time.time()
Konfigurere sporing av MLflow-eksperimenter
Autologging utvider loggingsfunksjonene for MLflow. Autologging registrerer automatisk inndataparameterverdiene og utdatamålingene for en maskinlæringsmodell mens du lærer opp den. Deretter logger du denne informasjonen til arbeidsområdet. I arbeidsområdet kan du få tilgang til og visualisere informasjonen med MLflow-API-ene, eller det tilsvarende eksperimentet, i arbeidsområdet. Hvis du vil ha mer informasjon om autologging, kan du se Autologging i Microsoft Fabric.
# Set up Mlflow for experiment tracking
mlflow.set_experiment(EXPERIMENT_NAME)
mlflow.autolog(disable=True) # Disable Mlflow autologging
Hvis du vil deaktivere Automatisk tillogging av Microsoft Fabric i en notatblokkøkt, ringer du mlflow.autolog()
og angir disable=True
:
Les rå datodata fra lakehouse
raw_df = spark.read.csv(f"{DATA_FOLDER}/raw/{DATA_FILE}", header=True, inferSchema=True)
Trinn 3: Utfør utforskende dataanalyse
Utforsk datasettet med kommandoen display
, for å vise statistikk på høyt nivå for datasettet og vise diagramvisningene:
display(raw_df.limit(20))
Klargjøre dataene
Fjern duplikatene for å rense dataene:
df = (
raw_df.select([TEXT_COL, LABEL_COL])
.where(F.col(LABEL_COL).isin(LABELS))
.dropDuplicates([TEXT_COL])
.cache()
)
display(df.limit(20))
Bruk klassefordeling for å håndtere eventuelle skjevheter:
# 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))
Del avsnittene og setningene i mindre enheter for å tokenisere datasettet. På denne måten blir det enklere å tilordne mening. Deretter fjerner du stoppordene for å forbedre ytelsen. Fjerning av stoppord innebærer fjerning av ord som vanligvis forekommer på tvers av alle dokumenter i corpus. Fjerning av stoppord er et av de mest brukte forhåndsbearbeidede trinnene i NLP-programmer (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))
Vis wordcloud-biblioteket for hver klasse. Et wordcloud-bibliotek er en visuelt fremtredende presentasjon av nøkkelord som vises ofte i tekstdata. Wordcloud-biblioteket er effektivt fordi gjengivelsen av nøkkelord danner et skylignende fargebilde, for bedre å fange opp hovedtekstdataene med et øyekast. Finn ut mer om 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")
Til slutt kan du bruke word2vec til å vektorisere teksten. Word2vec-teknikken oppretter en vektorrepresentasjon av hvert ord i teksten. Ord som brukes i lignende sammenhenger, eller som har semantiske relasjoner, fanges effektivt gjennom nærheten i vektorområdet. Denne nærheten indikerer at lignende ord har lignende ordvektorer.
# 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))
Trinn 4: Kalibrer og evaluer modellen
Når dataene er på plass, definerer du modellen. I denne delen lærer du opp en logistisk regresjonsmodell for å klassifisere vektorisert tekst.
Klargjøre opplærings- og testdatasett
# Split the dataset into training and testing
(train_df, test_df) = vec_df.randomSplit((0.8, 0.2), seed=42)
Spore maskinlæringseksperimenter
Et maskinlæringseksperiment er den primære enheten for organisering og kontroll for alle relaterte maskinlæringskjøringer. En kjøring tilsvarer en enkelt kjøring av modellkode.
Sporing av maskinlæringseksperiment administrerer alle eksperimentene og komponentene deres, for eksempel parametere, måledata, modeller og andre artefakter. Sporing muliggjør organisering av alle nødvendige komponenter i et bestemt maskinlæringseksperiment. Det muliggjør også enkel reproduksjon av tidligere resultater med lagrede eksperimenter. Finn ut mer om maskinlæringseksperimenter i Microsoft Fabric.
# Build the logistic regression classifier
lr = (
LogisticRegression()
.setMaxIter(max_iter)
.setFeaturesCol("features")
.setLabelCol("labelIdx")
.setWeightCol("weight")
)
Justere hyperparametere
Bygg et rutenett med parametere for å søke over hyperparameterne. Deretter bygger du en kryss-evaluator estimator, for å produsere en CrossValidator
modell:
# 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,
)
Evaluer modellen
Vi kan evaluere modellene på testdatasettet for å sammenligne dem. En godt trent modell bør demonstrere høy ytelse, på de relevante måledataene, når den kjøres mot validerings- og testdatasettene.
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
Spor eksperimenter ved hjelp av MLflow
Start opplærings- og evalueringsprosessen. Bruk MLflow til å spore alle eksperimenter og loggparametere, måledata og modeller. All denne informasjonen logges under eksperimentnavnet i arbeidsområdet.
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,
}
)
Slik viser du eksperimentene dine:
- Velg arbeidsområdet i venstre navigasjonsrute
- Finn og velg eksperimentnavnet – i dette tilfellet sample_aisample-tekstklassifisering
Trinn 5: Resultat og lagre prognoseresultater
Microsoft Fabric gjør det mulig for brukere å operasjonalisere maskinlæringsmodeller med PREDICT
skalerbar funksjon. Denne funksjonen støtter satsvis poengsum (eller satsvis inferencing) i en hvilken som helst databehandlingsmotor. Du kan opprette satsvise prognoser direkte fra en notatblokk eller elementsiden for en bestemt modell. Hvis du vil lære mer om FORUTSI og hvordan du bruker den i Fabric, kan du se maskinlæringsmodell med PREDICT i Microsoft Fabric.
Fra de foregående evalueringsresultatene har modell 1 de største måledataene for både område under Precision-Recall kurve (AUPRC) og for område under kurvemottakerens driftsegenskaper (AUC-ROC). Derfor bør du bruke modell 1 for prognose.
Målet AUC-ROC er mye brukt til å måle binær klassifisererytelse. Noen ganger blir det imidlertid mer hensiktsmessig å evaluere klassifisereren basert på AUPRC-målinger. Diagrammet AUC-ROC visualiserer avveiningen mellom sann positiv rente (TPR) og usann positiv rente (FPR). AUPRC-kurven kombinerer presisjon (positiv prediktiv verdi eller PPV) og tilbakekalling (sann positiv hastighet eller TPR) i én enkelt visualisering.
# 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.")