Mit dem KI-fähigen BigQuery DataFrames-Paket Informationen aus strukturierten und unstrukturierten Daten gewinnen

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

  • Ein Browser, z. B. Chrome oder Firefox
  • Google Cloud-Projekt mit aktivierter Abrechnung

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.

  1. Wählen Sie in der Google Cloud Console auf der Seite der Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.
  2. Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein. So prüfen Sie, ob die Abrechnung für ein Projekt aktiviert ist
  3. 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.

  1. Rufen Sie in der Google Cloud Console BigQuery Studio auf.
  2. Klicken Sie auf das Dreipunkt-Menü  neben der Schaltfläche +.
  3. Wählen Sie Python-Notebook aus.
  4. Schließen Sie die Vorlagenauswahl.
  5. Wählen Sie + Code aus, um eine neue Codezelle zu erstellen.
  6. Installieren Sie die neueste Version des BigQuery DataFrames-Pakets über die Codezelle.Geben Sie dazu den folgenden Befehl ein.
    %pip install --upgrade bigframes --quiet
    
    Klicken Sie auf die Schaltfläche 🞂 oder drücken Sie die Umschalttaste + Eingabetaste, um die Codezelle auszuführen.

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")

Balkendiagramm mit Kalifornien als Bundesstaat mit den meisten Beschwerden

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")
)

ein Streudiagramm, in dem die Bevölkerung mit Beschwerden verglichen wird

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