สร้างแอปพลิเคชันคำแนะนำ Customer 360 ด้วย BigQuery Graph

1. บทนำ

ใน Codelab นี้ คุณจะได้เรียนรู้วิธีใช้ BigQuery Graph เพื่อสร้างมุมมองข้อมูลลูกค้าแบบครบ 360 องศาและเครื่องมือแนะนำสินค้าสำหรับ Cymbal Pets ซึ่งเป็นบริษัทค้าปลีกสมมติ คุณจะได้ใช้ประโยชน์จากความสามารถของ SQL ในการสร้าง ค้นหา และวิเคราะห์ข้อมูลกราฟภายใน BigQuery โดยตรง รวมถึงรวมเข้ากับการค้นหาแบบเวกเตอร์เพื่อการแนะนำสินค้าขั้นสูง

BigQuery Graph ช่วยให้คุณสร้างแบบจำลองความสัมพันธ์ระหว่างเอนทิตีข้อมูล (เช่น ลูกค้า สินค้า และคำสั่งซื้อ) เป็นกราฟ ซึ่งช่วยให้ตอบคำถามที่ซับซ้อนเกี่ยวกับพฤติกรรมของลูกค้าและความสัมพันธ์ของผลิตภัณฑ์ได้ง่าย

แผนภาพกรณีการใช้งาน

สิ่งที่คุณจะได้ทำ

  • สร้างชุดข้อมูลและสคีมา BigQuery สำหรับกราฟ Cymbal Pets
  • โหลดข้อมูลตัวอย่าง (ลูกค้า สินค้า คำสั่งซื้อ ร้านค้า) จาก Cloud Storage
  • สร้างกราฟเชิงคุณสมบัติใน BigQuery เพื่อเชื่อมต่อเอนทิตีเหล่านี้
  • แสดงข้อมูลประวัติการซื้อของลูกค้าผ่านภาพโดยใช้การค้นหากราฟ
  • สร้างระบบแนะนำสินค้าโดยใช้การค้นหาแบบเวกเตอร์
  • ปรับปรุงคำแนะนำโดยใช้ความสัมพันธ์ของกราฟ "สินค้าที่มักมีการซื้อร่วมกัน" และความคล้ายคลึงของ Jaccard

สิ่งที่คุณต้องมี

  • เว็บเบราว์เซอร์ เช่น Chrome
  • โปรเจ็กต์ Google Cloud ที่เปิดใช้การเรียกเก็บเงินแล้ว

Codelab นี้เหมาะสำหรับนักพัฒนาแอปทุกระดับ รวมถึงผู้เริ่มต้น

2. ก่อนเริ่มต้น

สร้างโปรเจ็กต์ Google Cloud

  1. ใน คอนโซล Google Cloud ให้เลือกหรือสร้างโปรเจ็กต์ที่อยู่ในระบบคลาวด์ของ Google Cloud
  2. ตรวจสอบว่าได้เปิดใช้การเรียกเก็บเงินสำหรับโปรเจ็กต์ที่อยู่ในระบบคลาวด์แล้ว

เริ่มต้น Cloud Shell

  1. คลิกเปิดใช้งาน Cloud Shell ที่ด้านบนของคอนโซล Google Cloud
  2. ยืนยันการตรวจสอบสิทธิ์โดยทำดังนี้
gcloud auth list
  1. ยืนยันโปรเจ็กต์โดยทำดังนี้
gcloud config get project
  1. ตั้งค่าหากจำเป็นโดยทำดังนี้
export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID

เปิดใช้ API

เรียกใช้คำสั่งนี้เพื่อเปิดใช้ BigQuery API ที่จำเป็น

gcloud services enable bigquery.googleapis.com \
  bigqueryreservation.googleapis.com 

สร้างการจองและการมอบหมาย BigQuery

หากต้องการเรียกใช้การค้นหา GQL คุณต้องมีการจองที่ใช้รุ่น Enterprise หรือ Enterprise Plus โดยสร้างการจองรุ่น Enterprise ที่มีการปรับขนาดอัตโนมัติใน Cloud Shell ดังนี้

