1. Übersicht
In diesem Lab verwenden Sie BigQuery DataFrames aus einem Python-Notebook in BigQuery Studio, um mit Python Erkenntnisse aus Daten zu gewinnen. Generative KI von Google nutzen, um unstrukturierte Textdaten zu analysieren und zu visualisieren
Sie erstellen ein Python-Notebook, um eine öffentliche Datenbank mit Kundenbeschwerden zu kategorisieren und zusammenzufassen. Diese kann an beliebige unstrukturierte Textdaten angepasst werden.
Ziele
Aufgaben in diesem Lab:
- Python-Notebooks in BigQuery Studio aktivieren und verwenden
- Verbindung zu BigQuery mit dem BigQuery DataFrames-Paket herstellen
- Einbettungen aus unstrukturierten Textdaten mit BigQuery ML und einer Verbindung zu einem Texteinbettungsendpunkt in Vertex AI erstellen
- Einbettungen mit BigQuery ML clustern
- Cluster mit einem LLM über BigQuery ML zusammenfassen
2. Voraussetzungen
Hinweis
Wenn Sie der Anleitung in diesem Codelab folgen möchten, benötigen Sie ein Google Cloud-Projekt mit aktiviertem BigQuery Studio und einem verknüpften Abrechnungskonto.
- Wählen Sie in der Google Cloud Console auf der Seite zur Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.
- Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein. So prüfen Sie, ob die Abrechnung für ein Projekt aktiviert ist
- Folgen Sie der Anleitung unter BigQuery Studio für die Asset-Verwaltung aktivieren.
BigQuery Studio vorbereiten
Leeres Notebook erstellen und mit einer Laufzeit verbinden
- Rufen Sie BigQuery Studio in der Google Cloud Console auf.
- Klicken Sie neben der Schaltfläche + auf das ▼.
- Wählen Sie Python-Notebook aus.
- Schließen Sie die Vorlagenauswahl.
- Wählen Sie + Code aus, um eine neue Codezelle zu erstellen.
- Installieren Sie die neueste Version des BigQuery DataFrames-Pakets über die Codezelle.Geben Sie den folgenden Befehl ein.
Klicken Sie auf die Schaltfläche 🞂 oder drücken Sie Umschalt + Eingabetaste, um die Codezelle auszuführen.%pip install --upgrade bigframes --quiet
3. Öffentliches Dataset lesen
Initialisieren Sie das BigQuery DataFrames-Paket, indem Sie Folgendes in einer neuen Codezelle ausführen:
import bigframes.pandas as bpd
bpd.options.bigquery.ordering_mode = "partial"
Hinweis: In diesem Tutorial verwenden wir den experimentellen „Modus für partielle Sortierung“, der in Verbindung mit pandas-ähnlicher Filterung effizientere Abfragen ermöglicht. Einige pandas-Funktionen, für die eine strikte Reihenfolge oder ein Index erforderlich ist, funktionieren möglicherweise nicht.
Datenbank für Verbraucherbeschwerden
Die Consumer Complaint Database (Datenbank für Verbraucherbeschwerden) wird über das Programm für öffentliche Datasets in Google Cloud in BigQuery bereitgestellt. Diese Sammlung von Beschwerden über Finanzprodukte und ‑dienstleistungen für Verbraucher wird vom US Consumer Financial Protection Bureau erhoben.
Fragen Sie in BigQuery die Tabelle bigquery-public-data.cfbp_complaints.complaint_database ab, um die Consumer Complaint Database zu analysieren. Mit der Methode bigframes.pandas.read_gbq() können Sie einen DataFrame aus einem Abfragestring oder einer Tabellen-ID erstellen.
Führen Sie den folgenden Code in einer neuen Codezelle aus, um einen DataFrame mit dem Namen „feedback“ zu erstellen:
feedback = bpd.read_gbq(
"bigquery-public-data.cfpb_complaints.complaint_database"
)
Grundlegende Informationen zu einem DataFrame abrufen
Mit der Methode DataFrame.peek() können Sie eine kleine Stichprobe der Daten herunterladen.
Führen Sie diese Zelle aus:
feedback.peek()
Erwartete Ausgabe:
date_received product ... timely_response consumer_disputed complaint_id
0 2014-03-05 Bank account or service ... True False 743665
1 2014-01-21 Bank account or service ... True False 678608
2 2020-12-31 Debt collection ... True <NA> 4041190
3 2014-02-12 Debt collection ... True False 714350
4 2015-02-23 Debt collection ... True False 1251358
Hinweis: Für head() ist eine Sortierung erforderlich und es ist im Allgemeinen weniger effizient als peek(), wenn Sie eine Stichprobe von Daten visualisieren möchten.
Wie bei pandas können Sie mit der Property DataFrame.dtypes alle verfügbaren Spalten und die entsprechenden Datentypen aufrufen. Sie werden auf pandas-kompatible Weise bereitgestellt.
Führen Sie diese Zelle aus:
feedback.dtypes
Erwartete Ausgabe:
date_received date32[day][pyarrow]
product string[pyarrow]
subproduct string[pyarrow]
issue string[pyarrow]
subissue string[pyarrow]
consumer_complaint_narrative string[pyarrow]
company_public_response string[pyarrow]
company_name string[pyarrow]
state string[pyarrow]
zip_code string[pyarrow]
tags string[pyarrow]
consumer_consent_provided string[pyarrow]
submitted_via string[pyarrow]
date_sent_to_company date32[day][pyarrow]
company_response_to_consumer string[pyarrow]
timely_response boolean
consumer_disputed boolean
complaint_id string[pyarrow]
dtype: object
Mit der Methode DataFrame.describe() werden einige grundlegende Statistiken aus dem DataFrame abgefragt. Da dieser DataFrame keine numerischen Spalten enthält, wird eine Zusammenfassung der Anzahl der Werte, die nicht null sind, und der Anzahl der eindeutigen Werte angezeigt.
Führen Sie diese Zelle aus:
# Exclude some of the larger columns to make the query more efficient.
feedback.drop(columns=[
"consumer_complaint_narrative",
"company_public_response",
"company_response_to_consumer",
]).describe()
Erwartete Ausgabe:
product subproduct issue subissue company_name state ... timely_response consumer_disputed complaint_id
count 3458906 3223615 3458906 2759004 3458906 3417792 ... 3458906 768399 3458906
nunique 18 76 165 221 6694 63 ... 2 2 3458906
4. Daten analysieren
Bevor Sie sich die tatsächlichen Beschwerden ansehen, können Sie die Daten mit den Pandas-ähnlichen Methoden im DataFrame visualisieren.
DataFrame visualisieren
Es gibt mehrere integrierte Visualisierungsmethoden wie DataFrame.plot.hist(). Da dieser DataFrame hauptsächlich String- und boolesche Daten enthält, können wir zuerst einige Aggregationen durchführen, um mehr über die verschiedenen Spalten zu erfahren.
Zählen Sie, wie viele Beschwerden aus den einzelnen Bundesstaaten eingehen.
complaints_by_state = (
feedback.groupby(
"state", as_index=False,
).size()
.rename(columns={"size": "total_complaints"})
.sort_values(by="total_complaints", ascending=False)
)
Konvertieren Sie die Daten mit der Methode DataFrame.to_pandas() in einen Pandas DataFrame.
complaints_pd = complaints_by_state.head(10).to_pandas()
Verwenden Sie Pandas-Visualisierungsmethoden für diesen heruntergeladenen DataFrame.
complaints_pd.plot.bar(x="state", y="total_complaints")

