با استفاده از بسته BigQuery DataFrames دارای قابلیت هوش مصنوعی، بینش را از داده‌های ساختاریافته و بدون ساختار با استفاده از بسته BigQuery DataFrames با قابلیت هوش مصنوعی دریافت کنید.

۱. مرور کلی

در این آزمایش، شما از BigQuery DataFrames از یک نوت‌بوک پایتون در BigQuery Studio برای کسب بینش از داده‌ها با استفاده از پایتون استفاده خواهید کرد. از هوش مصنوعی مولد گوگل برای تجزیه و تحلیل و تجسم داده‌های متنی بدون ساختار استفاده خواهید کرد.

شما یک دفترچه یادداشت پایتون برای دسته‌بندی و خلاصه‌سازی یک پایگاه داده شکایات عمومی مشتریان ایجاد خواهید کرد. این دفترچه می‌تواند برای کار بر روی هر داده متنی بدون ساختار تطبیق داده شود.

اهداف

در این آزمایشگاه، شما یاد می‌گیرید که چگونه وظایف زیر را انجام دهید:

  • فعال‌سازی و استفاده از نوت‌بوک‌های پایتون در BigQuery Studio
  • با استفاده از بسته BigQuery DataFrames به BigQuery متصل شوید
  • ایجاد جاسازی از داده‌های متنی بدون ساختار با استفاده از BigQuery ML و اتصال به یک نقطه پایانی جاسازی متن در Vertex AI
  • تعبیه‌های خوشه‌ای با استفاده از BigQuery ML
  • خلاصه‌سازی خوشه‌ها با LLM از طریق BigQuery ML

۲. الزامات

  • یک مرورگر، مانند کروم یا فایرفاکس
  • یک پروژه گوگل کلود با قابلیت پرداخت صورتحساب

قبل از اینکه شروع کنی

برای دنبال کردن دستورالعمل‌های این آزمایشگاه کد، به یک پروژه گوگل کلود با BigQuery Studio فعال و یک حساب پرداخت متصل نیاز دارید.

  1. در کنسول گوگل کلود ، در صفحه انتخاب پروژه، یک پروژه گوگل کلود را انتخاب یا ایجاد کنید
  2. مطمئن شوید که صورتحساب برای پروژه Google Cloud شما فعال است. یاد بگیرید که چگونه بررسی کنید که آیا صورتحساب در یک پروژه فعال است یا خیر
  3. دستورالعمل‌ها را برای فعال کردن BigQuery Studio برای مدیریت دارایی دنبال کنید.

آماده‌سازی استودیوی BigQuery

یک دفترچه یادداشت خالی ایجاد کنید و آن را به یک محیط اجرا متصل کنید.

  1. در کنسول گوگل کلود به BigQuery Studio بروید.
  2. روی علامت کنار دکمه + کلیک کنید.
  3. دفترچه یادداشت پایتون را انتخاب کنید.
  4. انتخابگر قالب را ببندید.
  5. برای ایجاد یک سلول کد جدید ، + Code را انتخاب کنید.
  6. آخرین نسخه از بسته BigQuery DataFrames را از طریق کد نصب کنید. دستور زیر را تایپ کنید.
    %pip install --upgrade bigframes --quiet
    
    برای اجرای سلول کد، روی دکمه 🞂 کلیک کنید یا Shift + Enter را فشار دهید.

۳. خواندن یک مجموعه داده عمومی

با اجرای دستور زیر در یک سلول کد جدید، بسته BigQuery DataFrames را مقداردهی اولیه کنید:

import bigframes.pandas as bpd

bpd.options.bigquery.ordering_mode = "partial"

توجه: در این آموزش، ما از حالت آزمایشی «مرتب‌سازی جزئی» استفاده می‌کنیم که امکان پرس‌وجوهای کارآمدتری را در هنگام استفاده با فیلترینگ مشابه پانداس فراهم می‌کند. برخی از ویژگی‌های پانداس که نیاز به مرتب‌سازی دقیق یا اندیس‌گذاری دارند، ممکن است کار نکنند.

پایگاه داده شکایات مصرف‌کنندگان

پایگاه داده شکایات مصرف‌کنندگان از طریق برنامه مجموعه داده‌های عمومی گوگل کلود در BigQuery ارائه می‌شود. این مجموعه شامل شکایات مربوط به محصولات و خدمات مالی مصرف‌کنندگان است و داده‌ها توسط دفتر حمایت مالی مصرف‌کنندگان ایالات متحده جمع‌آوری می‌شوند.

