الحصول على إحصاءات من البيانات المهيكلة وغير المهيكلة باستخدام حزمة BigQuery DataFrames المتوافقة مع الذكاء الاصطناعي

1. نظرة عامة

في هذا التمرين العملي، ستستخدم إطارات بيانات BigQuery من دفتر ملاحظات Python في BigQuery Studio للحصول على إحصاءات من البيانات باستخدام Python. استخدِم تكنولوجيات الذكاء الاصطناعي التوليدي من Google لتحليل البيانات النصية غير المنظَّمة وعرضها بشكل مرئي.

ستنشئ دفتر ملاحظات Python لتصنيف قاعدة بيانات الشكاوى العامة للعملاء وتلخيصها. ويمكن تعديل هذا الإجراء للعمل على أي بيانات نصية غير منظَّمة.

الأهداف

في هذه الميزة الاختبارية، ستتعرّف على كيفية تنفيذ المهام التالية:

  • تفعيل دفاتر ملاحظات Python واستخدامها في BigQuery Studio
  • الربط بخدمة BigQuery باستخدام حزمة BigQuery DataFrames
  • إنشاء نماذج إدراج من بيانات نصية غير منظَّمة باستخدام BigQuery ML والربط بنقطة نهاية إدراج نص في Vertex AI
  • إدراجات المجموعات باستخدام BigQuery ML
  • تلخيص المجموعات باستخدام نموذج تعلُّم لغوي كبير (LLM) من خلال ميزة "تعلُّم الآلة" في BigQuery

2. المتطلبات

  • متصفّح، مثل Chrome أو Firefox
  • مشروع على Google Cloud تم تفعيل الفوترة فيه

قبل البدء

اتّباع التعليمات الواردة في هذا الدليل التعليمي حول رموز البرامج، ستحتاج إلى مشروع على Google Cloud تم تفعيل BigQuery Studio فيه وحساب فوترة مرتبط.

  1. في Google Cloud Console، اختَر مشروعًا على Google Cloud أو أنشِئه في صفحة أداة اختيار المشاريع.
  2. تأكَّد من تفعيل الفوترة لمشروعك على Google Cloud. تعرَّف على كيفية التحقّق مما إذا كانت الفوترة مفعَّلة في مشروع.
  3. اتّبِع التعليمات لتفعيل BigQuery Studio لإدارة مواد العرض.

إعداد BigQuery Studio

أنشئ دفتر ملاحظات فارغًا واربطه بوقت تشغيل.

  1. انتقِل إلى BigQuery Studio في Google Cloud Console.
  2. انقر على بجانب الزر +.
  3. اختَر دفتر ملاحظات Python.
  4. أغلِق أداة اختيار النماذج.
  5. انقر على + رمز لإنشاء خلية رمز جديدة.
  6. ثبِّت أحدث إصدار من حزمة BigQuery DataFrames من خلية الرمز البرمجي.اكتب الأمر التالي.
    %pip install --upgrade bigframes --quiet
    
    انقر على الزر 🞂 أو اضغط على Shift ‏+ Enter لتشغيل خلية الرمز.

3- قراءة مجموعة بيانات عامة

يمكنك إعداد حزمة BigQuery DataFrames من خلال تنفيذ ما يلي في خلية رمز جديدة:

import bigframes.pandas as bpd

bpd.options.bigquery.ordering_mode = "partial"

ملاحظة: في هذا الدليل التعليمي، نستخدم "وضع الترتيب الجزئي" التجريبي الذي يتيح إجراء طلبات بحث أكثر فعالية عند استخدامه مع الفلترة التي تشبه بانداس. قد لا تعمل بعض ميزات pandas التي تتطلّب ترتيبًا أو فهرسًا صارمًا.

قاعدة بيانات شكاوى المستهلكين

تتوفّر قاعدة بيانات الشكاوى من المستهلكين على BigQuery من خلال برنامج مجموعات البيانات العامة في Google Cloud. هذه مجموعة من الشكاوى بشأن المنتجات والخدمات المالية للمستهلكين، ويتم جمع البيانات من قِبل مكتب حماية المستهلك المالي في الولايات المتحدة.

في BigQuery، أدخِل طلب بحث في جدول bigquery-public-data.cfbp_complaints.complaint_database لتحليل قاعدة بيانات الشكاوى من المستهلكين. استخدِم الطريقة bigframes.pandas.read_gbq() لإنشاء إطار بيانات من سلسلة طلب بحث أو رقم تعريف جدول.

شغِّل ما يلي في خلية رمز جديدة لإنشاء إطار بيانات باسم "ملاحظات":

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

التعرّف على معلومات أساسية عن إطار البيانات

استخدِم طريقة 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() إذا كنت تريد عرض نموذج للبيانات.

تمامًا كما هو الحال مع pandas، استخدِم السمة DataFrame.dtypes للاطّلاع على جميع الأعمدة المتاحة وأنواع البيانات المقابلة لها. ويتم عرضها بطريقة متوافقة مع pandas.

