1. Übersicht
In diesem Lab verwenden Sie BigQuery DataFrames aus einem Python-Notebook in BigQuery Studio, um mit Python Statistiken zu erstellen. Mit der generativen KI von Google können Sie unstrukturierte Textdaten analysieren und visualisieren.
Sie erstellen ein Python-Notebook, um eine öffentliche Datenbank mit Kundenbeschwerden zu kategorisieren und zusammenzufassen. Dieser Ansatz kann für alle unstrukturierten Textdaten angepasst werden.
Zielsetzungen
Aufgaben in diesem Lab:
- Python-Notebooks in BigQuery Studio aktivieren und verwenden
- Mit dem BigQuery DataFrames-Paket eine Verbindung zu BigQuery herstellen
- Mit BigQuery ML und einer Verbindung zu einem Text-Embedding-Endpunkt in Vertex AI Einbettungen aus unstrukturierten Textdaten erstellen
- Cluster-Embeddings mit BigQuery ML
- Cluster mit einem LLM über BigQuery ML zusammenfassen
2. Voraussetzungen
Hinweis
Um der Anleitung in diesem Codelab zu folgen, 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 der 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
Erstellen Sie ein leeres Notebook und verbinden Sie es mit einer Laufzeit.
- Rufen Sie in der Google Cloud Console BigQuery Studio auf.
- Klicken Sie auf das Dreipunkt-Menü ▼ neben der Schaltfläche +.
- 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 dazu den folgenden Befehl ein.
Klicken Sie auf die Schaltfläche 🞂 oder drücken Sie die Umschalttaste + 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 dieser Anleitung verwenden wir den experimentellen „Teilsortierungsmodus“, der effizientere Abfragen ermöglicht, wenn er mit einem Pandas-ähnlichen Filter verwendet wird. Einige Pandas-Funktionen, für die eine strenge Sortierung oder ein Index erforderlich ist, funktionieren möglicherweise nicht.
Datenbank mit Verbraucherbeschwerden
Die Datenbank mit Verbraucherbeschwerden wird in BigQuery über das Programm für öffentliche Datasets von Google Cloud bereitgestellt. Dies ist eine Sammlung von Beschwerden zu Finanzprodukten und ‑dienstleistungen für Verbraucher. Die Daten werden vom US-amerikanischen Consumer Financial Protection Bureau erhoben.
Stellen Sie in BigQuery eine Abfrage für die Tabelle bigquery-public-data.cfbp_complaints.complaint_database, 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
Verwenden Sie die Methode DataFrame.peek()
, um eine kleine Stichprobe der Daten herunterzuladen.
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.
Genau wie bei Pandas können Sie mit der Property DataFrame.dtypes
alle verfügbaren Spalten und ihre zugehörigen Datentypen aufrufen. Sie werden in einer pandas-kompatiblen 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 ohne Nullen 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, sollten Sie die Pandas-ähnlichen Methoden auf dem DataFrame verwenden, um die Daten zu 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 Bundesländern 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 diese mit der Methode DataFrame.to_pandas()
in einen Pandas-DataFrame.
complaints_pd = complaints_by_state.head(10).to_pandas()
Verwenden Sie Pandas-Visualisierungsmethoden auf diesem heruntergeladenen DataFrame.
complaints_pd.plot.bar(x="state", y="total_complaints")
Zusammenführen mit anderen Datasets
Bisher haben Sie sich Beschwerden nach Bundesstaat angesehen, aber dabei geht wichtiger Kontext verloren. Einige Bundesstaaten haben mehr Einwohner als andere. Führen Sie eine Zusammenführung mit einem Bevölkerungs-Dataset wie der American Community Survey des US Census Bureau und der bigquery-public-data.geo_us_boundaries.states
-Tabelle durch.
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")
)
Im American Community Survey werden Bundesstaaten anhand des GEOID identifiziert. Führen Sie eine Zusammenführung mit der Tabelle „states“ durch, um die Bevölkerung nach dem zweistelligen Code des Bundesstaats zu erhalten.
pops = us_states.set_index("geo_id")[["state"]].join(
us_survey.set_index("geo_id")[["total_pop"]]
)
Führen Sie nun eine Zusammenführung mit der Datenbank mit Beschwerden durch, um die Bevölkerungszahl 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ölkerungszahl der Bundesländer mit der Anzahl der Beschwerden zu vergleichen.
(
complaints_and_pops
.to_pandas()
.plot.scatter(x="total_pop", y="total_complaints")
)
Einige Bundesländer scheinen Ausreißer zu sein, wenn die Bevölkerung mit der Anzahl der Beschwerden verglichen wird. Es bleibt dem Leser überlassen, diese mit Punktlabels zu identifizieren. Erstellen Sie auch einige Hypothesen dazu, warum das der Fall sein könnte (z.B. unterschiedliche demografische Merkmale, unterschiedliche Anzahl von Finanzdienstleistungsunternehmen usw.) und testen Sie sie.
5. Einbettungen berechnen
Oft sind wichtige Informationen in unstrukturierten Daten wie Text, Audio oder Bildern versteckt. In diesem Beispiel sind viele der nützlichen Informationen in der Beschwerdedatenbank im Textinhalt der Beschwerde enthalten.
Mithilfe von KI und traditionellen Verfahren wie der Stimmungsanalyse, dem „Bag of Words“-Verfahren und Word2Vec können aus unstrukturierten Daten einige quantitative Informationen extrahiert werden. In letzter Zeit können Modelle für „Vektor-Embeddings“, die eng mit LLMs verwandt sind, eine Sequenz von Gleitkommazahlen erstellen, die die semantischen Informationen von Text repräsentieren.
Untermenge der Datenbank auswählen
Das Ausführen eines Vektoreinbettungsmodells beansprucht mehr Ressourcen als andere Vorgänge. Wählen Sie für den Rest dieser Anleitung eine Teilmenge der Daten aus, um Kosten und Kontingentprobleme zu vermeiden.
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. Die Datenbank enthält insgesamt fast 3,5 Millionen Zeilen (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
Die Methode drop_duplicates
von pandas erfordert eine vollständige Sortierung der Zeilen, da versucht wird, entweder die erste oder die letzte übereinstimmende Zeile auszuwählen und den zugehörigen Index beizubehalten.
Verwenden Sie stattdessen einen 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
In BigQuery DataFrames werden Einbettungsvektoren über die Klasse „TextEmbeddingGenerator“ generiert. Diese Funktion 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 repräsentieren die semantische Bedeutung des Texts, wie sie vom Text-Embedding-Modell 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 wir uns einen einzelnen Einbettungsvektor an:
feedback_embeddings["ml_generate_embedding_result"].peek().iloc[0]
Die Erstellung von Einbettungen erfolgt im Rahmen eines Vertrags mit teilweisem Erfolg. Das bedeutet, dass einige Zeilen möglicherweise Fehler enthalten und keine Einbettung generieren. Fehlermeldungen werden in der Spalte 'ml_generate_embedding_status'
angezeigt. Ein leeres Feld bedeutet, dass keine Fehler vorliegen.
Filtern Sie die Einbettungen so, dass nur Zeilen enthalten sind, in denen kein Fehler aufgetreten ist.
mask = feedback_embeddings["ml_generate_embedding_status"] == ""
valid_embeddings = feedback_embeddings[mask]
valid_embeddings.shape
6. Mit Texteinbettungen clustern
Clustern Sie die Einbettungen jetzt mit k-Means. Verwenden Sie für diese Demo eine beliebige Anzahl von Gruppen (auch als Centroide bezeichnet). Bei einer Lösung mit Produktionsqualität sollte die Anzahl der Centroide mithilfe einer Methode 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 Fehler beim Einbetten.
mask = clusters["ml_generate_embedding_status"] == ""
clusters = clusters[mask]
Sehen Sie sich die Verteilung der Kommentare pro Centroid an.
clusters.groupby("CENTROID_ID").size()
7. Cluster zusammenfassen
Geben Sie einige Kommentare zu den einzelnen Centroiden ein und bitten Sie Gemini, die Beschwerden zusammenzufassen. Prompt Engineering ist ein neues Gebiet, aber es gibt gute Beispiele im Internet, z. B. 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 Kosten 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
- Versuchen Sie, Python-Code in Ihrem Notebook zu generieren. Python-Notebooks in BigQuery Studio basieren auf Colab Enterprise. Hinweis: Ich finde es sehr hilfreich, um Hilfe beim Erstellen von Testdaten zu bitten.
- Beispiel-Notebooks für BigQuery DataFrames auf GitHub
- Erstellen Sie einen Zeitplan zum Ausführen eines Notebooks in BigQuery Studio.
- Sie können eine Remote-Funktion mit BigQuery DataFrames bereitstellen, um Python-Pakete von Drittanbietern in BigQuery zu integrieren.