Dapatkan insight dari data terstruktur dan tidak terstruktur menggunakan paket BigQuery DataFrames yang kompatibel dengan AI

1. Ringkasan

Di lab ini, Anda akan menggunakan BigQuery DataFrames dari notebook Python di BigQuery Studio untuk mendapatkan insight dari data menggunakan Python. Manfaatkan AI generatif Google untuk menganalisis dan memvisualisasikan data teks tidak terstruktur.

Anda akan membuat notebook Python untuk mengategorikan dan meringkas database keluhan pelanggan publik. Fungsi ini dapat disesuaikan untuk digunakan pada data teks tidak terstruktur.

Tujuan

Di lab ini, Anda akan mempelajari cara melakukan tugas berikut:

  • Mengaktifkan dan menggunakan notebook Python di BigQuery Studio
  • Menghubungkan ke BigQuery menggunakan paket BigQuery DataFrames
  • Membuat penyematan dari data teks tidak terstruktur menggunakan BigQuery ML dan koneksi ke endpoint penyematan teks di Vertex AI
  • Penyematan cluster menggunakan BigQuery ML
  • Meringkas cluster dengan LLM melalui BigQuery ML

2. Persyaratan

  • Browser, seperti Chrome atau Firefox
  • Project Google Cloud yang mengaktifkan penagihan

Sebelum memulai

Untuk mengikuti petunjuk dalam codelab ini, Anda memerlukan Project Google Cloud dengan BigQuery Studio yang diaktifkan dan akun penagihan yang terhubung.

  1. Di Konsol Google Cloud, di halaman pemilih project, pilih atau buat project Google Cloud
  2. Pastikan penagihan diaktifkan untuk project Google Cloud Anda. Pelajari cara memeriksa apakah penagihan telah diaktifkan pada suatu project
  3. Ikuti petunjuk untuk Mengaktifkan BigQuery Studio untuk pengelolaan aset.

Menyiapkan BigQuery Studio

Buat notebook kosong dan hubungkan ke runtime.

  1. Buka BigQuery Studio di Konsol Google Cloud.
  2. Klik di samping tombol +.
  3. Pilih Python notebook.
  4. Tutup pemilih template.
  5. Pilih + Kode untuk membuat sel kode baru.
  6. Instal paket BigQuery DataFrames versi terbaru dari sel kode.Ketik perintah berikut.
    %pip install --upgrade bigframes --quiet
    
    Klik tombol 🞂 atau tekan Shift + Enter untuk menjalankan sel kode.

3. Membaca set data publik

Lakukan inisialisasi paket BigQuery DataFrames dengan menjalankan kode berikut di sel kode baru:

import bigframes.pandas as bpd

bpd.options.bigquery.ordering_mode = "partial"

Catatan: dalam tutorial ini, kita menggunakan "mode pengurutan parsial" eksperimental, yang memungkinkan kueri yang lebih efisien saat digunakan dengan pemfilteran seperti pandas. Beberapa fitur pandas yang memerlukan pengurutan atau indeks yang ketat mungkin tidak berfungsi.

Database Keluhan Konsumen

Database Keluhan Konsumen disediakan di BigQuery melalui program set data publik Google Cloud. Ini adalah kumpulan keluhan tentang produk dan layanan keuangan konsumen, dan datanya dikumpulkan oleh Consumer Financial Protection Bureau Amerika Serikat.

Di BigQuery, buat kueri tabel bigquery-public-data.cfbp_complaints.complaint_database untuk menganalisis Database Keluhan Konsumen. Gunakan metode bigframes.pandas.read_gbq() untuk membuat DataFrame dari string kueri atau ID tabel.

Jalankan kode berikut di sel kode baru untuk membuat DataFrame bernama "feedback":

feedback = bpd.read_gbq(
    "bigquery-public-data.cfpb_complaints.complaint_database"
)

Menemukan informasi dasar tentang DataFrame

Gunakan metode DataFrame.peek() untuk mendownload sampel kecil data.

Jalankan sel ini:

feedback.peek()