Mit anderen Datasets verknüpfen
Bisher haben Sie sich Beschwerden nach Bundesstaat angesehen. Dabei geht jedoch wichtiger Kontext verloren. Einige Bundesstaaten haben mehr Einwohner als andere. Sie können die Daten mit einem Bevölkerungs-Dataset wie der American Community Survey des US Census Bureau und der bigquery-public-data.geo_us_boundaries.states-Tabelle zusammenführen.
us_states = bpd.read_gbq("bigquery-public-data.geo_us_boundaries.states")
us_survey = bpd.read_gbq("bigquery-public-data.census_bureau_acs.state_2020_5yr")
# Ensure there are leading 0s on GEOIDs for consistency across tables.
us_states = us_states.assign(
geo_id=us_states["geo_id"].str.pad(2, fillchar="0")
)
us_survey = us_survey.assign(
geo_id=us_survey["geo_id"].str.pad(2, fillchar="0")
)
Bei der American Community Survey werden Bundesstaaten anhand der GEOID identifiziert. Führen Sie einen Join mit der Tabelle „states“ aus, um die Bevölkerung nach zweistelligem Bundesstaatscode zu erhalten.
pops = us_states.set_index("geo_id")[["state"]].join(
us_survey.set_index("geo_id")[["total_pop"]]
)
Führen Sie diese Daten nun mit der Beschwerdedatenbank zusammen, um die Bevölkerung mit der Anzahl der Beschwerden zu vergleichen.
complaints_and_pops = complaints_by_state.set_index("state").join(
pops.set_index("state")
)
Erstellen Sie ein Streudiagramm, um die Bevölkerungszahlen der Bundesstaaten mit der Anzahl der Beschwerden zu vergleichen.
(
complaints_and_pops
.to_pandas()
.plot.scatter(x="total_pop", y="total_complaints")
)

