Kapitel 4. Datenvalidierung

Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com

In Kapitel 3 haben wir besprochen, wie wir Daten aus verschiedenen Quellen in unsere Pipeline einspeisen können. In diesem Kapitel wollen wir nun damit beginnen, die Daten zu verarbeiten, indem wir sie validieren, wie in Abbildung 4-1 dargestellt.

Data Validation as part of ML Pipelines
Abbildung 4-1. Datenvalidierung als Teil von ML-Pipelines

Daten sind die Grundlage für jedes Modell des maschinellen Lernens, und die Nützlichkeit und Leistung des Modells hängen von den Daten ab, die zum Trainieren, Validieren und Analysieren des Modells verwendet werden. Wie du dir vorstellen kannst, können wir ohne robuste Daten keine robusten Modelle erstellen. Umgangssprachlich hast du vielleicht schon einmal den Ausdruck "Garbage in, garbage out" gehört, was bedeutet, dass unsere Modelle nicht funktionieren, wenn die zugrunde liegenden Daten nicht kuratiert und validiert sind. Genau das ist der Zweck des ersten Arbeitsschritts in unserer Pipeline für maschinelles Lernen: die Validierung der Daten.

In diesem Kapitel erläutern wir zunächst die Idee der Datenvalidierung und stellen dir dann ein Python-Paket aus dem TensorFlow Extended Ökosystem namens TensorFlow Data Validation (TFDV) vor. Wir zeigen dir, wie du das Paket in deinen Data Science-Projekten einrichten kannst, führen dich durch die häufigsten Anwendungsfälle und zeigen dir einige sehr nützliche Workflows.

Der Schritt der Datenvalidierung prüft, ob die Daten in deinen Pipelines dem entsprechen, was dein Feature-Engineering-Schritt erwartet. Er hilft dir, mehrere Datensätze zu vergleichen. Er zeigt dir auch, ob sich deine Daten im Laufe der Zeit ändern, z. B. wenn sich deine Trainingsdaten deutlich von den neuen Daten unterscheiden, die deinem Modell zur Inferenz zur Verfügung gestellt werden.

Am Ende des Kapitels integrieren wir unseren ersten Workflow-Schritt in unsere TFX-Pipeline.

Warum Datenvalidierung?

Beim maschinellen Lernen versuchen wir, aus Mustern in Datensätzen zu lernen und diese Erkenntnisse zu verallgemeinern. Deshalb stehen die Daten im Mittelpunkt unserer Arbeitsabläufe beim maschinellen Lernen, und die Qualität der Daten ist entscheidend für den Erfolg unserer Lernprojekte.

Jeder Schritt in unserer Pipeline für maschinelles Lernen bestimmt, ob der Arbeitsablauf mit dem nächsten Schritt fortgesetzt werden kann oder ob der gesamte Arbeitsablauf abgebrochen und neu gestartet werden muss (z. B. mit mehr Trainingsdaten). Die Datenvalidierung ist ein besonders wichtiger Prüfpunkt, weil sie Änderungen in den Daten auffängt, die in die Pipeline für maschinelles Lernen gelangen, bevor sie die zeitaufwändigen Vorverarbeitungs- und Trainingsschritte erreichen.

Wenn wir die Aktualisierung unserer Modelle für maschinelles Lernen automatisieren wollen, ist die Validierung unserer Daten unerlässlich. Wenn wir von Validierung sprechen, meinen wir vor allem drei verschiedene Überprüfungen unserer Daten:

  • Prüfe auf Datenanomalien.

  • Prüfe, ob sich das Datenschema nicht geändert hat.

  • Überprüfe, ob die Statistiken unserer neuen Datensätze noch mit den Statistiken unserer vorherigen Trainingsdatensätze übereinstimmen.

Der Schritt der Datenvalidierung in unserer Pipeline führt diese Prüfungen durch und weist auf eventuelle Fehler hin. Wenn ein Fehler entdeckt wird, können wir den Workflow anhalten und das Datenproblem von Hand lösen, indem wir zum Beispiel einen neuen Datensatz kuratieren.

Es ist auch sinnvoll, den Schritt der Datenvalidierung aus dem Schritt der Datenverarbeitung, dem nächsten Schritt in unserer Pipeline, zu übernehmen. Die Datenvalidierung erstellt Statistiken zu deinen Datenmerkmalen und zeigt auf, ob ein Merkmal einen hohen Prozentsatz an fehlenden Werten enthält oder ob die Merkmale stark korreliert sind. Diese Informationen sind nützlich, wenn du entscheidest, welche Merkmale in den Vorverarbeitungsschritt einbezogen werden sollen und wie die Vorverarbeitung aussehen soll.

Mit der Datenvalidierung kannst du die Statistiken verschiedener Datensätze vergleichen. Dieser einfache Schritt kann dir bei der Fehlersuche in deinem Modell helfen. Mit der Datenvalidierung kannst du zum Beispiel die Statistiken deiner Trainingsdaten mit denen deiner Validierungsdaten vergleichen. Mit ein paar Codezeilen macht sie dich auf jeden Unterschied aufmerksam. Du könntest ein binäres Klassifizierungsmodell mit einer perfekten Aufteilung von 50 % positiven und 50 % negativen Bezeichnungen trainieren, aber die Aufteilung der Bezeichnungen ist in deinem Validierungssatz nicht 50/50. Dieser Unterschied in der Labelverteilung wirkt sich letztendlich auf deine Validierungskennzahlen aus.