Output yang diharapkan:

  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   

Catatan: head() memerlukan pengurutan dan umumnya kurang efisien daripada peek() jika Anda ingin memvisualisasikan sampel data.

Sama seperti pandas, gunakan properti DataFrame.dtypes untuk melihat semua kolom yang tersedia dan jenis data yang sesuai. Data ini ditampilkan dengan cara yang kompatibel dengan pandas.

Jalankan sel ini:

feedback.dtypes

Output yang diharapkan:

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

Metode DataFrame.describe() membuat kueri beberapa statistik dasar dari DataFrame. Karena tidak berisi kolom numerik, DataFrame ini menampilkan ringkasan jumlah nilai non-null dan jumlah nilai yang berbeda.

Jalankan sel ini:

# 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()

Output yang diharapkan:

         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. Menjelajahi data

Sebelum melihat keluhan yang sebenarnya, gunakan metode seperti pandas pada DataFrame untuk memvisualisasikan data.

Memvisualisasikan DataFrame

Ada beberapa metode visualisasi bawaan seperti DataFrame.plot.hist(). Karena DataFrame ini sebagian besar berisi data string dan boolean, kita dapat melakukan beberapa agregasi terlebih dahulu untuk mempelajari lebih lanjut berbagai kolom.

Hitung jumlah keluhan yang diterima dari setiap negara bagian.

complaints_by_state = (
  feedback.groupby(
    "state", as_index=False,
  ).size()
  .rename(columns={"size": "total_complaints"})
  .sort_values(by="total_complaints", ascending=False)
)

Konversikan ini ke DataFrame pandas menggunakan metode DataFrame.to_pandas().

complaints_pd = complaints_by_state.head(10).to_pandas()

Gunakan metode visualisasi pandas pada DataFrame yang didownload ini.

complaints_pd.plot.bar(x="state", y="total_complaints")

diagram batang yang menunjukkan California sebagai negara bagian dengan keluhan terbanyak

Menggabungkan dengan set data lain

Sebelumnya, Anda melihat keluhan per negara bagian, tetapi hal ini menghilangkan konteks penting. Beberapa negara bagian memiliki populasi yang lebih besar daripada yang lain. Gabungkan dengan set data populasi seperti Survei Komunitas Amerika (ACS) dari Biro Sensus Amerika Serikat dan tabel 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 mengidentifikasi negara bagian berdasarkan GEOID. Gabungkan dengan tabel negara bagian untuk mendapatkan populasi berdasarkan kode negara bagian dua huruf.

pops = us_states.set_index("geo_id")[["state"]].join(
  us_survey.set_index("geo_id")[["total_pop"]]
)

Sekarang, gabungkan ini ke database keluhan untuk membandingkan populasi dengan jumlah keluhan.

complaints_and_pops = complaints_by_state.set_index("state").join(
    pops.set_index("state")
)

Buat diagram pencar untuk membandingkan populasi negara bagian dengan jumlah keluhan.

(
  complaints_and_pops
  .to_pandas()
  .plot.scatter(x="total_pop", y="total_complaints")
)

diagram sebar yang membandingkan populasi dengan keluhan

Beberapa negara bagian tampaknya merupakan outlier saat membandingkan populasi dengan jumlah keluhan. Hal ini dibiarkan sebagai latihan bagi pembaca untuk memetakan dengan label titik untuk mengidentifikasinya. Demikian pula, buat beberapa hipotesis tentang penyebabnya (misalnya, demografi yang berbeda, jumlah perusahaan jasa keuangan yang berbeda, dll.) dan uji hipotesis tersebut.

5. Menghitung penyematan

Sering kali, informasi penting tersembunyi dalam data tidak terstruktur, seperti teks, audio, atau gambar. Dalam contoh ini, sebagian besar informasi yang berguna dalam database keluhan terdapat dalam konten teks keluhan.