در BigQuery، برای تجزیه و تحلیل پایگاه داده شکایات مصرف‌کنندگان، جدول bigquery-public-data.cfbp_complaints.complaint_database را جستجو کنید. از متد bigframes.pandas.read_gbq() برای ایجاد یک DataFrame از یک رشته پرس و جو یا شناسه جدول استفاده کنید.

برای ایجاد یک DataFrame با نام "feedback" کد زیر را در یک سلول کد جدید اجرا کنید:

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

اطلاعات اولیه در مورد یک DataFrame را کشف کنید

از متد DataFrame.peek() برای دانلود نمونه کوچکی از داده‌ها استفاده کنید.

این سلول را اجرا کنید:

feedback.peek()

خروجی مورد انتظار:

  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   

نکته: head() نیاز به مرتب‌سازی دارد و اگر بخواهید نمونه‌ای از داده‌ها را مصورسازی کنید، عموماً نسبت به peek() کارایی کمتری دارد.

درست مانند پانداس، از ویژگی DataFrame.dtypes برای مشاهده تمام ستون‌های موجود و انواع داده‌های مربوط به آنها استفاده کنید. این موارد به روشی سازگار با پانداس نمایش داده می‌شوند.

این سلول را اجرا کنید:

feedback.dtypes

خروجی مورد انتظار:

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

متد DataFrame.describe() برخی از آمارهای اولیه را از DataFrame پرس‌وجو می‌کند. از آنجایی که این DataFrame حاوی هیچ ستون عددی نیست، خلاصه‌ای از تعداد مقادیر غیر تهی و تعداد مقادیر متمایز را نشان می‌دهد.

این سلول را اجرا کنید:

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

خروجی مورد انتظار:

         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

۴. کاوش داده‌ها

قبل از اینکه به بررسی شکایات واقعی بپردازیم، از متدهای شبیه پانداس در DataFrame برای تجسم داده‌ها استفاده کنید.

تجسم DataFrame

چندین متد تجسم‌سازی داخلی مانند DataFrame.plot.hist() وجود دارد. از آنجایی که این DataFrame عمدتاً حاوی داده‌های رشته‌ای و بولی است، می‌توانیم ابتدا کمی تجمیع انجام دهیم تا درباره ستون‌های مختلف اطلاعات بیشتری کسب کنیم.

تعداد شکایات دریافتی از هر ایالت را بشمارید.

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

این را با استفاده از متد DataFrame.to_pandas() به یک دیتافریم pandas تبدیل کنید.

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

از روش‌های مصورسازی پانداس روی این DataFrame دانلود شده استفاده کنید.

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

نمودار میله‌ای که کالیفرنیا را به عنوان ایالتی با بیشترین شکایات نشان می‌دهد

با مجموعه داده‌های دیگر ادغام کنید

قبلاً، شما شکایات را بر اساس ایالت بررسی می‌کردید، اما این مورد، زمینه‌ی مهم را از دست می‌دهد. برخی ایالت‌ها جمعیت بیشتری نسبت به سایرین دارند. با یک مجموعه داده‌ی جمعیتی مانند «نظرسنجی جامعه‌ی آمریکایی» اداره‌ی سرشماری ایالات متحده و جدول 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")
)

«بررسی جامعه آمریکایی» ایالت‌ها را بر اساس GEOID مشخص می‌کند. برای بدست آوردن جمعیت بر اساس کد دو حرفی ایالت، آن را به جدول ایالت‌ها اضافه کنید.

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

حالا، این را به پایگاه داده شکایات اضافه کنید تا جمعیت را با تعداد شکایات مقایسه کنید.

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

یک نمودار پراکندگی برای مقایسه جمعیت ایالت‌ها با تعداد شکایات ایجاد کنید.

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

نمودار پراکندگی که جمعیت را با شکایات مقایسه می‌کند

به نظر می‌رسد که چند ایالت هنگام مقایسه جمعیت با تعداد شکایات، داده‌های پرت هستند. به عنوان تمرین، به خواننده واگذار می‌شود تا با برچسب‌های نقطه‌ای، این موارد را شناسایی کند. به همین ترتیب، چند فرضیه برای چرایی این موضوع ارائه دهید (مثلاً جمعیت‌شناسی متفاوت، تعداد متفاوت شرکت‌های خدمات مالی و غیره) و آنها را آزمایش کنید.

۵. محاسبه‌ی جایگذاری‌ها

اغلب، اطلاعات مهم در داده‌های بدون ساختار، مانند متن، صدا یا تصاویر پنهان هستند. در این مثال، بسیاری از اطلاعات مفید در پایگاه داده شکایات، در محتوای متنی شکایت موجود است.