In einer Welt, in der die Datensätze ständig wachsen, ist die Datenvalidierung von entscheidender Bedeutung, um sicherzustellen, dass unsere Modelle für maschinelles Lernen der Aufgabe noch gewachsen sind. Da wir Schemata vergleichen können, können wir schnell erkennen, ob sich die Datenstruktur in neu gewonnenen Datensätzen geändert hat (z. B. wenn ein Merkmal veraltet ist). Außerdem können wir erkennen, ob deine Daten anfangen zu driften. Das bedeutet, dass deine neu gesammelten Daten eine andere Statistik aufweisen als der ursprüngliche Datensatz, der zum Trainieren deines Modells verwendet wurde. Diese Drift kann bedeuten, dass neue Merkmale ausgewählt werden müssen oder dass die Schritte zur Datenvorverarbeitung aktualisiert werden müssen (z. B. wenn sich das Minimum oder Maximum einer numerischen Spalte ändert). Für die Drift gibt es verschiedene Gründe: ein zugrundeliegender Trend in den Daten, saisonale Schwankungen der Daten oder das Ergebnis einer Rückkopplungsschleife, wie wir in Kapitel 13 besprechen.

In den folgenden Abschnitten werden wir diese verschiedenen Anwendungsfälle durchgehen. Zuvor wollen wir jedoch einen Blick auf die Installationsschritte werfen, die erforderlich sind, um TFDV zum Laufen zu bringen.

TFDV

Das TensorFlow-Ökosystem bietet ein Tool, das dich bei der Datenvalidierung unterstützen kann: TFDV. Es ist Teil des TFX-Projekts. Mit TFDV kannst du die Art von Analysen durchführen, die wir zuvor besprochen haben (z. B. Schemata erstellen und neue Daten anhand eines bestehenden Schemas validieren). Außerdem bietet es Visualisierungen auf der Grundlage des Google PAIR-Projekts Facets, wie in Abbildung 4-2 dargestellt.

TFDV akzeptiert zwei Eingabeformate, um die Datenvalidierung zu starten: TensorFlow's TFRecord und CSV-Dateien. Wie andere TFX-Komponenten auch, verteilt es die Analyse mit Apache Beam.

screenshot of a TFDV visualization
Abbildung 4-2. Screenshot einer TFDV-Visualisierung

Installation

Als wir das in Kapitel 2 vorgestellte Paket tfx installiert haben, wurde TFDV bereits als Abhängigkeit installiert. Wenn wir TFDV als eigenständiges Paket verwenden möchten, können wir es mit diesem Befehl installieren:

$ pip install tensorflow-data-validation

Nach der Installation von tfx oder tensorflow-data-validation können wir nun unsere Datenvalidierung in deine Machine-Learning-Workflows integrieren oder unsere Daten visuell in einem Jupyter Notebook analysieren. In den folgenden Abschnitten gehen wir ein paar Anwendungsfälle durch.

Erzeugen von Statistiken aus deinen Daten

Der erste Schritt in unserem Datenvalidierungsprozess besteht darin, einige zusammenfassende Statistiken für unsere Daten zu erstellen. Wir können zum Beispiel die CSV-Daten unserer Verbraucherbeschwerden direkt mit TFDV laden und Statistiken für jedes Merkmal erstellen:

import tensorflow_data_validation as tfdv
stats = tfdv.generate_statistics_from_csv(
    data_location='/data/consumer_complaints.csv',
    delimiter=',')

Mit folgendem Code können wir auf ganz ähnliche Weise Merkmalsstatistiken aus TFRecord-Dateien erstellen:

stats = tfdv.generate_statistics_from_tfrecord(
    data_location='/data/consumer_complaints.tfrecord')

Wie du TFRecord-Dateien erstellst, wird in Kapitel 3 beschrieben.

Beide TFDV-Methoden erzeugen eine Datenstruktur, in der die zusammenfassenden Statistiken für jedes Merkmal gespeichert werden, einschließlich der Minimal-, Maximal- und Durchschnittswerte.

Die Datenstruktur sieht wie folgt aus:

datasets {
  num_examples: 66799
  features {
    type: STRING
    string_stats {
      common_stats {
        num_non_missing: 66799
        min_num_values: 1
        max_num_values: 1
        avg_num_values: 1.0
        num_values_histogram {
          buckets {
            low_value: 1.0
            high_value: 1.0
            sample_count: 6679.9
...
}}}}}}

Bei numerischen Merkmalen berechnet die TFDV für jedes Merkmal:

  • Die Gesamtzahl der Datensätze

  • Die Anzahl der fehlenden Datensätze

  • Der Mittelwert und die Standardabweichung des Merkmals in den Datensätzen

  • Der minimale und maximale Wert des Merkmals in den Datensätzen

  • Der Prozentsatz der Nullwerte des Merkmals in den Datensätzen