AI dan teknik tradisional, seperti analisis sentimen, "bag of words", dan word2vec, dapat mengekstrak beberapa informasi kuantitatif dari data tidak terstruktur. Baru-baru ini, model "vector embedding", yang terkait erat dengan LLM, dapat membuat urutan bilangan floating point yang mewakili informasi semantik teks.

Memilih subset database

Menjalankan model penyematan vektor menggunakan lebih banyak resource daripada operasi lainnya. Untuk mengurangi biaya dan masalah kuota, pilih sebagian data untuk tutorial ini.

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

Ada sekitar 1.000 keluhan yang dikirimkan pada 01-12-2022 dibandingkan dengan hampir 3,5 juta baris dalam total database (periksa dengan feedback.shape).

Pilih hanya data untuk 01-12-2022 dan hanya kolom 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

Metode drop_duplicates dari pandas memerlukan pengurutan total baris karena mencoba memilih baris pertama atau terakhir yang cocok dan mempertahankan indeks yang terkait dengannya.

Sebagai gantinya, gabungkan dengan panggilan ke metode groupby untuk menghapus duplikat baris.

feedback = (
  feedback.groupby("consumer_complaint_narrative", as_index=False)
  .size()
)[["consumer_complaint_narrative"]]

feedback.shape

Membuat embedding

BigQuery DataFrames menghasilkan vektor penyematan melalui class TextEmbeddingGenerator. Hal ini didasarkan pada metode ML.GENERATE_EMBEDDING, di BigQuery ML yang memanggil model penyematan teks yang disediakan oleh Vertex AI.

from bigframes.ml.llm import TextEmbeddingGenerator

embedding_model = TextEmbeddingGenerator(
    model_name="text-embedding-004"
)
feedback_embeddings = embedding_model.predict(feedback)

Lihat tampilan penyematan. Vektor ini mewakili makna semantik teks seperti yang dipahami oleh model embedding teks.

feedback_embeddings.peek()

Output yang diharapkan:

                        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-...   

Vektor ini memiliki banyak dimensi. Lihat satu vektor penyematan:

feedback_embeddings["ml_generate_embedding_result"].peek().iloc[0]

Pembuatan penyematan beroperasi berdasarkan kontrak "keberhasilan sebagian". Artinya, beberapa baris mungkin mengalami error dan tidak menghasilkan penyematan. Pesan error ditampilkan oleh kolom 'ml_generate_embedding_status'. Kosong berarti tidak ada error.

Filter penyematan untuk hanya menyertakan baris yang tidak mengalami error.

mask = feedback_embeddings["ml_generate_embedding_status"] == ""
valid_embeddings = feedback_embeddings[mask]
valid_embeddings.shape

6. Membuat cluster menggunakan embedding teks

Sekarang, buat cluster penyematan menggunakan k-means. Untuk demo ini, gunakan jumlah grup arbitrer (alias centroid). Solusi berkualitas produksi harus menyesuaikan jumlah centroid menggunakan teknik seperti metode Silhouette.

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

Hapus semua kegagalan penyematan.

mask = clusters["ml_generate_embedding_status"] == ""
clusters = clusters[mask]

Lihat sekilas dan lihat distribusi komentar per centroid.

clusters.groupby("CENTROID_ID").size()

7. Meringkas cluster

Masukkan beberapa komentar yang terkait dengan setiap centroid dan minta Gemini untuk meringkas keluhan. Rekayasa perintah adalah bidang yang baru muncul, tetapi ada contoh yang bagus di Internet, seperti 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()

Gunakan Gemini untuk menulis laporan dari ringkasan.

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. Pembersihan

Jika telah membuat project Google Cloud baru untuk tutorial ini, Anda dapat menghapusnya untuk mencegah tagihan tambahan untuk tabel atau resource lain yang dibuat.

9. Selamat!

Anda telah menganalisis data terstruktur dan tidak terstruktur menggunakan DataFrame BigQuery. Selama prosesnya, Anda telah menjelajahi Set Data Publik Google Cloud, notebook Python di BigQuery Studio, BigQuery ML, Vertex AI, dan fitur natural language ke Python di BigQuery Studio. Hebat!

Langkah berikutnya