Objektkontext-Anreicherungen in BigQuery analysieren

Wenn Sie Objektkontext-Anreicherungen mit SQL in BigQuery abfragen, können Sie Metadaten in Millionen von gespeicherten Objekten suchen, filtern und analysieren, ohne jedes Objekt einzeln prüfen zu müssen.

Wenn Sie Storage Insights-Datasets konfigurieren, exportiert Cloud Storage Ihr Objektinventar und Ihre Metadaten, einschließlich der von KI-Modellen generierten Objektkontext-Anreicherungen, automatisch direkt nach BigQuery. Auf dieser Seite wird erläutert, wie Cloud Storage Objektkontext-Anreicherungen in BigQuery strukturiert. Außerdem bietet es SQL-Rezepte zum Suchen von Labels, Erkennen von Gesichtern, Identifizieren expliziter Inhalte, Extrahieren von Begrenzungsrahmen und Kategorisieren von PDF-Dokumenten.

Erforderliche Rollen abrufen

Bitten Sie Ihren Administrator, Ihnen die folgenden IAM-Rollen für Ihr Projekt zuzuweisen, um die Berechtigungen zu erhalten, die Sie zum Abfragen von Objektkontext-Anreicherungen in BigQuery benötigen:

Weitere Informationen zum Zuweisen von Rollen finden Sie unter Zugriff auf Projekte, Ordner und Organisationen verwalten.

Diese vordefinierten Rollen enthalten die Berechtigungen, die zum Abfragen von Objektkontext-Anreicherungen in BigQuery erforderlich sind. Maximieren Sie den Abschnitt Erforderliche Berechtigungen, um die notwendigen Berechtigungen anzuzeigen:

Erforderliche Berechtigungen

Die folgenden Berechtigungen sind erforderlich, um Objektkontext-Anreicherungen in BigQuery abzufragen:

  • bigquery.jobs.create
  • bigquery.tables.getData

Sie können diese Berechtigungen auch mit benutzerdefinierten Rollen oder anderen vordefinierten Rollen erhalten.

Einbindung von Objektkontext-Anreicherungen in Storage Insights

Wenn Sie ein Storage Insights-Dataset für Ihr Projekt konfigurieren, exportiert Cloud Storage Ihr Bucket-Inventar und Ihre Objektkontexte regelmäßig in ein BigQuery-Dataset.

In BigQuery werden Ihre Daten in der Ansicht object_contexts_catalog_view angezeigt. Diese Ansicht bietet einen einheitlichen Katalog Ihrer gespeicherten Objekte. Jede Zeile enthält Objektattribute (project, bucket, name, generation) und ein wiederkehrendes contexts-Datensatzarray:

  • contexts.key: Die eindeutige Kontext-ID. Von Cloud Storage generierte Anreicherungen für maschinelles Lernen beginnen immer mit dem Präfix google:annotation: (z. B. google:annotation:label-detector-v1 oder google:annotation:face-detector-v1).
  • contexts.value: Der Status der Modellausführung für die Anreicherung (z. B. SUCCESS oder FAILURE).
  • contexts.extendedData: Eine JSON-Spalte, die die Anreicherungsnutzlast des Modells enthält, z. B. erkannte Labels, Gesichtsmerkmale, Polygon-Eckpunkte und Kategoriepfade.

Die vollständige Tabellenstruktur und die Spaltenbeschreibungen finden Sie im Katalogschema für Objektkontexte.

Abfragemuster verstehen: UNNEST im Vergleich zu EXISTS