Außerdem erstellt es ein Histogramm der Werte für jedes Merkmal.

Für kategorische Merkmale bietet die TFDV:

  • Die Gesamtzahl der Datensätze

  • Der Prozentsatz der fehlenden Datensätze

  • Die Anzahl der eindeutigen Datensätze

  • Die durchschnittliche Stringlänge aller Datensätze eines Merkmals

  • Für jede Kategorie bestimmt TFDV die Stichprobenzahl für jedes Label und seinen Rang

Du wirst gleich sehen, wie wir diese Statistiken in etwas Umsetzbares verwandeln können.

Schema aus deinen Daten generieren

Nachdem wir unsere zusammenfassenden Statistiken erstellt haben, ist der nächste Schritt die Erstellung eines Schemas für unseren Datensatz. Datenschemata sind eine Form der Beschreibung der Darstellung deines Datensatzes. Ein Schema legt fest, welche Merkmale in deinem Datensatz erwartet werden und auf welchem Typ jedes Merkmal basiert (Float, Integer, Bytes usw.). Außerdem sollte dein Schema die Grenzen deiner Daten festlegen (z. B. Mindest- und Höchstwerte sowie Schwellenwerte für fehlende Datensätze für ein Merkmal).

Die Schemadefinition deines Datensatzes kann dann verwendet werden, um künftige Datensätze zu validieren und festzustellen, ob sie mit deinen früheren Trainingssätzen übereinstimmen. Die von TFDV erstellten Schemata können auch im folgenden Workflow-Schritt verwendet werden, wenn du deine Datensätze vorverarbeitest, um sie in Daten umzuwandeln, die zum Trainieren von Machine Learning-Modellen verwendet werden können.

Wie im Folgenden gezeigt wird, kannst du die Schemainformationen mit einem einzigen Funktionsaufruf aus deinen erstellten Statistiken generieren:

schema = tfdv.infer_schema(stats)

tfdv.infer_schema erzeugt ein von TensorFlow definiertes Schema-Protokoll:1

feature {
  name: "product"
  type: BYTES
  domain: "product"
  presence {
    min_fraction: 1.0
    min_count: 1
  }
  shape {
    dim {
      size: 1
    }
  }
}

Du kannst das Schema mit einem einzigen Funktionsaufruf in jedem Jupyter Notebook anzeigen:

tfdv.display_schema(schema)

Die Ergebnisse sind in Abbildung 4-3 dargestellt.

Screenshot of a schema visualization
Abbildung 4-3. Screenshot einer Schema-Visualisierung

In dieser Visualisierung bedeutet Presence, ob das Merkmal in 100% der Datenbeispiele vorhanden sein muss (required) oder nicht (optional). Valency bedeutet die Anzahl der erforderlichen Werte pro Trainingsbeispiel. Bei kategorialen Merkmalen würde single bedeuten, dass jedes Trainingsbeispiel genau eine Kategorie für das Merkmal enthalten muss.

Das hier erstellte Schema ist möglicherweise nicht genau das, was wir brauchen, weil es davon ausgeht, dass der aktuelle Datensatz auch für alle zukünftigen Daten genau repräsentativ ist. Wenn ein Merkmal in allen Trainingsbeispielen in diesem Datensatz vorkommt, wird es als required markiert, aber in Wirklichkeit ist es vielleicht optional. Wie du das Schema entsprechend deiner eigenen Kenntnisse über den Datensatz aktualisieren kannst, zeigen wir dir im Abschnitt "Aktualisieren des Schemas".

Da das Schema nun definiert ist, können wir unsere Trainings- oder Auswertungsdatensätze vergleichen oder unsere Datensätze auf Probleme überprüfen, die unser Modell beeinträchtigen könnten.

Erkennen von Problemen in deinen Daten

In den vorherigen Abschnitten haben wir besprochen, wie wir zusammenfassende Statistiken und ein Schema für unsere Daten erstellen. Diese beschreiben unsere Daten, aber sie zeigen keine potenziellen Probleme auf. In den nächsten Abschnitten werden wir beschreiben, wie TFDV uns helfen kann, Probleme in unseren Daten zu erkennen.

Datensätze vergleichen

Nehmen wir an, wir haben zwei Datensätze: Trainings- und Validierungsdatensätze. Bevor wir unser maschinelles Lernmodell trainieren, möchten wir feststellen, wie repräsentativ der Validierungsdatensatz für den Trainingsdatensatz ist. Entsprechen die Validierungsdaten unserem Trainingsdatenschema? Fehlen irgendwelche Merkmalsspalten oder eine erhebliche Anzahl von Merkmalswerten? Mit TFDV können wir die Antwort schnell herausfinden.

Wie im Folgenden gezeigt, können wir beide Datensätze laden und dann beide Datensätze visualisieren. Wenn wir den folgenden Code in einem Jupyter Notebook ausführen, können wir die Datensatzstatistiken leicht vergleichen:

train_stats = tfdv.generate_statistics_from_tfrecord(
    data_location=train_tfrecord_filename)