# 1. Create a BigQuery Enterprise reservation with 0 baseline slots and 100 max autoscaling slots
bq mk --reservation \
  --project_id=${GCP_PROJECT} \
  --location=US \
  --edition=ENTERPRISE \
  --slots=0 \
  --autoscale_max_slots=100 \
  --ignore_idle_slots=true \
  c360-reservation

# 2. Assign your Cloud project to the newly created reservation for query execution
bq mk --reservation_assignment \
  --project_id=${GCP_PROJECT} \
  --location=US \
  --reservation_id=c360-reservation \
  --job_type=QUERY \
  --assignee_type=PROJECT \
  --assignee_id=${GCP_PROJECT}

3. กำหนดสคีมา

ขั้นแรก คุณต้องสร้างชุดข้อมูลเพื่อจัดเก็บตารางที่เกี่ยวข้องกับกราฟและกำหนดสคีมาสำหรับโหนดและขอบ

  1. สำหรับ Codelab นี้ เราจะเรียกใช้คำสั่ง SQL คุณสามารถเรียกใช้คำสั่งเหล่านี้ใน BigQuery Studio > SQL Editor หรือใช้คำสั่ง bq query ใน Cloud Shell การค้นหา SQL ใหม่เราจะถือว่าคุณใช้ BigQuery SQL Editor เพื่อให้ได้รับประสบการณ์การใช้งานที่ดีขึ้นกับคำสั่งสร้างหลายบรรทัด
  2. สร้างชุดข้อมูล cymbal_pets_demo โดยทำดังนี้
CREATE SCHEMA IF NOT EXISTS cymbal_pets_demo;
  1. สร้างตารางสำหรับ order_items, products, orders, stores, customers และ co_related_products_for_angelica ตารางเหล่านี้จะใช้เป็นข้อมูลต้นทางสำหรับกราฟของเรา
CREATE TABLE IF NOT EXISTS cymbal_pets_demo.order_items
(
  order_id INT64,
  product_id INT64,
  order_item_id INT64,
  quantity INT64,
  price FLOAT64,
  PRIMARY KEY (order_id, product_id, order_item_id) NOT ENFORCED
)
CLUSTER BY order_item_id;

CREATE TABLE IF NOT EXISTS cymbal_pets_demo.products
(
  product_id INT64,
  product_name STRING,
  brand STRING,
  category STRING,
  subcategory INT64,
  animal_type INT64,
  search_keywords INT64,
  price FLOAT64,
  description STRING,
  inventory_level INT64,
  supplier_id INT64,
  average_rating FLOAT64,
  uri STRING,
  embedding ARRAY<FLOAT64>,
  PRIMARY KEY (product_id) NOT ENFORCED
)
CLUSTER BY product_id;

CREATE TABLE IF NOT EXISTS cymbal_pets_demo.orders
(
  customer_id INT64,
  order_id INT64,
  shipping_address_city STRING,
  store_id INT64,
  order_date STRING,
  order_type STRING,
  payment_method STRING,
  PRIMARY KEY (order_id) NOT ENFORCED
);

CREATE TABLE IF NOT EXISTS cymbal_pets_demo.stores
(
  store_id INT64,
  store_name STRING,
  address_state STRING,
  address_city STRING,
  latitude FLOAT64,
  longitude FLOAT64,
  opening_hours STRUCT<Monday STRING, Tuesday STRING, Wednesday STRING, Thursday STRING, Friday STRING, Saturday STRING, Sunday STRING>,
  manager_id INT64,
  PRIMARY KEY (store_id) NOT ENFORCED
)
CLUSTER BY store_id;

CREATE TABLE IF NOT EXISTS cymbal_pets_demo.customers
(
  customer_id INT64,
  first_name STRING,
  last_name STRING,
  email STRING,
  gender STRING,
  address_city STRING,
  address_state STRING,
  loyalty_member BOOL,
  PRIMARY KEY (customer_id) NOT ENFORCED
)
CLUSTER BY customer_id;

CREATE TABLE IF NOT EXISTS cymbal_pets_demo.co_related_products_for_angelica
(
  angelica_product_id INT64,
  other_product_id INT64,
  co_purchase_count INT64,
  jaccard_similarity FLOAT64
);

ตอนนี้คุณได้กำหนดโครงสร้างสำหรับข้อมูลกราฟแล้ว

4. โหลดข้อมูล