Beim Vergleich der Bevölkerung mit der Anzahl der Beschwerden scheinen einige Bundesstaaten Ausreißer zu sein. Es bleibt dem Leser überlassen, diese Punkte mit Punktlabels zu kennzeichnen. Stellen Sie außerdem einige Hypothesen auf, warum das so sein könnte (z.B. unterschiedliche demografische Merkmale, unterschiedliche Anzahl von Finanzdienstleistungsunternehmen usw.), und testen Sie sie.
5. Einbettungen berechnen
Häufig sind wichtige Informationen in unstrukturierten Daten wie Text, Audio oder Bildern verborgen. In diesem Beispiel sind viele der nützlichen Informationen in der Beschwerdedatenbank im Textinhalt der Beschwerde enthalten.
Mit KI und traditionellen Techniken wie der Stimmungsanalyse, „Bag of Words“ und Word2Vec lassen sich einige quantitative Informationen aus unstrukturierten Daten extrahieren. In jüngerer Zeit können Modelle für „Vektoreinbettung“, die eng mit LLMs verwandt sind, eine Folge von Gleitkommazahlen erstellen, die die semantischen Informationen von Text darstellen.
Untermenge der Datenbank auswählen
Für die Ausführung eines Vektoreinbettungsmodells werden mehr Ressourcen benötigt als für andere Vorgänge. Um Kosten und Kontingentprobleme zu reduzieren, wählen Sie für den Rest dieser Anleitung eine Teilmenge der Daten aus.
import bigframes.pandas as bpd
bpd.options.bigquery.ordering_mode = "partial"
feedback = bpd.read_gbq(
"bigquery-public-data.cfpb_complaints.complaint_database"
)
# Note: if not using ordering_mode = "partial", you must specify these in read_gbq
# for these to affect query efficiency.
# feedback = bpd.read_gbq(
# "bigquery-public-data.cfpb_complaints.complaint_database",
# columns=["consumer_complaint_narrative"],
# filters= [
# ("consumer_complaint_narrative", "!=", ""),
# ("date_received", "==", "2022-12-01")])
feedback.shape
Am 01.12.2022 wurden etwa 1.000 Beschwerden eingereicht, verglichen mit fast 3,5 Millionen Zeilen in der Gesamtdatenbank (siehe feedback.shape).
Wählen Sie nur die Daten für den 01.12.2022 und nur die Spalte consumer_complaint_narrative aus.
import datetime
feedback = feedback[
# Filter rows by passing in a boolean Series.
(feedback["date_received"] == datetime.date(2022, 12, 1))
& ~(feedback["date_received"].isnull())
& ~(feedback["consumer_complaint_narrative"].isnull())
& (feedback["consumer_complaint_narrative"] != "")
& (feedback["state"] == "CA")
# Uncomment the following if using free credits for a workshop.
# Billing accounts with free credits have limited Vertex AI quota.
# & (feedback["product"] == "Mortgage")
][
# Filter columns by passing in a list of strings.
["consumer_complaint_narrative"]
]
feedback.shape
Für die Methode drop_duplicates von pandas ist eine vollständige Sortierung der Zeilen erforderlich, da entweder die erste oder die letzte übereinstimmende Zeile ausgewählt und der zugehörige Index beibehalten wird.
Aggregieren Sie stattdessen mit einem Aufruf der Methode groupby, um Zeilen zu deduplizieren.
feedback = (
feedback.groupby("consumer_complaint_narrative", as_index=False)
.size()
)[["consumer_complaint_narrative"]]
feedback.shape
Einbettungen generieren
BigQuery DataFrames generiert Einbettungsvektoren über die TextEmbeddingGenerator-Klasse. Dies basiert auf der ML.GENERATE_EMBEDDING-Methode in BigQuery ML, die die von Vertex AI bereitgestellten Texteinbettungsmodelle aufruft.
from bigframes.ml.llm import TextEmbeddingGenerator
embedding_model = TextEmbeddingGenerator(
model_name="text-embedding-004"
)
feedback_embeddings = embedding_model.predict(feedback)
So sehen Einbettungen aus. Diese Vektoren stellen die semantische Bedeutung des Texts dar, wie sie vom Texteinbettungsmodell verstanden wird.
feedback_embeddings.peek()
Erwartete Ausgabe:
ml_generate_embedding_result \
0 [ 7.36380890e-02 2.11779331e-03 2.54309829e-...
1 [-1.10935252e-02 -5.53950183e-02 2.01338865e-...
2 [-7.85628427e-03 -5.39347418e-02 4.51385677e-...
3 [ 0.02013054 -0.0224789 -0.00164843 0.011354...
4 [-1.51684484e-03 -5.02693094e-03 1.72322839e-...
Diese Vektoren haben viele Dimensionen. Sehen Sie sich einen einzelnen Einbettungsvektor an:
feedback_embeddings["ml_generate_embedding_result"].peek().iloc[0]
Die Generierung von Embeddings erfolgt im Rahmen eines Vertrags mit „teilweisem Erfolg“. Das bedeutet, dass einige Zeilen möglicherweise Fehler enthalten und kein Einbettungsvektor generiert wird. Fehlermeldungen werden in der Spalte 'ml_generate_embedding_status' angezeigt. Ein leerer Wert bedeutet, dass keine Fehler vorliegen.
Filtern Sie die Einbettungen, sodass nur Zeilen ohne Fehler enthalten sind.
mask = feedback_embeddings["ml_generate_embedding_status"] == ""
valid_embeddings = feedback_embeddings[mask]
valid_embeddings.shape
6. Clustering mit Texteinbettungen
Clustern Sie die Einbettungen jetzt mit dem k-Means-Algorithmus. Verwenden Sie für diese Demo eine beliebige Anzahl von Gruppen (auch als Zentroiden bezeichnet). Bei einer Lösung in Produktionsqualität sollte die Anzahl der Zentroiden mit einer Technik wie der Silhouettenmethode optimiert werden.
from bigframes.ml.cluster import KMeans
num_clusters = 5
cluster_model = KMeans(n_clusters=num_clusters)
cluster_model.fit(valid_embeddings["ml_generate_embedding_result"])
clusters = cluster_model.predict(valid_embeddings)
clusters.peek()
Entfernen Sie alle Einbettungsfehler.
mask = clusters["ml_generate_embedding_status"] == ""
clusters = clusters[mask]
Sehen Sie sich die Verteilung der Kommentare pro Schwerpunkt an.
clusters.groupby("CENTROID_ID").size()
7. Cluster zusammenfassen
Geben Sie einige Kommentare ein, die mit jedem Schwerpunkt verbunden sind, und bitten Sie Gemini, die Beschwerden zusammenzufassen. Prompt Engineering ist ein aufstrebendes Gebiet, aber es gibt gute Beispiele im Internet, z. B. unter https://www.promptingguide.ai/.
from bigframes.ml.llm import GeminiTextGenerator
preamble = "What is the main concern in this list of user complaints:"
suffix = "Write the main issue using a formal tone."
# Now let's sample the raw comments and get the LLM to summarize them.
prompts = []
for centroid_id in range(1, num_clusters + 1):
cluster = clusters[clusters["CENTROID_ID"] == centroid_id]
comments = "\n".join(["- {0}".format(x) for x in cluster.content.peek(40)])
prompts.append("{}:\n{}\n{}".format(preamble, comments, suffix))
prompt_df = bpd.DataFrame(prompts)
gemini = GeminiTextGenerator(model_name="gemini-1.5-flash-001")
issues = gemini.predict(X=prompt_df, temperature=0.0)
issues.peek()
Mit Gemini einen Bericht aus den Zusammenfassungen erstellen
from IPython.display import display, Markdown
prompt = "Turn this list of issues into a short, concise report:"
for value in issues["ml_generate_text_llm_result"]:
prompt += "- {}".format(value)
prompt += "Using a formal tone, write a markdown text format report."
summary_df = bpd.DataFrame(([prompt]))
summary = gemini.predict(X=summary_df, temperature=0.0)
report = (summary["ml_generate_text_llm_result"].values[0])
display(Markdown(report))
8. Bereinigen
Wenn Sie für diese Anleitung ein neues Google Cloud-Projekt erstellt haben, können Sie es löschen, um zusätzliche Gebühren für erstellte Tabellen oder andere Ressourcen zu vermeiden.
9. Glückwunsch!
Sie haben strukturierte und unstrukturierte Daten mit BigQuery DataFrames analysiert. Dabei haben Sie die öffentlichen Datasets von Google Cloud, Python-Notebooks in BigQuery Studio, BigQuery ML, Vertex AI und die Funktionen für die Umwandlung von natürlicher Sprache in Python in BigQuery Studio kennengelernt. Fantastisch!
Nächste Schritte
- Python-Code in Ihrem Notebook generieren Python-Notebooks in BigQuery Studio basieren auf Colab Enterprise. Tipp: Ich finde es sehr hilfreich, um Unterstützung beim Generieren von Testdaten zu bitten.
- Beispiel-Notebooks für BigQuery DataFrames auf GitHub
- Planen Sie die Ausführung eines Notebooks in BigQuery Studio.
- Stellen Sie eine Remote-Funktion mit BigQuery DataFrames bereit, um Python-Drittanbieterpakete in BigQuery einzubinden.