Ein Objekt kann mehrere Kontexte haben und jedes Modell kann mehrere Erkennungen ausgeben (z. B. mehrere Labels oder erkannte Gesichter). Wenn Sie die Ansicht object_contexts_catalog_view abfragen, verwenden Sie in der Regel eines der folgenden SQL-Muster:

  • Zeile pro Erkennung (UNNEST): Verwenden Sie den Operator UNNEST für das wiederholte contexts-Datensatzarray und das innere JSON-Array des Modells (mit der Funktion JSON_QUERY_ARRAY). Durch das Aufheben der Verschachtelung werden wiederholte Anreicherungen vereinfacht, sodass für jedes erkannte Feature eine eigene Zeile erstellt wird. Verwenden Sie diesen Ansatz, wenn Sie einzelne Labels prüfen, Koordinaten von Begrenzungsrahmen extrahieren oder Statistiken für alle Erkennungen berechnen möchten.
  • Zeile pro Objekt (EXISTS): Verwenden Sie eine korrelierte EXISTS-Unterabfrage, um zu prüfen, ob ein Objekt ein bestimmtes Label, eine bestimmte Modellausgabe oder einen bestimmten Schwellenwert enthält. Bei diesem Ansatz werden wiederholte Kontexte ausgewertet, ohne sie in der äußeren Abfrage zu verschachteln. Es wird genau eine Zeile pro Objekt zurückgegeben, unabhängig davon, wie viele Erkennungen übereinstimmen.

Beispielabfragen

Die folgenden SQL-Beispiele zeigen, wie Sie Objektkontext-Anreicherungen für gängige Datenkuratierungs- und Analyseworkflows abfragen und filtern.

Ersetzen Sie in jeder Abfrage Folgendes:

  • PROJECT_ID: Die ID Ihres Cloud de Confiance -Projekts.
  • DATASET_ID: Der Name des BigQuery-Datasets, in das Storage Insights Ihre Daten exportiert.

Bilder mit einem bestimmten Label finden

Wenn Sie nach Bildern suchen möchten, die vom Modell label-detector bewertet wurden, können Sie entweder jedes übereinstimmende Label als einzelne Zeile oder eindeutige Bilder zurückgeben, die das Label enthalten.

Übereinstimmende Labels zurückgeben (Zeilen werden vereinfacht)

Mit der folgenden Abfrage werden die Arrays contexts und labelAnnotations vereinfacht, um für jedes übereinstimmende Label, das in einem Bild gefunden wird, eine separate Zeile zurückzugeben:

SELECT
  t.project,
  t.bucket,
  t.name,
  t.generation,
  STRING(label.description) AS label_description,
  FLOAT64(label.score) AS confidence_score
FROM
  `PROJECT_ID.DATASET_ID.object_contexts_catalog_view` AS t,
  UNNEST(t.contexts) AS context,
  UNNEST(JSON_QUERY_ARRAY(context.extendedData.labelAnnotationGroup.labelAnnotations)) AS label
WHERE
  context.key = 'google:annotation:label-detector-v1'
  AND LOWER(STRING(label.description)) = 'car'
  AND FLOAT64(label.score) > 0.75
LIMIT 10;

Eindeutige Bilder zurückgeben (vermeidet doppelte Zeilen)

Wenn ein Bild mehrere übereinstimmende Labels enthält, werden durch das Unnesting mehrere Zeilen für dieses Objekt erzeugt. Wenn Sie genau eine Zeile pro Bild zurückgeben möchten, prüfen Sie in einer EXISTS-Unterabfrage, ob das Label vorhanden ist:

SELECT
  project,
  bucket,
  name,
  generation
FROM
  `PROJECT_ID.DATASET_ID.object_contexts_catalog_view` AS t
WHERE
  EXISTS(
    SELECT 1
    FROM
      UNNEST(t.contexts) AS context,
      UNNEST(JSON_QUERY_ARRAY(context.extendedData.labelAnnotationGroup.labelAnnotations)) AS label
    WHERE
      context.key = 'google:annotation:label-detector-v1'
      AND LOWER(STRING(label.description)) = 'car'
      AND FLOAT64(label.score) > 0.75
  )
LIMIT 10;

Porträts und Selfies mit einem lächelnden Motiv finden (Gesichtserkennung)

Sie können mehrere Gesichtsmerkmale wie Gesichtsausdrücke, Kopfausrichtungswinkel und Begrenzungsrahmenabmessungen kombinieren, um bestimmte Arten von Fotos zu finden.