ตอนนี้ให้ป้อนข้อมูลตัวอย่างจาก Cloud Storage ลงในตาราง

เรียกใช้คำสั่ง LOAD DATA ต่อไปนี้ใน BigQuery SQL Editor

LOAD DATA INTO `cymbal_pets_demo.customers`
FROM FILES (
    format = 'AVRO',
    uris = ['gs://sample-data-and-media/cymbal-pets/tables/customers/*.avro'],
    enable_logical_types = true
);

LOAD DATA INTO `cymbal_pets_demo.order_items`
FROM FILES (
    format = 'AVRO',
    uris = ['gs://sample-data-and-media/cymbal-pets/tables/order_items/*.avro'],
    enable_logical_types = true
);

LOAD DATA INTO `cymbal_pets_demo.orders`
FROM FILES (
    format = 'AVRO',
    uris = ['gs://sample-data-and-media/cymbal-pets/tables/orders/*.avro'],
    enable_logical_types = true
);

-- 1. Create a new partitioned and clustered table from your current data
CREATE TABLE cymbal_pets_demo.orders_temp
PARTITION BY order_date
CLUSTER BY order_id
AS
SELECT
  customer_id,
  order_id,
  shipping_address_city,
  store_id,
  -- Parse the string to a DATE type. Adjust format string ('%Y-%m-%d') if necessary.
  PARSE_DATE('%Y-%m-%d', order_date) AS order_date,
  order_type,
  payment_method
FROM
  cymbal_pets_demo.orders;

-- 2. Drop the original, non-partitioned table
DROP TABLE cymbal_pets_demo.orders;

-- 3. Rename the temporary table to the original table name
ALTER TABLE cymbal_pets_demo.orders_temp RENAME TO orders;

LOAD DATA INTO `cymbal_pets_demo.products`
FROM FILES (
    format = 'AVRO',
    uris = ['gs://sample-data-and-media/cymbal-pets/tables/products/*.avro'],
    enable_logical_types = true
);

LOAD DATA INTO `cymbal_pets_demo.stores`
FROM FILES (
    format = 'AVRO',
    uris = ['gs://sample-data-and-media/cymbal-pets/tables/stores/*.avro'],
    enable_logical_types = true
);

คุณจะเห็นข้อความยืนยันว่ามีการโหลดแถวลงในแต่ละตารางแล้ว

5. สร้างกราฟเชิงคุณสมบัติ

เมื่อโหลดข้อมูลแล้ว คุณก็กำหนดกราฟเชิงคุณสมบัติ ได้ ซึ่งจะบอก BigQuery ว่าตารางใดแสดงโหนด (เอนทิตี เช่น ลูกค้า สินค้า) และตารางใดแสดงขอบ (ความสัมพันธ์ เช่น "เข้าชม" "สั่งซื้อ" "มี")

สคีกราฟ

เรียกใช้คำสั่ง DDL ต่อไปนี้

CREATE OR REPLACE PROPERTY GRAPH cymbal_pets_demo.PetsOrderGraph
NODE TABLES (
  cymbal_pets_demo.customers KEY(customer_id) LABEL Customer,
  cymbal_pets_demo.products KEY(product_id) LABEL Products,
  cymbal_pets_demo.stores KEY(store_id) LABEL Stores,
  cymbal_pets_demo.orders KEY(order_id) LABEL Orders
)
EDGE TABLES (
  cymbal_pets_demo.orders as customer_to_store_edge
    KEY (order_id)
    SOURCE KEY (customer_id) references customers(customer_id)
    DESTINATION KEY (store_id) references stores(store_id)
    LABEL Visited
    PROPERTIES ALL COLUMNS,

  cymbal_pets_demo.order_items
    KEY (order_item_id)
    SOURCE KEY (order_id) references orders(order_id)
    DESTINATION KEY (product_id) references products(product_id)
    LABEL Has
    PROPERTIES ALL COLUMNS,

  cymbal_pets_demo.orders as customer_to_orders_edge
    KEY (order_id)
    SOURCE KEY (customer_id) references customers(customer_id)
    DESTINATION KEY (order_id) references orders(order_id)
    LABEL Placed
    PROPERTIES ALL COLUMNS,

  cymbal_pets_demo.co_related_products_for_angelica
    KEY (angelica_product_id)
    SOURCE KEY (angelica_product_id) references products(product_id)
    DESTINATION KEY (other_product_id) references products(product_id)
    LABEL BoughtTogether
    PROPERTIES ALL COLUMNS
);