val_stats = tfdv.generate_statistics_from_tfrecord(
    data_location=val_tfrecord_filename)

tfdv.visualize_statistics(lhs_statistics=val_stats, rhs_statistics=train_stats,
                          lhs_name='VAL_DATASET', rhs_name='TRAIN_DATASET')

Abbildung 4-4 zeigt den Unterschied zwischen den beiden Datensätzen. Der Validierungsdatensatz (mit 4.998 Datensätzen) weist beispielsweise eine geringere Rate an fehlenden sub_issue Werten auf. Das könnte bedeuten, dass das Merkmal seine Verteilung im Validierungsdatensatz ändert. Noch wichtiger ist, dass die Visualisierung zeigt, dass mehr als die Hälfte aller Datensätze keine sub_issue Informationen enthält. Wenn sub_issue ein wichtiges Merkmal für unser Modelltraining ist, müssen wir unsere Datenerfassungsmethoden anpassen, um neue Daten mit den korrekten Problemidentifikatoren zu sammeln.

Das Schema der Trainingsdaten, das wir zuvor erstellt haben, ist jetzt sehr praktisch. Mit TFDV können wir jede Datenstatistik anhand des Schemas überprüfen und Anomalien melden.

Comparison between a training and validation dataset
Abbildung 4-4. Vergleich zwischen Trainings- und Validierungsdatensätzen

Anomalien können mithilfe des folgenden Codes erkannt werden:

anomalies = tfdv.validate_statistics(statistics=val_stats, schema=schema)

Und wir können dann die Anomalien mit anzeigen:

tfdv.display_anomalies(anomalies)

Es wird das in Tabelle 4-1 dargestellte Ergebnis angezeigt.

Tabelle 4-1. Visualisierung der Anomalien in einem Jupyter Notebook
Name des Merkmals Anomalie Kurzbeschreibung Anomalie lange Beschreibung

"Unternehmen"

Spalte entfällt

Das Merkmal war in weniger Beispielen vorhanden als erwartet.

Der folgende Code zeigt das zugrunde liegende Anomalieprotokoll. Es enthält nützliche Informationen, die wir nutzen können, um unseren maschinellen Lernprozess zu automatisieren:

anomaly_info {
  key: "company"
  value {
    description: "The feature was present in fewer examples than expected."
    severity: ERROR
    short_description: "Column dropped"
    reason {
      type: FEATURE_TYPE_LOW_FRACTION_PRESENT
      short_description: "Column dropped"
      description: "The feature was present in fewer examples than expected."
    }
    path {
      step: "company"
    }
  }
}

Das Schema aktualisieren

Das vorangegangene Anomalieprotokoll zeigt uns, wie wir Abweichungen von dem Schema erkennen können, das automatisch aus unserem Datensatz generiert wird. Ein weiterer Anwendungsfall für TFDV ist das manuelle Festlegen des Schemas entsprechend unserem Fachwissen über die Daten. Nehmen wir das zuvor besprochene Merkmal sub_issue. Wenn wir entscheiden, dass dieses Merkmal in mehr als 90 % unserer Trainingsbeispiele vorhanden sein muss, können wir das Schema entsprechend anpassen.

Zuerst müssen wir das Schema aus seinem serialisierten Speicherort laden:

schema = tfdv.load_schema_text(schema_location)

Dann aktualisieren wir dieses Merkmal so, dass es in 90 % der Fälle benötigt wird:

sub_issue_feature = tfdv.get_feature(schema, 'sub_issue')
sub_issue_feature.presence.min_fraction = 0.9

Wir könnten auch die Liste der US-Bundesstaaten aktualisieren und Alaska entfernen:

state_domain = tfdv.get_domain(schema, 'state')
state_domain.value.remove('AK')

Wenn wir mit dem Schema zufrieden sind, schreiben wir die Schemadatei mit folgendem Befehl an ihren serialisierten Ort:

tfdv.write_schema_text(schema, schema_location)

Dann müssen wir die Statistiken erneut validieren, um die aktualisierten Anomalien zu sehen:

updated_anomalies = tfdv.validate_statistics(eval_stats, schema)
tfdv.display_anomalies(updated_anomalies)

Auf diese Weise können wir die Anomalien so anpassen, dass sie für unseren Datensatz geeignet sind.2

Datenverzerrung und -drift

TFDV bietet einen eingebauten "Schiefe-Vergleicher", der große Unterschiede zwischen den Statistiken zweier Datensätze erkennt. Dies ist nicht die statistische Definition von Schiefe (ein Datensatz, der asymmetrisch um seinen Mittelwert verteilt ist). Sie ist in der TFDV definiert als die L-Norm der Differenz zwischen den serving_statistics zweier Datensätze. Wenn die Differenz zwischen den beiden Datensätzen den Schwellenwert der L-Infinity-Norm für ein bestimmtes Merkmal überschreitet, wird es von TFDV mit Hilfe der Anomalieerkennung, die weiter oben in diesem Kapitel beschrieben wurde, als Anomalie markiert.

L-unendlich Norm

