1. Przegląd
W tym module użyjesz BigQuery DataFrames z notatnika Pythona w BigQuery Studio, aby uzyskać wgląd w dane za pomocą Pythona. Korzystaj z generatywnej AI od Google, aby analizować i wizualizować nieustrukturyzowane dane tekstowe.
Utworzysz notatnik w Pythonie, aby kategoryzować i podsumowywać publiczną bazę danych skarg klientów. Można go dostosować do pracy z dowolnymi nieustrukturyzowanymi danymi tekstowymi.
Cele
Z tego modułu nauczysz się, jak:
- Aktywowanie i używanie notatników w Pythonie w BigQuery Studio
- Łączenie z BigQuery za pomocą pakietu BigQuery DataFrames
- Tworzenie wektorów dystrybucyjnych tekstu z nieustrukturyzowanych danych tekstowych za pomocą BigQuery ML i połączenia z punktem końcowym wektora dystrybucyjnego tekstu w Vertex AI
- Grupowanie wektorów za pomocą BigQuery ML
- Podsumowywanie klastrów za pomocą LLM w BigQuery ML
2. Wymagania
Zanim zaczniesz
Aby wykonać instrukcje podane w tym samouczku, musisz mieć projekt Google Cloud z włączoną usługą BigQuery Studio i połączonym kontem rozliczeniowym.
- W konsoli Google Cloud na stronie selektora projektu wybierz lub utwórz projekt Google Cloud.
- Sprawdź, czy w projekcie Google Cloud włączone są płatności. Dowiedz się, jak sprawdzić, czy w projekcie włączone są płatności
- Postępuj zgodnie z instrukcjami, aby włączyć BigQuery Studio do zarządzania zasobami.
Przygotowywanie BigQuery Studio
Utwórz pusty notatnik i połącz go ze środowiskiem wykonawczym.
- W konsoli Google Cloud otwórz BigQuery Studio.
- Kliknij ▼ obok przycisku +.
- Wybierz Notatnik w Pythonie.
- Zamknij selektor szablonów.
- Aby utworzyć nową komórkę z kodem, kliknij + Kod.
- Zainstaluj najnowszą wersję pakietu BigQuery DataFrames z komórki kodu. Wpisz to polecenie:
Aby uruchomić komórkę kodu, kliknij przycisk 🞂 lub naciśnij Shift + Enter.%pip install --upgrade bigframes --quiet
3. Odczytywanie publicznego zbioru danych
Zainicjuj pakiet BigQuery DataFrames, uruchamiając w nowej komórce kodu to polecenie:
import bigframes.pandas as bpd
bpd.options.bigquery.ordering_mode = "partial"
Uwaga: w tym samouczku używamy eksperymentalnego „trybu częściowego porządkowania”, który w połączeniu z filtrowaniem podobnym do tego w bibliotece pandas umożliwia wykonywanie bardziej wydajnych zapytań. Niektóre funkcje biblioteki pandas, które wymagają ścisłego uporządkowania lub indeksowania, mogą nie działać.
Baza skarg konsumentów
Baza danych skarg konsumentów jest udostępniana w BigQuery w ramach programu publicznych zbiorów danych Google Cloud. Jest to zbiór skarg dotyczących produktów i usług finansowych dla konsumentów. Dane są zbierane przez amerykańskie Biuro Ochrony Finansowej Konsumentów.
W BigQuery wyślij zapytanie do tabeli bigquery-public-data.cfbp_complaints.complaint_database, aby przeanalizować bazę danych skarg konsumentów. Użyj metody bigframes.pandas.read_gbq(), aby utworzyć obiekt DataFrame na podstawie ciągu zapytania lub identyfikatora tabeli.
Aby utworzyć ramkę danych o nazwie „feedback”, uruchom w nowej komórce kodu to polecenie:
feedback = bpd.read_gbq(
"bigquery-public-data.cfpb_complaints.complaint_database"
)
Poznaj podstawowe informacje o obiekcie DataFrame
Aby pobrać małą próbkę danych, użyj metody DataFrame.peek().
Uruchom tę komórkę:
feedback.peek()
Oczekiwane dane wyjściowe:
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
Uwaga: head() wymaga uporządkowania i jest zwykle mniej wydajne niż peek(), jeśli chcesz wizualizować próbkę danych.
Podobnie jak w przypadku biblioteki pandas, użyj właściwości DataFrame.dtypes, aby wyświetlić wszystkie dostępne kolumny i odpowiadające im typy danych. Są one udostępniane w sposób zgodny z biblioteką pandas.
Uruchom tę komórkę:
feedback.dtypes
Oczekiwane dane wyjściowe:
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
Metoda DataFrame.describe() wysyła zapytanie o podstawowe statystyki z obiektu DataFrame. Ten obiekt DataFrame nie zawiera kolumn numerycznych, więc wyświetla podsumowanie liczby wartości niezerowych i liczby unikalnych wartości.
Uruchom tę komórkę:
# 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()
Oczekiwane dane wyjściowe:
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. Analizowanie danych
Zanim zaczniesz analizować konkretne skargi, użyj metod podobnych do tych z biblioteki pandas w obiekcie DataFrame, aby wizualizować dane.
Wizualizacja obiektu DataFrame
Istnieje kilka wbudowanych metod wizualizacji, takich jak DataFrame.plot.hist(). Ponieważ ten obiekt DataFrame zawiera głównie dane tekstowe i wartości logiczne, możemy najpierw przeprowadzić agregację, aby dowiedzieć się więcej o różnych kolumnach.
Policz, ile skarg wpłynęło z każdego stanu.
complaints_by_state = (
feedback.groupby(
"state", as_index=False,
).size()
.rename(columns={"size": "total_complaints"})
.sort_values(by="total_complaints", ascending=False)
)
Przekształć go w obiekt pandas DataFrame za pomocą metody DataFrame.to_pandas().
complaints_pd = complaints_by_state.head(10).to_pandas()
Użyj metod wizualizacji biblioteki pandas w pobranym obiekcie DataFrame.
complaints_pd.plot.bar(x="state", y="total_complaints")