ซึ่งจะสร้างกราฟ PetsOrderGraph ที่ช่วยให้เราทำการข้ามกราฟได้โดยใช้โอเปอเรเตอร์ GRAPH_TABLE

6. แสดงข้อมูลประวัติการซื้อของลูกค้าทั้งหมดผ่านภาพ

สำหรับส่วนการแสดงข้อมูลผ่านภาพและการแนะนำของ Codelab นี้ เราจะใช้การแสดงข้อมูลกราฟผ่านภาพแบบเนทีฟใน BigQuery Studio ซึ่งช่วยให้เราแสดงผลลัพธ์กราฟผ่านภาพได้อย่างง่ายดาย

หรือคุณจะแสดงข้อมูลผ่านภาพใน BigQuery Graph Notebook โดยใช้ IPython Magics ก็ได้ การเพิ่มคำสั่ง Magic %%bigquery พร้อมฟังก์ชัน TO_JSON จะช่วยให้คุณแสดงผลลัพธ์ผ่านภาพได้ตามที่แสดงในส่วนต่อไปนี้

สมมติว่า Cymbal Pets ต้องการแสดงข้อมูลลูกค้าทั้งหมดและคำสั่งซื้อที่ลูกค้าทำในช่วงเวลาที่กำหนดผ่านภาพแบบครบ 360 องศา

เรียกใช้คำสั่งต่อไปนี้ในแท็บ BigQuery Studio ใหม่

GRAPH cymbal_pets_demo.PetsOrderGraph
  # finds the customer node and then finds all
  # the Orders nodes that are connected to that customer through the
  # Placed relationship
  MATCH (customer:Customer)-[placed:Placed]->(ordr:Orders)-[has:Has]->(product:Products)
  # filters the Orders nodes to only include those where the
  # order_date is within the last 3 months.
  WHERE ordr.order_date >= date('2024-11-27')
  # # This line finds all the Products nodes that are connected to the
  # # filtered Orders nodes through the Has relationship.
  MATCH p=(customer:Customer)-[placed:Placed]->(ordr:Orders)-[has:Has]->(product:Products)
  LIMIT 40
  RETURN 
    TO_JSON(p) as paths

หากต้องการแสดงผลลัพธ์ผ่านภาพ ให้คลิกกราฟในบานหน้าต่างผลการค้นหา

ประวัติการซื้อของลูกค้าทั้งหมด

7. แสดงข้อมูลประวัติการซื้อของ Angelica ผ่านภาพ

สมมติว่า Cymbal Pets ต้องการเจาะลึกข้อมูลของลูกค้าชื่อ Angelica Russell โดยต้องการวิเคราะห์สินค้าที่ Angelica ซื้อในช่วง 3 เดือนที่ผ่านมาและร้านค้าที่ลูกค้าเข้าชม

GRAPH cymbal_pets_demo.PetsOrderGraph
  # finds the customer node with the name "Angelica Russell" and then finds all
  # the Orders nodes that are connected to that customer through the
  # Placed relationship and all the Products nodes that are connected to the
  # filtered Orders nodes through the Has relationship.
   MATCH p=(customer:Customer {first_name: 'Angelica', last_name: 'Russell'})-[placed:Placed]->(ordr:Orders)-[has:Has]->(product:Products)
  # filters the Orders nodes to only include those where the
  # order_date is within the last 3 months.
  WHERE ordr.order_date >= date('2024-11-27')
  # finds the Stores nodes where Angelica placed order from
  MATCH p2=(customer)-[visited:Visited]->(store:Stores)
  RETURN
    TO_JSON(p) as path, TO_JSON(p2) as path2

ประวัติการซื้อของแอนเจลิกา

8. การแนะนำสินค้าโดยใช้การค้นหาแบบเวกเตอร์

Cymbal Pets ต้องการแนะนำสินค้าให้ Angelica โดยอิงตามสิ่งที่เธอซื้อเมื่อเร็วๆ นี้ เราสามารถใช้การค้นหาแบบเวกเตอร์ เพื่อค้นหาสินค้าที่มีการฝังที่คล้ายกับสินค้าที่เธอซื้อในอดีต