Die L-Unendlichkeitsnorm ist ein Ausdruck, der verwendet wird, um die Differenz zwischen zwei Vektoren (in unserem Fall die Servierstatistik) zu definieren. Die L-Infinity-Norm ist definiert als der maximale absolute Wert der Einträge des Vektors.

Die L-Unendlich-Norm des Vektors [3, -10, -5] ist zum Beispiel 10. Normen werden oft verwendet, um Vektoren zu vergleichen. Wenn wir die Vektoren [2, 4, -1] und [9, 1, 8] vergleichen wollen, berechnen wir zuerst ihre Differenz, die [-7, 3, -9] ist, und dann die L-Infinitätsnorm dieses Vektors, die 9 ist.

Im Fall von TFDV sind die beiden Vektoren die zusammenfassenden Statistiken der beiden Datensätze. Die zurückgegebene Norm ist der größte Unterschied zwischen diesen beiden Statistiksätzen.

Der folgende Code zeigt, wie du die Schiefe zwischen Datensätzen vergleichen kannst:

tfdv.get_feature(schema,
                 'company').skew_comparator.infinity_norm.threshold = 0.01
skew_anomalies = tfdv.validate_statistics(statistics=train_stats,
                                          schema=schema,
                                          serving_statistics=serving_stats)

Tabelle 4-2 zeigt die Ergebnisse.

Tabelle 4-2. Visualisierung der Datenverzerrung zwischen den Trainings- und Servicedatensätzen
Name des Merkmals Anomalie Kurzbeschreibung Anomalie lange Beschreibung

"Unternehmen"

Hoher L-Abstand zwischen Ausbildung und Aufschlag

Der L-Infinity-Abstand zwischen Training und Bedienung beträgt 0,0170752 (bis zu sechs signifikante Stellen) und liegt damit über dem Schwellenwert 0,01. Der Merkmalswert mit der größten Differenz ist: Experian

TFDV bietet auch eine drift_comparator, um die Statistiken von zwei Datensätzen desselben Typs zu vergleichen, z. B. zwei Trainingssätze, die an zwei verschiedenen Tagen gesammelt wurden. Wenn ein Drift festgestellt wird, sollte der Datenwissenschaftler entweder die Modellarchitektur überprüfen oder feststellen, ob das Feature Engineering erneut durchgeführt werden muss.

Ähnlich wie bei dem Beispiel mit der Schiefe solltest du deine drift_comparator für die Merkmale definieren, die du beobachten und vergleichen möchtest. Dann kannst du validate_statistics mit den beiden Datensatzstatistiken als Argumente aufrufen, eine für deine Basislinie (z.B. den gestrigen Datensatz) und eine für einen Vergleich (z.B. den heutigen Datensatz):

tfdv.get_feature(schema,
                 'company').drift_comparator.infinity_norm.threshold = 0.01
drift_anomalies = tfdv.validate_statistics(statistics=train_stats_today,
                                           schema=schema,
                                           previous_statistics=\
                                               train_stats_yesterday)

Dies ergibt das in Tabelle 4-3 dargestellte Ergebnis.

Tabelle 4-3. Visualisierung der Datenabweichung zwischen zwei Trainingssätzen
Name des Merkmals Anomalie Kurzbeschreibung Anomalie lange Beschreibung

"Unternehmen"

Hoher L-Unendlichkeitsabstand zwischen aktuellem und vorherigem

Der L-Infinity-Abstand zwischen dem aktuellen und dem vorherigen Merkmal beträgt 0,0170752 (bis zu sechs signifikante Stellen) und liegt damit über dem Schwellenwert 0,01. Der Merkmalswert mit der größten Differenz ist: Experian

Die L-Infinity-Norm ist sowohl auf skew_comparator als auch auf drift_comparator nützlich, um uns große Unterschiede zwischen Datensätzen aufzuzeigen, insbesondere solche, die uns zeigen könnten, dass etwas mit unserer Dateneingabe-Pipeline nicht stimmt. Da die L-Infinity-Norm nur eine einzige Zahl liefert, ist das Schema möglicherweise nützlicher, um Abweichungen zwischen Datensätzen zu erkennen.

Verzerrte Datensätze

Ein weiteres potenzielles Problem mit einem Eingabedatensatz sind Verzerrungen. Wir definieren Verzerrung hier als Daten, die in irgendeiner Weise nicht repräsentativ für die reale Welt sind. Dies steht im Gegensatz zur Fairness, die wir in Kapitel 7 als Vorhersagen unseres Modells definieren, die unterschiedliche Auswirkungen auf verschiedene Gruppen von Menschen haben.

Verzerrungen können sich auf verschiedene Weise in Daten einschleichen. Ein Datensatz ist zwangsläufig immer eine Teilmenge der realen Welt - wir können nicht hoffen, alle Details über alles zu erfassen. Die Art und Weise, wie wir Stichproben aus der realen Welt ziehen, ist immer in irgendeiner Weise verzerrt. Eine der Arten von Verzerrungen, die wir überprüfen können, ist die Selektionsverzerrung, bei der die Verteilung des Datensatzes nicht mit der realen Verteilung der Daten übereinstimmt.