In der folgenden Abfrage wird ein allgemeiner Tabellenausdruck (Common Table Expression, CTE) verwendet, um die Abdeckung des Begrenzungsrahmens für Gesichter zu berechnen. Es wird nach lächelnden Porträts gefiltert, auf denen die Person nach vorn blickt und mindestens 60% des Bildes einnimmt:

WITH
  face_stats AS (
    SELECT
      t.project,
      t.bucket,
      t.name,
      t.generation,
      -- Extract the joy likelihood score (0.0 to 1.0)
      FLOAT64(face.joyProbability) AS joy_probability,
      -- Extract head pose orientation angles (degrees)
      FLOAT64(face.rollAngle) AS roll_angle,
      FLOAT64(face.panAngle) AS pan_angle,
      FLOAT64(face.tiltAngle) AS tilt_angle,
      -- Calculate the bounding box area relative to total image area (0.0 to 1.0)
      (
        SELECT AS STRUCT
          (MAX(FLOAT64(v.x)) - MIN(FLOAT64(v.x)))
          * (MAX(FLOAT64(v.y)) - MIN(FLOAT64(v.y))) AS coverage
        FROM
          UNNEST(JSON_QUERY_ARRAY(face.boundingPoly.normalizedVertices)) AS v
      ).coverage AS face_coverage_percentage
    FROM
      `PROJECT_ID.DATASET_ID.object_contexts_catalog_view` AS t,
      UNNEST(t.contexts) AS context,
      UNNEST(
        JSON_QUERY_ARRAY(
          context.extendedData.faceAnnotationGroup.faceAnnotations)) AS face
    WHERE
      context.key = 'google:annotation:face-detector-v1'
  )
SELECT
  project,
  bucket,
  name,
  generation,
  joy_probability,
  face_coverage_percentage
FROM
  face_stats
WHERE
  joy_probability > 0.5
  AND roll_angle BETWEEN -10 AND 10
  AND pan_angle BETWEEN -10 AND 10
  AND tilt_angle BETWEEN -10 AND 10
  AND face_coverage_percentage >= 0.60
LIMIT 10;

In dieser Abfrage werden die folgenden Filter angewendet:

  • joy_probability > 0.5: Wählt Gesichter aus, die als fröhlich oder lächelnd bewertet werden.
  • BETWEEN -10 AND 10: Schränkt die Winkel roll, pan und tilt ein, sodass das Gesicht direkt zur Kamera ausgerichtet ist.
  • face_coverage_percentage >= 0.60: Verwendet normalisierte Polygon-Eckpunkte (0.0 bis 1.0), um nach Gesichtern zu filtern, die 60% oder mehr des Frames einnehmen.

Bilder mit Sicherheitsmeldungen finden

Das Modell content-safety wertet Bilder auf Inhalte nur für Erwachsene und gewaltverherrlichende Inhalte aus. Das Modell weist jeder Kategorie eine Wahrscheinlichkeitsbewertung zu, z. B. VERY_UNLIKELY, UNLIKELY, POSSIBLE, LIKELY oder VERY_LIKELY.

Die folgende Abfrage gibt eindeutige Bilder zurück, die das Modell mit hoher Konfidenz als Inhalte nur für Erwachsene kennzeichnet:

SELECT
  project,
  bucket,
  name,
  generation
FROM
  `PROJECT_ID.DATASET_ID.object_contexts_catalog_view` AS t
WHERE
  EXISTS(
    SELECT 1
    FROM
      UNNEST(t.contexts) AS context
    WHERE
      context.key = 'google:annotation:content-safety-v1'
      AND STRING(context.extendedData.contentSafetyAnnotation.adultContentLikelihood) = 'VERY_LIKELY'
  )
LIMIT 10;

Wenn Sie nach gewaltverherrlichenden Inhalten oder anderen Sensitivitäten filtern möchten, ersetzen Sie das Feld adultContentLikelihood durch das Feld violentContentLikelihood oder prüfen Sie die Bewertung 'LIKELY'.

Bilder mit einem bestimmten Label zählen

Wenn Sie die Gesamtzahl der eindeutigen Bilder mit einem bestimmten Label zählen möchten, ohne Bilder mit mehreren Labels doppelt zu zählen, verwenden Sie COUNT(*) mit einer EXISTS-Unterabfrage:

SELECT
  COUNT(*) AS image_count
FROM
  `PROJECT_ID.DATASET_ID.object_contexts_catalog_view` AS t
WHERE
  EXISTS(
    SELECT 1
    FROM
      UNNEST(t.contexts) AS context,
      UNNEST(
        JSON_QUERY_ARRAY(
          context.extendedData.labelAnnotationGroup.labelAnnotations)) AS label
    WHERE
      context.key = 'google:annotation:label-detector-v1'
      AND LOWER(STRING(label.description)) = 'ristretto'
      AND FLOAT64(label.score) > 0.5
  );

Begrenzungsrahmenkoordinaten für erkannte Objekte extrahieren

Das Modell object-detector erkennt physische Objekte in einem Bild und stellt normalisierte Begrenzungspolygone (boundingPoly) bereit, die angeben, wo das Objekt im Frame erscheint.

Mit der folgenden Abfrage werden erkannte Objekte mit dem Namen Drink extrahiert und Koordinatenspalten für den Begrenzungsrahmen auf oberster Ebene (x_min, y_min, x_max, y_max) erstellt:

SELECT
  t.project,
  t.bucket,
  t.name,
  t.generation,
  STRING(object.name) AS object_name,
  FLOAT64(object.score) AS confidence_score,
  -- Calculate bounding box boundaries from normalized vertices
  (
    SELECT AS STRUCT
      MIN(FLOAT64(v.x)) AS x_min,
      MIN(FLOAT64(v.y)) AS y_min,
      MAX(FLOAT64(v.x)) AS x_max,
      MAX(FLOAT64(v.y)) AS y_max
    FROM
      UNNEST(JSON_QUERY_ARRAY(object.boundingPoly.normalizedVertices)) AS v
  ).*
FROM
  `PROJECT_ID.DATASET_ID.object_contexts_catalog_view` AS t,
  UNNEST(t.contexts) AS context,
  UNNEST(
    JSON_QUERY_ARRAY(
      context.extendedData.objectAnnotationGroup.objectAnnotations)) AS object
WHERE
  context.key = 'google:annotation:object-detector-v1'
  AND LOWER(STRING(object.name)) = 'drink'
  AND FLOAT64(object.score) > 0.5
LIMIT 10;

Die Unterabfrage berechnet die minimalen und maximalen normalisierten Koordinaten für jedes Polygon. Der Ausdruck .* entpackt die Koordinatenfelder x_min, y_min, x_max und y_max direkt in die Ergebnismenge.

Objekte über mehrere Modelle hinweg abgleichen

Da Cloud Storage Anreicherungen aus jedem Modell als unabhängige Kontexte an dasselbe Objekt anhängt, können Sie mehrere Modellergebnisse zusammenführen, um sehr spezifische Inhalte zu finden.

In der folgenden Abfrage wird contexts zweimal entpackt, um Bilder zu finden, die vom Modell label-detector als Ristretto klassifiziert werden und ein lokalisiertes Drink-Objekt enthalten, das vom Modell object-detector identifiziert wurde:

SELECT
  t.project,
  t.bucket,
  t.name,
  t.generation,
  STRING(object.name) AS object_name,
  FLOAT64(object.score) AS object_score,
  STRING(label.description) AS label_description,
  FLOAT64(label.score) AS label_score,
  (
    SELECT AS STRUCT
      MIN(FLOAT64(v.x)) AS x_min,
      MIN(FLOAT64(v.y)) AS y_min,
      MAX(FLOAT64(v.x)) AS x_max,
      MAX(FLOAT64(v.y)) AS y_max
    FROM
      UNNEST(JSON_QUERY_ARRAY(object.boundingPoly.normalizedVertices)) AS v
  ).*
FROM
  `PROJECT_ID.DATASET_ID.object_contexts_catalog_view` AS t,
  -- Match the label detection context
  UNNEST(t.contexts) AS label_ctx,
  UNNEST(
    JSON_QUERY_ARRAY(
      label_ctx.extendedData.labelAnnotationGroup.labelAnnotations)) AS label,
  -- Match the object detection context on the same object
  UNNEST(t.contexts) AS object_ctx,
  UNNEST(
    JSON_QUERY_ARRAY(
      object_ctx.extendedData.objectAnnotationGroup.objectAnnotations)) AS object