شغِّل هذه الخلية:

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() عن بعض الإحصاءات الأساسية من إطار البيانات. بما أنّ إطار البيانات هذا لا يحتوي على أعمدة رقمية، يعرض ملخصًا لعدد القيم غير الصفرية وعدد القيم الفريدة.

شغِّل هذه الخلية:

# 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

4. استكشاف البيانات

قبل الاطّلاع على الشكاوى الفعلية، استخدِم الطرق المشابهة لواجهة pandas في DataFrame لعرض البيانات بشكل مرئي.

عرض إطار البيانات

هناك العديد من طرق العروض المرئية المدمجة، مثل DataFrame.plot.hist(). وبما أنّ إطار البيانات هذا يحتوي في الغالب على بيانات سلاسل وبيانات منطقية، يمكننا أولاً إجراء بعض عمليات التجميع لمعرفة المزيد من المعلومات عن الأعمدة المختلفة.

احتسِب عدد الشكاوى التي يتم تلقّيها من كل ولاية.

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

حوِّل هذا الجدول إلى إطار بيانات pandas باستخدام الطريقة DataFrame.to_pandas().

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

استخدِم طرق تصور البيانات في Pandas على إطار البيانات الذي تم تنزيله.

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

يحدِّد استطلاع American Community Survey الولايات حسب مفتاح 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")
)

رسم بياني بالنقاط المبعثرة يقارن عدد السكان بعدد الشكاوى

يبدو أنّ هناك ولايتين تُعدّان قيمتَي شذوذ عند مقارنة عدد السكان بعدد الشكاوى. نترك للقارئ مهمة إنشاء الرسم البياني باستخدام تصنيفات النقاط لتحديد هذه النقاط. وبالمثل، يمكنك وضع بعض الفرضيات حول سبب حدوث ذلك (مثل الخصائص الديمغرافية المختلفة وعدد شركات الخدمات المالية المختلفة وما إلى ذلك) واختبارها.

5- احتساب عمليات التضمين

غالبًا ما تكون المعلومات المهمة مخفية في البيانات غير المنظَّمة، مثل النصوص أو الملفات الصوتية أو الصور. في هذا المثال، يتضمّن محتوى الشكوى النصي الكثير من المعلومات المفيدة في قاعدة بيانات الشكاوى.

يمكن للذكاء الاصطناعي والتقنيات التقليدية، مثل تحليل المشاعر و"مجموعة الكلمات" وword2vec، استخراج بعض المعلومات الكمّية من البيانات غير المنظَّمة. في الآونة الأخيرة، يمكن لنماذج "إدراج المتجهات"، التي ترتبط ارتباطًا وثيقًا بالنماذج اللغوية الكبيرة، إنشاء تسلسل من الأرقام ذات النقطة العائمة التي تمثّل المعلومات الدلالية للنص.

اختيار مجموعة فرعية من قاعدة البيانات

يستهلك تشغيل نموذج إدراج المتجهات موارد أكثر من العمليات الأخرى. لتقليل التكاليف ومشاكل الحصة، اختَر مجموعة فرعية من البيانات لبقية هذا الدليل التعليمي.

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

تمّ تقديم حوالي 1,000 شكوى في ‎01-12-2022 مقارنةً بـ 3.5 مليون صف تقريبًا في إجمالي قاعدة البيانات (يُرجى التحقّق من ذلك مع feedback.shape).

اختَر بيانات ‎01-12-2022 وعمود 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 ناقلات التضمين من خلال فئة 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

6- تجميع البيانات باستخدام تضمينات النصوص

الآن، يمكنك تجميع البيانات المضمّنة باستخدام الخوارزمية التصنيفية. في هذا العرض التوضيحي، استخدِم عددًا عشوائيًا من المجموعات (المعروفة أيضًا باسم مراكز الكتلة). يجب أن يضبط الحلّ المخصّص للإنتاج عدد مراكز الكتلة باستخدام أسلوب مثل طريقة 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()

7- تلخيص المجموعات

أدخِل بعض التعليقات المرتبطة بكل نقطة مركزية واطلب من 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()

استخدِم Gemini لكتابة تقرير من الملخّصات.

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. تَنظيم

إذا أنشأت مشروعًا جديدًا على Google Cloud لهذا الدليل التعليمي، يمكنك حذفه لمنع تحصيل رسوم إضافية مقابل الجداول أو الموارد الأخرى التي تم إنشاؤها.

9. تهانينا!

إذا كنت قد حلّلت البيانات المنظَّمة وغير المنظَّمة باستخدام إطارات بيانات BigQuery خلال هذه الرحلة، استكشَفت مجموعات البيانات العامة في Google Cloud، ودفاتر ملاحظات Python في BigQuery Studio، وBigQuery ML، وVertex AI، وميزات تحويل اللغة الطبيعية إلى Python في BigQuery Studio. أحسنت!

الخطوات التالية