เรียกใช้สคริปต์ SQL ต่อไปนี้ในเซลล์ Colab ใหม่ สคริปต์นี้จะทำดังนี้

  1. ระบุสินค้าที่ Angelica ซื้อเมื่อเร็วๆ นี้
  2. ใช้ VECTOR_SEARCH เพื่อค้นหาสินค้าที่คล้ายกัน 4 รายการแรกจากตาราง products

หมายเหตุ: ขั้นตอนนี้ถือว่าคุณได้เรียกใช้ AI.GENERATE_EMBEDDINGS เพื่อสร้างคอลัมน์การฝังในตารางผลิตภัณฑ์แล้ว

DECLARE products_bought_by_angelica ARRAY<INT64>;

-- 1. Get IDs of products bought by Angelica
SET products_bought_by_angelica = (
  SELECT ARRAY_AGG(product_id) FROM
   GRAPH_TABLE(
    cymbal_pets_demo.PetsOrderGraph
      MATCH (c:Customer {first_name: 'Angelica', last_name: 'Russell'})-[placed:Placed]->(o:Orders)
      WHERE o.order_date >= date('2024-11-27')
      MATCH (o)-[has_edge:Has]->(p:Products)
      RETURN DISTINCT p.product_id as product_id
  ));

-- 2. Find similar products using vector search
SELECT 
  query.product_name as AngelicaBought, 
  base.product_name as RecommendedProducts, 
  base.category
FROM
  VECTOR_SEARCH(
    TABLE cymbal_pets_demo.products,
    'embedding',
    (SELECT * FROM cymbal_pets_demo.products
     WHERE product_id IN UNNEST(products_bought_by_angelica)),
    'embedding',
    top_k => 4)
WHERE query.product_name <> base.product_name;

คุณจะเห็นรายการสินค้าที่แนะนำซึ่งมีความหมายคล้ายกับสินค้าที่ Angelica ซื้อ

ผลการค้นหาเวกเตอร์

9. การแนะนำโดยใช้ "สินค้าที่มักมีการซื้อร่วมกัน" และความคล้ายคลึงของ Jaccard

เทคนิคการแนะนำที่มีประสิทธิภาพอีกอย่างหนึ่งคือ "การกรองแบบร่วมมือ" ซึ่งเป็นการแนะนำสินค้าที่ผู้ใช้รายอื่นมักซื้อร่วมกัน

เราสามารถค้นหาสินค้าเหล่านี้ได้โดยการข้ามกราฟจากลูกค้าไปยังสินค้าที่ลูกค้าซื้อ จากนั้นไปยังลูกค้ารายอื่นที่ซื้อสินค้าเหล่านั้น และสุดท้ายไปยังสินค้าอื่นๆ ที่ลูกค้าเหล่านั้นซื้อ

การเอาชนะอคติความนิยมด้วยความคล้ายคลึงของ Jaccard

แม้ว่าจำนวนการซื้อร่วมแบบดิบจะมีประโยชน์ แต่ก็อาจมีอคติกับสินค้าที่ได้รับความนิยม สินค้าที่ได้รับความนิยมมากอาจมีการซื้อร่วมกับสินค้าอื่นๆ มากมายเพียงเพราะความบังเอิญ

ความคล้ายคลึงของ Jaccard ช่วยให้การแนะนำก้าวไปอีกขั้นด้วยการทำให้จำนวนการซื้อร่วมเป็นปกติ โดยจะวัดความคล้ายคลึงระหว่าง 2 ชุด (ในกรณีนี้คือชุดคำสั่งซื้อที่มีสินค้าแต่ละรายการ)

สูตรความคล้ายคลึงของ Jaccard มีดังนี้

โดยที่

  • A intersect B คือจำนวนคำสั่งซื้อที่มีทั้งสินค้า A และสินค้า B (จำนวนการซื้อร่วม)
  • A คือจำนวนคำสั่งซื้อทั้งหมดที่มีสินค้า A
  • B คือจำนวนคำสั่งซื้อทั้งหมดที่มีสินค้า B