Wir können TFDV verwenden, um mit Hilfe der zuvor beschriebenen Statistikvisualisierungen zu prüfen, ob die Auswahl verzerrt ist. Wenn unser Datensatz zum Beispiel Gender als kategoriales Merkmal enthält, können wir überprüfen, ob die Kategorie "männlich" nicht verzerrt ist. In unserem Datensatz für Verbraucherbeschwerden haben wir State als kategorisches Merkmal. Im Idealfall spiegelt die Verteilung der Beispiele auf die verschiedenen US-Bundesstaaten die relative Bevölkerungszahl in jedem Staat wider.

In Abbildung 4-5 sehen wir, dass das nicht der Fall ist (z. B. hat Texas an dritter Stelle eine größere Bevölkerung als Florida an zweiter Stelle). Wenn wir diese Art von Verzerrung in unseren Daten feststellen und glauben, dass diese Verzerrung die Leistung unseres Modells beeinträchtigt, können wir zurückgehen und mehr Daten sammeln oder unsere Daten über-/unterproben, um die richtige Verteilung zu erhalten.

Visualization of a biased feature in our dataset
Abbildung 4-5. Visualisierung eines verzerrten Merkmals in unserem Datensatz

Du kannst auch das zuvor beschriebene Anomalieprotokoll verwenden, um dich automatisch auf diese Art von Problemen aufmerksam zu machen. Mithilfe des Domänenwissens, das du über deinen Datensatz hast, kannst du Grenzwerte für numerische Werte erzwingen, die bedeuten, dass dein Datensatz so unvoreingenommen wie möglich ist - wenn dein Datensatz zum Beispiel die Löhne der Menschen als numerisches Merkmal enthält, kannst du erzwingen, dass der Mittelwert des Merkmalswertes realistisch ist.

Für weitere Details und Definitionen von Verzerrungen gibt es im Machine Learning Crash Course von Google einige nützliche Informationen.

Schneiden von Daten in TFDV

Wir können TFDV auch verwenden, um Datensätze nach Merkmalen unserer Wahl zu unterteilen und so zu zeigen, ob sie verzerrt sind. Dies ist vergleichbar mit der Berechnung der Modellleistung bei geschnittenen Merkmalen, die wir in Kapitel 7 beschreiben. Eine subtile Art der Verzerrung von Daten ist zum Beispiel, wenn Daten fehlen. Wenn Daten nicht zufällig fehlen, können sie bei einer Gruppe von Personen im Datensatz häufiger fehlen als bei anderen. Das kann dazu führen, dass das endgültige Modell für diese Gruppen schlechter abschneidet, wenn es trainiert wird.

In diesem Beispiel schauen wir uns Daten aus verschiedenen US-Bundesstaaten an. Mit dem folgenden Code können wir die Daten so aufteilen, dass wir nur Statistiken aus Kalifornien erhalten:

from tensorflow_data_validation.utils import slicing_util

slice_fn1 = slicing_util.get_feature_value_slicer(
    features={'state': [b'CA']}) 1
slice_options = tfdv.StatsOptions(slice_functions=[slice_fn1])
slice_stats = tfdv.generate_statistics_from_csv(
    data_location='data/consumer_complaints.csv',
    stats_options=slice_options)
1

Beachte, dass der Merkmalswert als eine Liste von Binärwerten angegeben werden muss.

Wir brauchen einen Hilfscode, um die aufgeschnittenen Statistiken in die Visualisierung zu kopieren:

from tensorflow_metadata.proto.v0 import statistics_pb2

def display_slice_keys(stats):
    print(list(map(lambda x: x.name, slice_stats.datasets)))

def get_sliced_stats(stats, slice_key):
    for sliced_stats in stats.datasets:
        if sliced_stats.name == slice_key:
            result = statistics_pb2.DatasetFeatureStatisticsList()
            result.datasets.add().CopyFrom(sliced_stats)
            return result
        print('Invalid Slice key')

def compare_slices(stats, slice_key1, slice_key2):
    lhs_stats = get_sliced_stats(stats, slice_key1)
    rhs_stats = get_sliced_stats(stats, slice_key2)
    tfdv.visualize_statistics(lhs_stats, rhs_stats)

Und wir können die Ergebnisse mit dem folgenden Code visualisieren:

tfdv.visualize_statistics(get_sliced_stats(slice_stats, 'state_CA'))

Und dann vergleiche die Statistiken für Kalifornien mit den Gesamtergebnissen:

compare_slices(slice_stats, 'state_CA', 'All Examples')

Die Ergebnisse sind in Abbildung 4-6 dargestellt.

Visualization of data sliced by feature values
Abbildung 4-6. Visualisierung von Daten, die nach Merkmalswerten unterteilt sind

In diesem Abschnitt haben wir einige nützliche Funktionen von TFDV vorgestellt, mit denen du Probleme in deinen Daten erkennen kannst. Als Nächstes schauen wir uns an, wie du deine Datenvalidierung mit einem Produkt von Google Cloud erweitern kannst.

Verarbeitung großer Datensätze mit GCP

