Projekte für maschinelles Lernen sind iterative Prozesse. Sie halten nicht nur in einem erfolgreichen Modell in einem Jupyter -Notebook an. Sie hören nicht einmal auf, nachdem das Modell online ist, und die Leute können darauf zugreifen. Auch nach dem Einsatz müssen Sie es ständig so gut babysitten, dass es genauso gut funktioniert wie in der Entwicklungsphase.
Zillows Skandal ist ein perfektes Beispiel dafür, was passiert, wenn Sie dies nicht tun. Im Jahr 2021 verlor Zillow aufgrund ihres maschinellen Lernenmodells, das die Immobilienpreise schätzten, beeindruckende 304 Millionen Dollar. Zillow überbezahlt für mehr als 7000 Häuser und musste sie zu einem viel günstigeren Preis abladen. Das Unternehmen wurde von seinem eigenen Modell „abgerissen“ und musste seine Belegschaft um 25%reduzieren.
Diese Arten von stillen Modellfehlern sind bei realen Modellen gemeinsam, daher müssen sie ständig aktualisiert werden, bevor ihre Produktionsleistung sinkt. Dies schadet den Ruf der Unternehmen, das Vertrauen mit den Stakeholdern und letztendlich ihre Taschen.
.In diesem Artikel werden Sie vermittelt, wie Sie einen End-to-End-Workflow zur Überwachung von maschinellem Lernmodellen nach der Bereitstellung mit Nannyml implementieren.
Wir werden die technischen Teile dieser Funktionen einzeln lernen.
Wir werden die grundlegenden Konzepte der Modellüberwachung durch die Analogie eines Roboter -Mastering -Bogenschießens lernen.
in unserer Analogie:
Also starten wir.
Stellen Sie sich vor, wir haben den Bogen, die Pfeile und das Ziel sorgfältig vorbereitet (wie die Datenvorbereitung). Unser Roboter, ausgestattet mit vielen Sensoren und Kameras, schießt während des Trainings 10000 Mal. Im Laufe der Zeit beginnt es mit beeindruckender Frequenz auf das Auge des Stiers zu treffen. Wir sind begeistert von der Leistung und beginnen mit dem Verkauf unseres Roboters und seinen Kopien an Bogenschießenliebhaber (das Modell bereitzustellen).
Aber bald bekommen wir einen Strom von Beschwerden. Einige Benutzer berichten, dass dem Roboter das Ziel völlig fehlt. Überrascht, wir sammeln ein Team, um zu besprechen, was schief gelaufen ist.
Was wir finden, ist ein klassischer Fall von Datendrift . Die Umgebung, in der die Roboter arbeiten
Diese reale Verschiebung der Eingabefunktionen hat die Genauigkeit unseres Roboters abgeworfen, ähnlich wie ein maschinelles Lernmodell unterdurchschnittlich bei Eingabedaten, insbesondere der Beziehung zwischen Merkmalen, ändert sich im Laufe der Zeit.Konzept Drift
Diese neuen Ziele variieren in der Größe und werden in unterschiedlichen Entfernungen platziert. Diese Änderung erfordert einen anderen Ansatz für die Schießtechnik des Roboters - ein Lehrbuchbeispiel für
Konzept Drift .
In maschinellem Lernen tritt die Konzeptdrift auf, wenn sich die Beziehung zwischen den Eingabevariablen und dem Zielergebnis ändert. Für unsere Roboter mussten die neuen Arten von Zielen nun an das Aufnehmen anpassen, so wie sich ein maschinelles Lernenmodell anpassen muss, wenn sich die Dynamik der Daten erheblich geschult wurde.mehr reale Beispiele für Konzept und Datendrift
Betrachten wir nun einen End-to-End-ML-Überwachungs-Workflow.
Modellüberwachung umfasst drei Hauptschritte, denen ML -Ingenieure iterativ folgen sollten.
Der erste Schritt besteht natürlich darin, die Modellleistung in der Bereitstellung genau im Auge zu behalten. Aber das ist leichter gesagt als getan.
Wenn für ein Modell in der Produktion sofort Grundwahrheit verfügbar ist, ist es einfach, Änderungen des Modellverhaltens zu erkennen. Zum Beispiel können die Benutzer sofort sagen, was in unserer Analogie für Roboter/Bogenschießen falsch ist
Nehmen Sie dagegen das Beispiel eines Modells, das Kreditausfälle vorhersagt. Solche Modelle sagen voraus, ob ein Benutzer bei der nächsten Zahlung oder nicht jeden Monat ausfällt. Um die Vorhersage zu überprüfen, muss das Modell bis zum tatsächlichen Zahlungsdatum warten. Dies ist ein Beispiel für verzögerte Grundwahrheit , was in realer maschineller Lernsysteme am häufigsten vorkommt.
In solchen Fällen ist es zu kostspielig, um zu warten, bis die Grundwahrheit verfügbar ist, um festzustellen, ob Modelle gut abschneiden. ML -Ingenieure benötigen also Methoden, um die Modellleistung ohne sie zu schätzen. Hier kommen Algorithmen wie CBPE oder DLE ins Spiel (mehr später).
Überwachungsmodelle können auch durch Messung der direkten geschäftlichen Auswirkung durchgeführt werden, d. H. Die Überwachung von KPIs (wichtige Leistungsindikatoren). In Zillows Fall hätte ein ordnungsgemäßes Überwachungssystem den Gewinnverlust erkennen und die Ingenieure (hypothetisch) alarmiert haben.
Wenn das Überwachungssystem einen Leistungsabfall erkennt, unabhängig davon, ob das System die realisierte Leistung (mit Bodenwahrheit) oder die geschätzte Leistung (ohne Grundwahrheit) analysiert hat, müssen ML -Ingenieure die Ursache hinter dem Abfall identifizieren.
Dies beinhaltet normalerweise die Überprüfung von Funktionen einzeln oder in Kombination für Daten (Feature -Drift) und die Untersuchung der Ziele für die Konzeptdrift.
Basierend auf ihren Erkenntnissen verwenden sie verschiedene Problemauflösungstechniken.
Hier finden Sie eine nicht exklusive Liste von Techniken, um die Schäden zu verringern,
Nannyml befasst sich mit den ersten beiden Schritten dieses iterativen Prozesses. Also lasst uns darauf ankommen.
Schritt 1: Vorbereitung der Daten für Nannyml
Erstens benötigen wir ein Modell, das bereits geschult und bereit ist, um in die Produktion eingesetzt zu werden, damit wir es überwachen können. Zu diesem Zweck verwenden wir den Diamonds -Datensatz und trainieren einen Xgboost -Regressor.
Daten laden, Features definieren und zielen
import warnings import matplotlib.pyplot as plt import numpy as np import pandas as pd import seaborn as sns import xgboost as xgb from sklearn.model_selection import train_test_split from sklearn.preprocessing import OneHotEncoder warnings.filterwarnings("ignore")
dataset_link = "https://raw.githubusercontent.com/BexTuychiev/medium_stories/master/2024/1_january/4_intro_to_nannyml/diamonds_special.csv" diamonds_special = pd.read_csv(dataset_link) diamonds_special.head()
Diese spezielle Version des Datensatzes hat eine Spalte mit dem Namen "Set", die wir in einer Sekunde erhalten.
Im Moment extrahieren wir alle Feature -Namen, die kategorialen Feature -Namen und den Zielnamen:
import warnings import matplotlib.pyplot as plt import numpy as np import pandas as pd import seaborn as sns import xgboost as xgb from sklearn.model_selection import train_test_split from sklearn.preprocessing import OneHotEncoder warnings.filterwarnings("ignore")
Die Aufgabe ist eine Regression - wir werden die Diamantpreise angesichts ihrer physischen Attribute vorhersagen.
Der Diamonds -Datensatz ist ziemlich sauber. Die einzige Vorverarbeitung, die wir durchführen, besteht darin, die Textfunktionen in den Datentyp der Kategorie von Pandas zu übertragen. Dies ist eine Voraussetzung, um die automatische kategoriale Datenvorverarbeitung durch Xgboost zu aktivieren.
dataset_link = "https://raw.githubusercontent.com/BexTuychiev/medium_stories/master/2024/1_january/4_intro_to_nannyml/diamonds_special.csv" diamonds_special = pd.read_csv(dataset_link) diamonds_special.head()
Lassen Sie uns die Daten aufteilen.
Ja, Sie haben das richtig gelesen. Wir werden die Daten in vier Sätze aufteilen. Traditionell haben Sie es möglicherweise nur in drei aufgeteilt:
Workflows für Modellüberwachung erfordern einen weiteren Satz, um die Produktionsdaten nachzuahmen. Dies soll sicherstellen, dass unser System die Leistungsabfälle korrekt erkennt, indem die richtigen Algorithmen verwendet werden und berichtet, was schief gelaufen ist.
Zu diesem Zweck habe ich die Zeilen von Diamonds Special mit vier Kategorien in der Spalte festgelegt:
# Extract all feature names all_feature_names = diamonds_special.drop(["price", "set"], axis=1).columns.tolist() # Extract the columns and cast into category cats = diamonds_special.select_dtypes(exclude=np.number).columns # Define the target column target = "price"
Der Trainingssatz entspricht 70%, während der Rest jeweils 10% der Gesamtdaten ist. Lassen Sie es uns teilen:
for col in cats: diamonds_special[col] = diamonds_special[col].astype("category")
, aber reale Datensätze werden nicht mit integrierten Set-Labels geliefert, sodass Sie die Daten selbst manuell in vier Sätze aufteilen müssen. Hier ist eine Funktion, die die Aufgabe mit train_test_split von sklearn ausleitet:
diamonds_special.set.unique() ['train', 'val', 'test', 'prod'] Categories (4, object): ['prod', 'test', 'train', 'val']
Hinweis:
Verwenden Sie die Schaltfläche „Code erklären“, um eine zeilenweise Erläuterung der Funktion zu erhalten.Lassen Sie uns nun zum Modelltraining übergehen.
Vor dem Training eines XGBOOST -Modells müssen wir die Datensätze in DMatrices umwandeln. Hier ist der Code:
tr = diamonds_special[diamonds_special.set == "train"].drop("set", axis=1) val = diamonds_special[diamonds_special.set == "validation"].drop("set", axis=1) test = diamonds_special[diamonds_special.set == "test"].drop("set", axis=1) prod = diamonds_special[diamonds_special.set == "prod"].drop("set", axis=1) tr.shape (37758, 10)
Hier ist der Code, um einen Regressor mit bereits abgestimmten Hyperparametern zu trainieren:
def split_into_four(df, train_size=0.7): """ A function to split a dataset into four sets: - Training - Validation - Testing - Production train_size is set by the user. The remaining data will be equally divided between the three sets. """ # Do the splits training, the_rest = train_test_split(df, train_size=train_size) validation, the_rest = train_test_split(the_rest, train_size=1 / 3) testing, production = train_test_split(the_rest, train_size=0.5) # Reset the indices sets = (training, validation, testing, production) for set in sets: set.reset_index(inplace=True, drop=True) return sets tr, val, test, prod = split_into_four(your_dataset)
Großartig - Wir haben ein Modell, das 503 $ in Bezug auf RMSE im Validierungssatz erreicht. Bewerten wir das Modell ein letztes Mal im Testsatz:
dtrain = xgb.DMatrix(tr[all_feature_names], label=tr[target], enable_categorical=True) dval = xgb.DMatrix(val[all_feature_names], label=val[target], enable_categorical=True) dtest = xgb.DMatrix( test[all_feature_names], label=test[target], enable_categorical=True ) dprod = xgb.DMatrix( prod[all_feature_names], label=prod[target], enable_categorical=True )
Die Testleistung beträgt 551 $. Das ist gut genug.
Bis zu diesem Zeitpunkt war alles ziemlich einfach. Jetzt kommen wir zum Hauptteil - erstellen Sie Referenz- und Analyse -Sets.
Ein Referenzsatz ist ein anderer Name für den im Modellüberwachungskontext verwendeten Testsatz. Nannyml verwendet die Leistung des Modells im Testsatz als Grundlinie für die Produktionsleistung. Der Referenzsatz muss zwei Spalten von den Merkmalen haben:
Im Moment enthält unser Testsatz die Funktionen und das Ziel, fehlt jedoch y_test_pred:
import warnings import matplotlib.pyplot as plt import numpy as np import pandas as pd import seaborn as sns import xgboost as xgb from sklearn.model_selection import train_test_split from sklearn.preprocessing import OneHotEncoder warnings.filterwarnings("ignore")
Fügen wir es hinzu:
dataset_link = "https://raw.githubusercontent.com/BexTuychiev/medium_stories/master/2024/1_january/4_intro_to_nannyml/diamonds_special.csv" diamonds_special = pd.read_csv(dataset_link) diamonds_special.head()
Jetzt werden wir den Test in Referenz umbenennen:
# Extract all feature names all_feature_names = diamonds_special.drop(["price", "set"], axis=1).columns.tolist() # Extract the columns and cast into category cats = diamonds_special.select_dtypes(exclude=np.number).columns # Define the target column target = "price"
Stellen wir uns zu diesem Zeitpunkt vor, dass unser Regressor in der Cloud eingesetzt wird. Die Vorstellung ist einfacher als die Bereitstellung des Modells, das für diesen Artikel übertrieben ist.
Nachdem wir unser Diamonds -Preismodell eingesetzt haben, erhalten wir die Nachricht, dass eine große Versand von Diamanten kommt. Bevor die Fracht eintrifft, wurden uns die physischen Messungen von Diamanten als Prod (wir stellen uns immer noch vor) gesendet, damit wir Preise für sie generieren und auf unserer Website vermarkten können. Lassen Sie uns also generieren.
for col in cats: diamonds_special[col] = diamonds_special[col].astype("category")
Bevor die tatsächlichen Diamanten ankommen und ein menschlicher Spezialist die von unserem Modell generierten Preise überprüft, müssen wir überprüfen, ob unser Modell gut abschneidet. Wir möchten die Diamanten nicht mit ungenauen Preisen auf unserer Website anzeigen.
Um dies zu tun, müssten wir die Leistung des Modells messen, indem wir y_prod_prise mit den tatsächlichen Preisen neuer Diamanten, der Grundwahrheit, vergleichen. Aber wir werden keine Grundwahrheit haben, bevor die Preise überprüft werden. Wir müssten also die Leistung des Modells ohne Grundwahrheit schätzen.
Um diese Aufgabe zu erledigen, benötigt Nannyml einen Analysesatz - die Daten, die die Produktionsdaten mit Vorhersagen des Modells enthalten.
Erstellen eines Analysesatzes ähnelt dem Erstellen einer Referenz:
diamonds_special.set.unique() ['train', 'val', 'test', 'prod'] Categories (4, object): ['prod', 'test', 'train', 'val']
Jetzt sind wir bereit, die Leistung des Regressors abzuschätzen.
nannyml liefert zwei Hauptalgorithmen zur Schätzung der Leistung von Regressions- und Klassifizierungsmodellen:
Wir werden den DLE -Algorithmus für unsere Aufgabe verwenden. DLE kann die Leistung eines Produktionsmodells ohne Grundwahrheit messen und verschiedene Regressions-Pseudo-Metrics wie RMSE, RMSLE, MAE usw. melden.
Um DLE zu verwenden, müssen wir zunächst in die Verweise eingehen, um eine Basisleistung zu ermitteln.
tr = diamonds_special[diamonds_special.set == "train"].drop("set", axis=1) val = diamonds_special[diamonds_special.set == "validation"].drop("set", axis=1) test = diamonds_special[diamonds_special.set == "test"].drop("set", axis=1) prod = diamonds_special[diamonds_special.set == "prod"].drop("set", axis=1) tr.shape (37758, 10)
Initialisieren von DLE benötigt drei Parameter - die Eingabefunktionsnamen, der Name der Spalte, die die Grundwahrheit für das Testen enthält, und den Namen der Spalte, die Testvorhersagen enthält.
Zusätzlich verabschieden wir RMSE als Metrik und Stücke von 250.
def split_into_four(df, train_size=0.7): """ A function to split a dataset into four sets: - Training - Validation - Testing - Production train_size is set by the user. The remaining data will be equally divided between the three sets. """ # Do the splits training, the_rest = train_test_split(df, train_size=train_size) validation, the_rest = train_test_split(the_rest, train_size=1 / 3) testing, production = train_test_split(the_rest, train_size=0.5) # Reset the indices sets = (training, validation, testing, production) for set in sets: set.reset_index(inplace=True, drop=True) return sets tr, val, test, prod = split_into_four(your_dataset)
import warnings import matplotlib.pyplot as plt import numpy as np import pandas as pd import seaborn as sns import xgboost as xgb from sklearn.model_selection import train_test_split from sklearn.preprocessing import OneHotEncoder warnings.filterwarnings("ignore")
interpretieren wir das Diagramm - es verfügt über zwei Abschnitte, in denen die Leistung in den Referenz- und Analyse -Sätzen angezeigt wird. Wenn die geschätzte Produktion RMSE über die Schwellenwerte hinausgeht, markiert Nannyml sie als Warnungen.
Wie wir sehen können, haben wir einige Warnungen für Produktionsdaten, was darauf hindeutet, dass in den letzten Chargen etwas Fischiges vor sich geht.
Unser Überwachungssystem zeigt uns, dass die Modellleistung in der Produktion um etwa die Hälfte gesunken ist. Aber es ist nur eine Schätzung - wir können es nicht sicher sagen.
Während wir die geschätzte Leistung planen, ist die Sendung eingetroffen und unser Diamantenspezialist berechnete ihren tatsächlichen Preis. Wir haben sie als Preis in Produkt gespeichert.
Jetzt können wir die realisierte Leistung (tatsächliche Leistung) des Modells mit der geschätzten Leistung vergleichen, um festzustellen, ob unser Überwachungssystem gut funktioniert.
Nannyml bietet dazu eine PerformanceCalculator -Klasse:
dataset_link = "https://raw.githubusercontent.com/BexTuychiev/medium_stories/master/2024/1_january/4_intro_to_nannyml/diamonds_special.csv" diamonds_special = pd.read_csv(dataset_link) diamonds_special.head()
Die Klasse erfordert vier Parameter:
Nachdem wir diese übergeben und den Taschenrechner an die Referenz angemessen haben, berechnen wir den Analysesatz.
Um realized_results mit geschätzten_Resulten zu vergleichen, verwenden wir erneut ein visuelles:
# Extract all feature names all_feature_names = diamonds_special.drop(["price", "set"], axis=1).columns.tolist() # Extract the columns and cast into category cats = diamonds_special.select_dtypes(exclude=np.number).columns # Define the target column target = "price"
Nun, es sieht so aus, als ob der geschätzte RMSE (lila) der tatsächlichen Leistung ziemlich nahe war (realisiert RMSE, Blau).
Dies sagt uns eines - unser Überwachungssystem funktioniert gut, aber unser Modell ist nicht, wie der steigende Verlust angezeigt. Also, was ist der Grund (s)?
wir werden jetzt in das eintauchen.
Wie im Intro erwähnt, ist einer der häufigsten Gründe, warum Modelle in der Produktion versagen, die Drift. In diesem Abschnitt konzentrieren wir uns auf die Datenerfassung von Daten (Feature).
Drifterkennung ist Teil des Schritts der Ursachenanalyse des Modellüberwachungs -Workflows. Es beginnt normalerweise mit einer multivariaten Drifterkennung.
Eine der besten multivariaten Drift -Erkennungsmethoden ist die Berechnung des Datenrekonstruktionsfehlers unter Verwendung von PCA. Es funktioniert bemerkenswert gut und kann sogar die geringsten Drifts in Feature -Verteilungen fangen. Hier ist ein hochrangiger Überblick über diese Methode:
1. PCA passt zur Referenz und komprimiert es auf eine niedrigere Dimension - Reference_lower.
2. Reference_lower wird dann in seine ursprüngliche Dimensionalität dekomprimiert - Referenz_Reconstruation.
3. Die Differenz zwischen Referenz und Referenz_Reconstruation wird gefunden und als Datenrekonstruktionsfehler - reconstruct_error genannt.
4. Die gleiche Reduktions-/Rekonstruktionsmethode wird auf Produktionsdaten angewendet.
Diese vier Schritte werden in Nannyml als DataArConstructionDiftCalcuLculator -Klasse implementiert. Hier erfahren Sie, wie Sie es verwenden:
import warnings import matplotlib.pyplot as plt import numpy as np import pandas as pd import seaborn as sns import xgboost as xgb from sklearn.model_selection import train_test_split from sklearn.preprocessing import OneHotEncoder warnings.filterwarnings("ignore")
Sobald wir den Fehler für jeden Datenblock haben (jeweils 250 Zeilen), können wir ihn zeichnen:
dataset_link = "https://raw.githubusercontent.com/BexTuychiev/medium_stories/master/2024/1_january/4_intro_to_nannyml/diamonds_special.csv" diamonds_special = pd.read_csv(dataset_link) diamonds_special.head()
Wie wir sehen können, ist der Rekonstruktionsfehler sehr hoch, was auf eine Drift der Merkmale hinweist. Wir können den Fehler auch mit der realisierten Leistung vergleichen:
# Extract all feature names all_feature_names = diamonds_special.drop(["price", "set"], axis=1).columns.tolist() # Extract the columns and cast into category cats = diamonds_special.select_dtypes(exclude=np.number).columns # Define the target column target = "price"
Wie wir sehen können, entsprechen alle Spikes im Verlust mit Warnungen im Rekonstruktionsfehler.
Datenrekonstruktionsfehler ist eine einzige Zahl, um die Drift für alle Funktionen zu messen. Aber wie wäre es mit der Drift einzelner Merkmale? Wenn unser Datensatz Hunderte von Funktionen enthält, wie würden wir dann die am meisten treibenden Funktionen finden und geeignete Maßnahmen ergreifen?
Hier verwenden wir univariate Drift -Erkennungsmethoden. Nannyml bietet mehrere je nach Funktionstyp:
All dies vergleichen die Verteilung einzelner Merkmale in Bezug auf die des Analysesatzes. Wir können einige (oder sogar alle) innerhalb der univariierten Riftcalculator -Klasse verwenden:
for col in cats: diamonds_special[col] = diamonds_special[col].astype("category")
Der einzige erforderliche Parameter ist column_names, der Rest kann von Nannyml eingestellt werden. Um die Dinge einfach zu halten, verwenden wir Wasserstein und Jensen_Shannon für kontinuierliche und kategorische Merkmale.
Im Moment haben wir 11 Funktionen, sodass Plot (). Show () möglicherweise nicht die optimalen Ergebnisse liefern. Stattdessen können wir einen Warncone Ranker verwenden, um die Funktionen zurückzugeben, die die meisten Warnungen ergaben (wenn alle Teile berücksichtigt werden). Hier ist der Code:
diamonds_special.set.unique() ['train', 'val', 'test', 'prod'] Categories (4, object): ['prod', 'test', 'train', 'val']
Sobald wir die Ranker -Ergebnisse erzielt haben, können wir seinen Kopf drucken, da es sich um einen Pandas -Datenrahmen handelt:
tr = diamonds_special[diamonds_special.set == "train"].drop("set", axis=1) val = diamonds_special[diamonds_special.set == "validation"].drop("set", axis=1) test = diamonds_special[diamonds_special.set == "test"].drop("set", axis=1) prod = diamonds_special[diamonds_special.set == "prod"].drop("set", axis=1) tr.shape (37758, 10)
Wir können sehen, dass die problematischsten Merkmale Farbe und Tiefe sind. Dies sollte mich nicht überraschen, da ich es war, der sie künstlich dazu veranlasste, vor dem Schreiben des Artikels zu driften.
Aber wenn dies ein reales Szenario wäre, möchten Sie einige Zeit mit der Arbeit an der Problemlösung für diese Funktionen verbringen.
Ich finde die Modellüberwachung faszinierend, weil es die Illusion zerstört, dass maschinelles Lernen fertig ist, sobald Sie ein gutes Modell haben. Wenn sich die Erde umgeht und die Benutzermuster sich ändern, bleibt kein Modell für lange Zeit relevant. Dies macht die Überwachung der Modellüberwachung zu einem entscheidenden Bestandteil der Fähigkeiten eines ML -Ingenieurs.
Heute haben wir einen Workflow für die grundlegende Modellüberwachung behandelt. Wir haben zunächst über grundlegende Überwachungskonzepte gesprochen. Dann tauchten wir voran in den Code ein: Wir haben die Daten in ein mit Nannyml kompatibeler Format gefälscht. Erstellte unser erstes Diagramm für die geschätzte Modellleistung und erstellte ein weiteres, um es mit realisierter Leistung zu vergleichen. Erhielt ein paar Benachrichtigungen, dass die Leistung sinkt; überprüfte es mit multivariater Drifterkennung; schwere Merkmalsdrift gefunden; doppelt überprüft es mit individueller Merkmalsdrifterkennung; identifizierte die Driftfunktionen.
Leider haben wir gleich zur Auflösung von Problemen stehen. Dieser letzte Schritt zur Überwachung des Workflows liegt außerhalb des Rahmens dieses Artikels. Ich habe jedoch einige hervorragende Empfehlungen, die es abdecken und viel mehr über die Modellüberwachung:
Beide Kurse werden von der besten Person erstellt, auf die Sie sich hoffen können - dem CEO und Gründer von Nannyml. In den Kursen gibt es viele Informationen von Informationen, die Sie nicht verpassen können.
Ich empfehle auch, die Nanny ML-Dokumente für einige praktische Tutorials zu lesen.
Das obige ist der detaillierte Inhalt vonEin End-to-End-ML-Modellüberwachungsworkflow mit Nannyml in Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!