ในตัวอย่างต่อไปนี้ ชุด A = {b,c,e,f,g}, ชุด B = {a,d,b,g}, ส่วนที่ตัดกัน A⋂B = {b,g}, ส่วนที่รวมกัน A⋃B = {a,b,c,d,e,f,g} ดังนั้นความคล้ายคลึงของ Jaccard ระหว่าง A และ B คือ 2 / 7 = 0.285714

การสร้างและการจัดอันดับผู้สมัคร

ในระบบแนะนำสินค้าในโลกแห่งความเป็นจริงที่ทำงานกับชุดข้อมูลขนาดใหญ่ การคำนวณคะแนนความคล้ายคลึงที่ซับซ้อน (เช่น Jaccard) สำหรับสินค้าทุกคู่ที่เป็นไปได้มักจะไม่สามารถทำได้จริง แต่รูปแบบที่ใช้กันทั่วไปคือการใช้แนวทาง 2 ขั้นตอน ดังนี้

  1. การสร้างผู้สมัคร: ใช้เมตริกที่ง่ายและรวดเร็ว (เช่น จำนวนการซื้อร่วมแบบดิบ) เพื่อกรองพื้นที่การค้นหาและค้นหาผู้สมัครจำนวนที่จัดการได้ (เช่น 10 รายการแรก)
  2. การจัดอันดับใหม่: ใช้เมตริกที่แม่นยำกว่าแต่ต้องใช้การคำนวณมากกว่า (เช่น ความคล้ายคลึงของ Jaccard) เพื่อจัดอันดับผู้สมัครจำนวนน้อยนั้นและเลือกคำแนะนำ 3 รายการแรกสุดท้าย

ใน Codelab นี้ เราจะทำตามรูปแบบนี้

  • ขั้นตอนที่ 1: เรียกใช้การค้นหาเพื่อค้นหาสินค้าที่มักมีการซื้อร่วมกัน 10 รายการแรกสำหรับสินค้าแต่ละรายการ โดยอิงตามจำนวนการซื้อร่วมแบบดิบ และจัดเก็บไว้ในตาราง
  • ขั้นตอนที่ 2: ใช้การค้นหากราฟเพื่อดึงข้อมูลผู้สมัครเหล่านี้ จัดอันดับตามความคล้ายคลึงของ Jaccard และแสดงผลลัพธ์ 3 รายการแรก

[!WARNING] ข้อเสีย: การกรองตามจำนวนแบบดิบในขั้นตอนที่ 1 อาจทำให้เราพลาด "การเรียกคืน" การซื้อร่วมที่เฉพาะเจาะจงมากแต่เกิดขึ้นไม่บ่อย หากสินค้ามีความคล้ายคลึงกับสินค้าอื่นมากแต่มีการซื้อทั้ง 2 รายการไม่บ่อยนัก สินค้าดังกล่าวอาจไม่ติด 10 อันดับแรกของผู้สมัครและจะถูกมองข้ามไป

เรียกใช้การค้นหาต่อไปนี้เพื่อคำนวณทั้งจำนวนการซื้อร่วมแบบดิบและความคล้ายคลึงของ Jaccard และจัดเก็บผู้สมัคร10 รายการแรก ตามจำนวนแบบดิบ

CREATE OR REPLACE TABLE cymbal_pets_demo.co_related_products_for_angelica AS
-- Calculate the total number of orders for each product
WITH ProductOrderCounts AS (
    SELECT product_id, COUNT(DISTINCT order_id) as total_count
    FROM cymbal_pets_demo.order_items
    GROUP BY product_id
),
-- Calculate the intersection of each product pairs
CoPurchases AS (
    SELECT
        angelicaProduct.product_id AS angelica_product_id,
        otherProduct.product_id AS other_product_id,
        count(DISTINCT otherOrder.order_id) AS co_purchase_count
    FROM
        GRAPH_TABLE (cymbal_pets_demo.PetsOrderGraph
          MATCH (angelica:Customer {first_name: 'Angelica', last_name: 'Russell'})-[:Placed]->(o:Orders)-[:Has]->(angelicaProduct:Products)
          WHERE o.order_date >= date('2024-11-27')
          WITH angelica, angelicaProduct
          MATCH (otherCustomer:Customer)-[:Placed]->(otherOrder:Orders)-[:Has]->(angelicaProduct)
          WHERE otherCustomer <> angelica
          WITH angelicaProduct, otherOrder
          MATCH (otherOrder)-[:HAS]->(otherProduct:Products)
          WHERE angelicaProduct <> otherProduct
          RETURN angelicaProduct, otherProduct, otherOrder
        )
    GROUP BY
        angelicaProduct.product_id, otherProduct.product_id
)
SELECT * FROM (
    SELECT
        cp.angelica_product_id,
        cp.other_product_id,
        cp.co_purchase_count,
        -- The Jaccard calculation, which is the intersection of A and B divided by (A + B - intersection)
        SAFE_DIVIDE(cp.co_purchase_count, (poc1.total_count + poc2.total_count - cp.co_purchase_count)) AS jaccard_similarity,
        ROW_NUMBER() OVER (PARTITION BY cp.angelica_product_id ORDER BY cp.co_purchase_count DESC) AS rn
    FROM CoPurchases cp
    JOIN ProductOrderCounts poc1 ON cp.angelica_product_id = poc1.product_id
    JOIN ProductOrderCounts poc2 ON cp.other_product_id = poc2.product_id
)
WHERE rn <= 10;