Złączanie z innymi zbiorami danych
Wcześniej analizowaliśmy skargi w poszczególnych stanach, ale w ten sposób traciliśmy ważny kontekst. Niektóre stany mają większą populację niż inne. Połącz z zbiorem danych o populacji, takim jak American Community Survey amerykańskiego Biura Spisu Ludności i tabela bigquery-public-data.geo_us_boundaries.states.
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")
)
American Community Survey identyfikuje stany za pomocą GEOID. Połącz z tabelą stanów, aby uzyskać populację według dwuliterowego kodu stanu.
pops = us_states.set_index("geo_id")[["state"]].join(
us_survey.set_index("geo_id")[["total_pop"]]
)
Teraz połącz te dane z bazą danych skarg, aby porównać liczbę mieszkańców z liczbą skarg.
complaints_and_pops = complaints_by_state.set_index("state").join(
pops.set_index("state")
)
Utwórz wykres punktowy, aby porównać liczbę mieszkańców poszczególnych stanów z liczbą skarg.
(
complaints_and_pops
.to_pandas()
.plot.scatter(x="total_pop", y="total_complaints")
)

W przypadku kilku stanów widać odchylenia od normy, gdy porównamy liczbę mieszkańców z liczbą skarg. Pozostawiamy to jako ćwiczenie dla czytelnika, aby narysować wykres z etykietami punktów i zidentyfikować te wartości. Podobnie opracuj hipotezy dotyczące tego, dlaczego tak może być (np. różne dane demograficzne, różna liczba firm świadczących usługi finansowe itp.) i je przetestuj.
5. Obliczanie wektorów dystrybucyjnych
Ważne informacje są często ukryte w nieustrukturyzowanych danych, takich jak tekst, dźwięk czy obrazy. W tym przykładzie większość przydatnych informacji w bazie danych skarg znajduje się w tekście skargi.
AI i tradycyjne techniki, takie jak analiza nastawienia, „bag of words” i word2vec, mogą wyodrębniać z danych nieustrukturyzowanych informacje ilościowe. Ostatnio modele „osadzania wektorowego”, które są ściśle powiązane z LLM, mogą tworzyć sekwencję liczb zmiennoprzecinkowych reprezentujących informacje semantyczne tekstu.
Wybieranie podzbioru bazy danych
Uruchomienie modelu wektorów dystrybucyjnych zużywa więcej zasobów niż inne operacje. Aby zmniejszyć koszty i uniknąć problemów z limitami, wybierz podzbiór danych na potrzeby pozostałej części tego samouczka.
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
W dniu 1 grudnia 2022 r.przesłano około 1000 skarg, a w całej bazie danych jest prawie 3,5 miliona wierszy (sprawdź w feedback.shape).
Wybierz tylko dane z 1 grudnia 2022 r. i tylko kolumnę consumer_complaint_narrative.
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
Metoda drop_duplicates z biblioteki pandas wymaga całkowitego uporządkowania wierszy, ponieważ próbuje wybrać pierwszy lub ostatni pasujący wiersz i zachować powiązany z nim indeks.
Zamiast tego użyj agregacji z wywołaniem metody groupby, aby usunąć zduplikowane wiersze.
feedback = (
feedback.groupby("consumer_complaint_narrative", as_index=False)
.size()
)[["consumer_complaint_narrative"]]
feedback.shape
Generowanie wektorów dystrybucyjnych
BigQuery DataFrames generuje wektory osadzania za pomocą klasy TextEmbeddingGenerator. Jest to oparte na ML.GENERATE_EMBEDDINGmetodzie w BigQuery ML, która wywołuje modele wektorów dystrybucyjnych tekstu udostępniane przez Vertex AI.
from bigframes.ml.llm import TextEmbeddingGenerator
embedding_model = TextEmbeddingGenerator(
model_name="text-embedding-004"
)
feedback_embeddings = embedding_model.predict(feedback)
Zobacz, jak wyglądają wektory. Wektory te reprezentują znaczenie semantyczne tekstu w sposób, w jaki rozumie je model wektora dystrybucyjnego tekstu.
feedback_embeddings.peek()
Oczekiwane dane wyjściowe:
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-...
Wektory te mają wiele wymiarów. Przyjrzyj się pojedynczemu wektorowi dystrybucyjnemu:
feedback_embeddings["ml_generate_embedding_result"].peek().iloc[0]
Generowanie embeddingów działa na podstawie umowy „częściowe powodzenie”. Oznacza to, że niektóre wiersze mogą zawierać błędy i nie generować reprezentacji właściwościowych. Komunikaty o błędach są widoczne w kolumnie 'ml_generate_embedding_status'. Puste pole oznacza brak błędów.
Przefiltruj wektory, aby uwzględniały tylko wiersze, w których nie wystąpił błąd.
mask = feedback_embeddings["ml_generate_embedding_status"] == ""
valid_embeddings = feedback_embeddings[mask]
valid_embeddings.shape
6. Klastrowanie za pomocą wektorów dystrybucyjnych tekstu
Teraz pogrupuj wektory za pomocą algorytmu k-średnich. W tym przykładzie użyj dowolnej liczby grup (czyli centroidów). Rozwiązanie o jakości produkcyjnej powinno dostosowywać liczbę centroidów za pomocą techniki takiej jak metoda sylwetki.
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()
Usuń wszelkie błędy związane z osadzaniem.
mask = clusters["ml_generate_embedding_status"] == ""
clusters = clusters[mask]
Sprawdź rozkład komentarzy w poszczególnych centroidach.
clusters.groupby("CENTROID_ID").size()
7. Podsumuj klastry
Przekaż Gemini kilka komentarzy powiązanych z każdym centroidem i poproś Gemini o podsumowanie skarg. Inżynieria promptów to nowa dziedzina, ale w internecie można znaleźć dobre przykłady, np. na stronie 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()
Użyj Gemini do napisania raportu na podstawie podsumowań.
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. Czyszczenie danych
Jeśli na potrzeby tego samouczka został przez Ciebie utworzony nowy projekt w chmurze Google, możesz go usunąć, aby uniknąć dodatkowych opłat za utworzone tabele lub inne zasoby.
9. Gratulacje!
Analizujesz dane uporządkowane i nieuporządkowane za pomocą BigQuery DataFrames. Po drodze poznasz publiczne zbiory danych Google Cloud, notatniki w Pythonie w BigQuery Studio, BigQuery ML, Vertex AI i funkcje języka naturalnego w Pythonie w BigQuery Studio. Świetna robota!
Dalsze kroki
- Spróbuj wygenerować kod w Pythonie w notatniku. Notatniki w Pythonie w BigQuery Studio są oparte na Colab Enterprise. Wskazówka: proszenie o pomoc w generowaniu danych testowych jest bardzo przydatne.
- Zapoznaj się z przykładowymi notatnikami BigQuery DataFrames w GitHubie.
- Utwórz harmonogram uruchamiania notatnika w BigQuery Studio.
- Wdróż funkcję zdalną z BigQuery DataFrames, aby zintegrować pakiety Pythona innych firm z BigQuery.