WHERE
  label_ctx.key = 'google:annotation:label-detector-v1'
  AND LOWER(STRING(label.description)) = 'ristretto'
  AND FLOAT64(label.score) > 0.5
  AND object_ctx.key = 'google:annotation:object-detector-v1'
  AND LOWER(STRING(object.name)) = 'drink'
  AND FLOAT64(object.score) > 0.5
LIMIT 10;

PDF-Dokumente nach Klassifizierungskategorie filtern

Das pdf-classification-Modell weist gespeicherten PDF-Dokumenten hierarchische Kategorien (z. B. /Finance/Accounting & Auditing oder /Law & Government/Legal Services) zu.

Mit der folgenden Abfrage werden PDF-Objekte gesucht, die unter dem Zweig /Finance mit Konfidenzwerten größer als 0,5 kategorisiert sind:

SELECT
  t.project,
  t.bucket,
  t.name,
  t.generation,
  STRING(category.label) AS category_name,
  FLOAT64(category.score) AS confidence_score
FROM
  `PROJECT_ID.DATASET_ID.object_contexts_catalog_view` AS t,
  UNNEST(t.contexts) AS context,
  UNNEST(
    JSON_QUERY_ARRAY(
      context.extendedData.pdfClassificationCategoryList.categories)) AS category
WHERE
  context.key = 'google:annotation:pdf-classification-v1'
  AND STARTS_WITH(STRING(category.label), '/Finance')
  AND FLOAT64(category.score) > 0.5
LIMIT 10;

Eine vollständige Liste der unterstützten Taxonomiekategorien finden Sie unter PDF-Klassifizierungskategorien.

PDF-Dokumente nach Klassifizierungskategorie aggregieren

Wenn Sie die Verteilung der Dokumente in Ihrem Archiv analysieren möchten, können Sie Ihre PDF-Objekte nach Kategorie aggregieren und zählen:

SELECT
  STRING(category.label) AS category_name,
  COUNT(*) AS document_count
FROM
  `PROJECT_ID.DATASET_ID.object_contexts_catalog_view` AS t,
  UNNEST(t.contexts) AS context,
  UNNEST(
    JSON_QUERY_ARRAY(
      context.extendedData.pdfClassificationCategoryList.categories)) AS category
WHERE
  context.key = 'google:annotation:pdf-classification-v1'
GROUP BY
  category_name
ORDER BY
  document_count DESC
LIMIT 10;

Maßnahmen in Bezug auf Abfrageergebnisse ergreifen

Das Abfragen Ihrer Metadaten ist oft der erste Schritt bei der automatisierten Datenkuratierung, Compliance-Prüfung oder Richtlinienerzwingung. Nachdem Sie bestimmte Objektsätze in BigQuery identifiziert haben, können Sie diese Ergebnisse so in nachgelagerte Workflows einspeisen:

  • Datasets für maschinelles Lernen kuratieren: Exportieren Sie Ihre Abfrageergebnisse in eine neue BigQuery-Tabelle oder CSV-Datei, um gezielte Trainings- und Validierungs-Datasets für benutzerdefinierte Modelle zu erstellen.
  • Richtlinienwidrige Objekte unter Quarantäne stellen oder entfernen: Geben Sie die Objektnamen und Bucket-Speicherorte, die durch Sicherheitsabfragen identifiziert wurden, in Storage-Batchvorgänge ein, um sie in eingeschränkte Quarantäne-Buckets zu verschieben oder im Bulk zu löschen.
  • Inhaltsverteilung prüfen und Kosten optimieren: Aggregieren Sie Objektklassifizierungen, Dimensionen und Kategorien, um die Speicherverteilung in Ihrer Organisation zu verstehen und gezielte Regeln für die Verwaltung des Lebenszyklus zu erstellen.

Nächste Schritte