Je mehr Daten wir sammeln, desto zeitaufwändiger wird die Datenvalidierung in unserem Workflow für maschinelles Lernen. Eine Möglichkeit, die Zeit für die Validierung zu verkürzen, ist die Nutzung von Cloud-Lösungen. Wenn wir einen Cloud-Provider nutzen, sind wir nicht auf die Rechenleistung unseres Laptops oder auf unsere eigenen Rechenressourcen beschränkt.

Als Beispiel stellen wir dir vor, wie du TFDV auf dem Google Cloud-Produkt Dataflow ausführen kannst. TFDV läuft auf Apache Beam, was einen Wechsel zu GCP Dataflow sehr einfach macht.

Mit Dataflow können wir unsere Datenvalidierungsaufgaben beschleunigen, indem wir sie parallelisieren und auf die zugewiesenen Knoten für unsere Datenverarbeitungsaufgabe verteilen. Dataflow berechnet zwar die Anzahl der CPUs und die zugewiesenen Gigabytes an Speicher, kann aber unsere Pipeline beschleunigen.

Wir demonstrieren ein minimales Setup, um unsere Datenvalidierungsaufgaben zu verteilen. Für weitere Informationen empfehlen wir dir die erweiterte GCP-Dokumentation. Wir gehen davon aus, dass du ein Google Cloud-Konto eingerichtet hast, die Abrechnungsdetails eingerichtet sind und die GOOGLE_APPLICATION_CREDENTIALS Umgebungsvariable in deiner Terminal-Shell gesetzt hast. Wenn du Hilfe brauchst, um loszulegen, schau in Kapitel 3 oder in der Google Cloud-Dokumentation nach.

Wir können dieselbe Methode verwenden, die wir zuvor besprochen haben (z. B. tfdv.generate_statistics_from_tfrecord), aber die Methoden benötigen die zusätzlichen Argumente pipeline_options und output_path. Während output_path auf den Google Cloud-Bucket verweist, in den die Datenvalidierungsergebnisse geschrieben werden sollen, ist pipeline_options ein Objekt, das alle Google Cloud-Details enthält, um unsere Datenvalidierung auf Google Cloud auszuführen. Der folgende Code zeigt, wie wir ein solches Pipeline-Objekt einrichten können:

from apache_beam.options.pipeline_options import (
    PipelineOptions, GoogleCloudOptions, StandardOptions)

options = PipelineOptions()
google_cloud_options = options.view_as(GoogleCloudOptions)
google_cloud_options.project = '<YOUR_GCP_PROJECT_ID>' 1
google_cloud_options.job_name = '<YOUR_JOB_NAME>' 2
google_cloud_options.staging_location = 'gs://<YOUR_GCP_BUCKET>/staging' 3
google_cloud_options.temp_location = 'gs://<YOUR_GCP_BUCKET>/tmp'
options.view_as(StandardOptions).runner = 'DataflowRunner'
1

Lege den Bezeichner deines Projekts fest.

2

Gib deinem Auftrag einen Namen.

3

Verweise auf einen Speicherbereich für temporäre Dateien.

Wir empfehlen, einen Speicherbereich für deine Dataflow-Aufgaben zu erstellen. In diesem Speicherbereich werden alle Datensätze und temporären Dateien gespeichert.

Sobald wir die Google Cloud-Optionen konfiguriert haben, müssen wir das Setup für die Dataflow-Worker konfigurieren. Alle Aufgaben werden von Workern ausgeführt, die mit den notwendigen Paketen ausgestattet sein müssen, um ihre Aufgaben auszuführen. In unserem Fall müssen wir TFDV installieren, indem wir es als zusätzliches Paket angeben.

Dazu lädst du das neueste TFDV-Paket (die Binärdatei .whl )3 auf dein lokales System herunter. Wähle eine Version, die auf einem Linux-System ausgeführt werden kann (z. B. tensorflow_data_validation-0.22.0-cp37-cp37m-manylinux2010_x86_64.whl).

Um die Worker-Setup-Optionen zu konfigurieren, gibst du den Pfad zu dem heruntergeladenen Paket in der Liste setup_options.extra_packages an, wie gezeigt:

from apache_beam.options.pipeline_options import SetupOptions

setup_options = options.view_as(SetupOptions)
setup_options.extra_packages = [
    '/path/to/tensorflow_data_validation'
    '-0.22.0-cp37-cp37m-manylinux2010_x86_64.whl']

Wenn du alle Optionen konfiguriert hast, kannst du die Datenvalidierungsaufgaben von deinem lokalen Rechner aus starten. Sie werden auf den Google Cloud Dataflow-Instanzen ausgeführt:

data_set_path = 'gs://<YOUR_GCP_BUCKET>/train_reviews.tfrecord'
output_path = 'gs://<YOUR_GCP_BUCKET>/'
tfdv.generate_statistics_from_tfrecord(data_set_path,
                                       output_path=output_path,
                                       pipeline_options=options)

Nachdem du die Datenvalidierung mit Dataflow gestartet hast, kannst du wieder zur Google Cloud-Konsole wechseln. Dein neu gestarteter Auftrag sollte ähnlich aufgelistet sein wie in Abbildung 4-7.