ตรรกะของคำแนะนำ

เรียกใช้การค้นหานี้เพื่อแนะนำสินค้า 3 รายการแรกสำหรับการซื้อแต่ละครั้งของ Angelica ซึ่งเชื่อมต่อโดยตรงผ่านขอบ BoughtTogether โดยแสดงทั้งจำนวนการซื้อร่วมและความคล้ายคลึงของ Jaccard

SELECT * FROM GRAPH_TABLE(
  cymbal_pets_demo.PetsOrderGraph
  MATCH (customer:Customer {first_name: 'Angelica', last_name: 'Russell'})-[placed:Placed]->(ordr:Orders)
  WHERE ordr.order_date >= date('2024-11-27')
  MATCH (ordr)-[has:Has]->(product:Products)
  MATCH (product)-[bought_together:BoughtTogether]->(recommended_product:Products)
  RETURN 
    product.product_name AS OriginalProduct,
    recommended_product.product_name AS Recommended,
    bought_together.co_purchase_count AS Strength,
    bought_together.jaccard_similarity AS JaccardSimilarity
)
-- Rank product recommendations by Jaccard Similarity
QUALIFY ROW_NUMBER() OVER (PARTITION BY OriginalProduct ORDER BY JaccardSimilarity DESC) <= 3
ORDER BY OriginalProduct;

การค้นหานี้จะข้ามจากลูกค้า -> คำสั่งซื้อ -> สินค้า -> (สินค้าที่มักมีการซื้อร่วมกัน) -> สินค้าที่แนะนำ โดยแสดงคำแนะนำตามพฤติกรรมการซื้อโดยรวมและดึงข้อมูลคะแนนความคล้ายคลึง

ซื้อด้วยกัน

10. ล้างข้อมูล

หากต้องการหลีกเลี่ยงการเรียกเก็บเงินอย่างต่อเนื่องจากบัญชี Google Cloud ให้ลบทรัพยากรที่สร้างขึ้นระหว่าง Codelab นี้

ลบชุดข้อมูลและตารางทั้งหมดโดยทำดังนี้

DROP SCHEMA IF EXISTS cymbal_pets_demo CASCADE;

หากคุณสร้างโปรเจ็กต์ใหม่สำหรับ Codelab นี้ คุณสามารถลบโปรเจ็กต์ได้โดยทำดังนี้

gcloud projects delete $PROJECT_ID

11. ขอแสดงความยินดี

ขอแสดงความยินดี คุณสร้างมุมมองข้อมูลลูกค้าแบบครบ 360 องศาและเครื่องมือแนะนำสินค้าโดยใช้ BigQuery Graph ได้สำเร็จแล้ว

สิ่งที่คุณได้เรียนรู้

  • วิธีสร้างกราฟเชิงคุณสมบัติใน BigQuery
  • วิธีโหลดข้อมูลลงในโหนดและขอบของกราฟ
  • วิธีค้นหารูปแบบกราฟโดยใช้ GRAPH_TABLE และ MATCH
  • วิธีรวมการค้นหากราฟเข้ากับการค้นหาแบบเวกเตอร์เพื่อการแนะนำแบบไฮบริด

ขั้นตอนถัดไป