هوش مصنوعی و تکنیک‌های سنتی، مانند تحلیل احساسات، «bag of words» و word2vec، می‌توانند برخی از اطلاعات کمی را از داده‌های بدون ساختار استخراج کنند. اخیراً، مدل‌های «تعبیه برداری» که ارتباط نزدیکی با LLMها دارند، می‌توانند دنباله‌ای از اعداد ممیز شناور ایجاد کنند که نشان‌دهنده اطلاعات معنایی متن است.

انتخاب زیرمجموعه‌ای از پایگاه داده

اجرای یک مدل تعبیه برداری نسبت به سایر عملیات‌ها از منابع بیشتری استفاده می‌کند. برای کاهش هزینه‌ها و مشکلات سهمیه‌بندی، زیرمجموعه‌ای از داده‌ها را برای ادامه این آموزش انتخاب کنید.

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

حدود ۱۰۰۰ شکایت در تاریخ ۲۰۲۲-۱۲-۰۱ ثبت شده است، در مقایسه با تقریباً ۳.۵ میلیون ردیف در کل پایگاه داده (با feedback.shape بررسی کنید).

فقط داده‌های مربوط به تاریخ ۲۰۲۲-۱۲-۰۱ و فقط ستون 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

متد drop_duplicates از pandas نیاز به مرتب‌سازی کلی ردیف‌ها دارد زیرا سعی می‌کند اولین یا آخرین ردیف منطبق را انتخاب کرده و اندیس مرتبط با آن را حفظ کند.

در عوض، با فراخوانی متد groupby برای حذف ردیف‌های تکراری، آنها را تجمیع کنید.

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

feedback.shape

ایجاد جاسازی‌ها

BigQuery DataFrames بردارهای جاسازی را از طریق کلاس TextEmbeddingGenerator تولید می‌کند. این بر اساس متد ML.GENERATE_EMBEDDING در BigQuery ML است که مدل‌های جاسازی متن ارائه شده توسط Vertex AI را فراخوانی می‌کند.

from bigframes.ml.llm import TextEmbeddingGenerator

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

نگاهی به شکل جاسازی‌ها بیندازید. این بردارها، معنای معنایی متن را آنطور که توسط مدل جاسازی متن درک می‌شود، نشان می‌دهند.

feedback_embeddings.peek()

خروجی مورد انتظار:

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

این بردارها ابعاد زیادی دارند. به یک بردار جاسازی‌شده نگاهی بیندازید:

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

تولید جاسازی‌ها تحت قرارداد "موفقیت نسبی" عمل می‌کند. این بدان معناست که برخی از ردیف‌ها ممکن است خطا داشته باشند و جاسازی ایجاد نکنند. پیام‌های خطا توسط ستون 'ml_generate_embedding_status' نمایش داده می‌شوند. خالی به معنای بدون خطا است.

جاسازی‌ها را فیلتر کنید تا فقط ردیف‌هایی را شامل شوند که در آنها خطایی رخ نداده است.

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

۶. خوشه‌بندی با استفاده از جاسازی‌های متنی

حالا، با استفاده از k-means، جاسازی‌ها را خوشه‌بندی کنید. برای این نسخه آزمایشی، از تعداد دلخواهی از گروه‌ها (که به آنها مرکزوار هم می‌گویند) استفاده کنید. یک راه‌حل با کیفیت تولید باید تعداد مرکزوارها را با استفاده از تکنیکی مانند روش 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()

هرگونه خطای جاسازی را حذف کنید.

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

نگاهی بیندازید و توزیع نظرات را در هر مرکز ثقل مشاهده کنید.

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

۷. خوشه‌ها را خلاصه کنید

نظرات مربوط به هر مرکز ثقل را ارسال کنید و از Gemini بخواهید که شکایات را خلاصه کند. مهندسی سریع یک حوزه نوظهور است، اما نمونه‌های خوبی در اینترنت وجود دارد، مانند 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()

از جمینی برای نوشتن گزارش از خلاصه‌ها استفاده کنید.

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

۸. تمیز کردن

اگر برای این آموزش یک پروژه جدید Google Cloud ایجاد کرده‌اید، می‌توانید آن را حذف کنید تا از هزینه‌های اضافی برای جداول یا سایر منابع ایجاد شده جلوگیری شود.

۹. تبریک می‌گویم!

شما داده‌های ساختاریافته و بدون ساختار را با استفاده از BigQuery DataFrames تجزیه و تحلیل کرده‌اید. در طول مسیر، مجموعه داده‌های عمومی Google Cloud، دفترچه‌های پایتون در BigQuery Studio، BigQuery ML، Vertex AI و ویژگی‌های تبدیل زبان طبیعی به پایتون در BigQuery Studio را بررسی کرده‌اید. کار فوق‌العاده‌ای انجام داده‌اید!

مراحل بعدی