Google Cloud Dataflow Job Console
Abbildung 4-7. Google Cloud Dataflow Aufträge Konsole

Du kannst dann die Details des laufenden Auftrags, seinen Status und seine Details zur Autoskalierung überprüfen, wie in Abbildung 4-8 dargestellt.

Du siehst, dass du mit wenigen Schritten die Datenvalidierungsaufgaben in einer Cloud-Umgebung parallelisieren und verteilen kannst. Im nächsten Abschnitt werden wir die Integration der Datenvalidierungsaufgaben in unsere automatisierten Pipelines für maschinelles Lernen besprechen.

Google Cloud Dataflow Job Details
Abbildung 4-8. Google Cloud Dataflow Auftragsdetails

Integration von TFDV in deine Pipeline für maschinelles Lernen

Bis jetzt können alle Methoden, die wir besprochen haben, in einem eigenständigen Setup verwendet werden. Das kann hilfreich sein, um Datensätze außerhalb des Pipeline-Setups zu untersuchen.

TFX bietet eine Pipeline-Komponente namens StatisticsGen, die die Ausgabe der vorherigen ExampleGen Komponenten als Eingabe akzeptiert und dann die Erstellung von Statistiken durchführt:

from tfx.components import StatisticsGen

statistics_gen = StatisticsGen(
    examples=example_gen.outputs['examples'])
context.run(statistics_gen)

Wie in Kapitel 3 beschrieben, können wir die Ausgabe in einem interaktiven Kontext visualisieren:

context.show(statistics_gen.outputs['statistics'])

So erhalten wir die in Abbildung 4-9 dargestellte Visualisierung.

.Statistics generated by the `StatisticsGen` component
Abbildung 4-9. Von der Komponente StatisticsGen erstellte Statistiken

Die Erstellung unseres Schemas ist genauso einfach wie die Erstellung der Statistiken:

from tfx.components import SchemaGen

schema_gen = SchemaGen(
    statistics=statistics_gen.outputs['statistics'],
    infer_feature_shape=True)
context.run(schema_gen)

Die Komponente SchemaGen erstellt nur dann ein Schema, wenn noch keines vorhanden ist. Es ist eine gute Idee, das Schema beim ersten Durchlauf dieser Komponente zu überprüfen und es dann bei Bedarf manuell anzupassen, wie wir in "Aktualisieren des Schemas" besprochen haben . Wir können dieses Schema dann so lange verwenden, bis es geändert werden muss, z. B. wenn wir eine neue Funktion hinzufügen.

Nachdem wir die Statistiken und das Schema erstellt haben, können wir unseren neuen Datensatz nun validieren:

from tfx.components import ExampleValidator

example_validator = ExampleValidator(
    statistics=statistics_gen.outputs['statistics'],
    schema=schema_gen.outputs['schema'])
context.run(example_validator)
Hinweis

ExampleValidator kann die Anomalien im Vergleich zum Schema automatisch erkennen, indem es die zuvor beschriebenen Schräg- und Driftvergleiche verwendet. Dies deckt jedoch möglicherweise nicht alle potenziellen Anomalien in deinen Daten ab. Wenn du andere spezifische Anomalien erkennen willst, musst du eine eigene Komponente schreiben, wie wir in Kapitel 10 beschreiben.

Wenn die Komponente ExampleValidator einen Fehler in der Datensatzstatistik oder im Schema zwischen dem neuen und dem vorherigen Datensatz feststellt, setzt sie den Status im Metadatenspeicher auf fehlgeschlagen, und die Pipeline stoppt schließlich. Andernfalls fährt die Pipeline mit dem nächsten Schritt fort, der Vorverarbeitung der Daten.

Zusammenfassung

In diesem Kapitel haben wir besprochen, wie wichtig die Datenvalidierung ist und wie du diesen Prozess effizient durchführen und automatisieren kannst. Wir haben besprochen, wie man Datenstatistiken und Schemata erstellt und wie man zwei verschiedene Datensätze anhand ihrer Statistiken und Schemata vergleicht. Wir haben uns ein Beispiel dafür angesehen, wie du die Datenvalidierung in der Google Cloud mit Dataflow durchführen kannst und haben diesen Schritt des maschinellen Lernens in unsere automatisierte Pipeline integriert. Dies ist ein sehr wichtiger Schritt in unserer Pipeline, denn er verhindert, dass unsaubere Daten in die zeitaufwändigen Vorverarbeitungs- und Trainingsschritte eingespeist werden.

In den folgenden Kapiteln werden wir unser Pipeline-Setup erweitern, indem wir mit der Datenvorverarbeitung beginnen.

1 Du kannst die Protokollpuffer-Definitionen für das Schema-Protokoll im TensorFlow-Repository finden.

2 Du kannst das Schema auch so anpassen, dass in der Schulungs- und in der Dienstumgebung unterschiedliche Funktionen erforderlich sind. In der Dokumentation findest du weitere Informationen.

3 Lade die TFDV-Pakete herunter.

Get Aufbau von Pipelines für maschinelles Lernen now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.