חיפוש הטמעות באמצעות חיפוש וקטורי

במדריך הזה נסביר איך לבצע חיפוש דמיון בהטמעות שמאוחסנות בטבלאות BigQuery באמצעות הפונקציה VECTOR_SEARCH ואינדקס וקטורי.

חיפוש וקטורי הוא טכניקה להשוואה בין אובייקטים דומים באמצעות הטמעות. הטכניקה הזו משמשת להפעלת מוצרי Google, כולל חיפוש Google,‏ YouTube ו-Google Play. אתם יכולים להשתמש בחיפוש וקטורי כדי לבצע חיפושים סמנטיים בהיקף גדול, או לבצע חיפוש היברידי שמשלב חיפוש סמנטי עם חיפוש לקסיקלי (מילות מפתח). כשמשתמשים באינדקסים של וקטורים עם חיפוש וקטורי, אפשר לנצל טכנולוגיות בסיסיות כמו אינדוקס של קבצים הפוכים (IVF) ואלגוריתם ScaNN.

חיפוש וקטורי מבוסס על הטמעות. הטמעה היא וקטור מספרי רב-ממדי שמייצג ישות נתונה, כמו קטע טקסט או קובץ אודיו. מודלים של למידת מכונה (ML) משתמשים בהטמעות כדי לקודד סמנטיקה לגבי ישויות כאלה, וכך להקל על ניתוח שלהן והשוואה ביניהן. לדוגמה, פעולה נפוצה במודלים של אשכולות, סיווג והמלצות היא מדידת המרחק בין וקטורים במרחב הטמעה כדי למצוא פריטים שהדמיון הסמנטי ביניהם הוא הגדול ביותר.

מטרות

  • אפשר לבצע חיפוש דמיון בהטמעות שמאוחסנות בטבלאות BigQuery באמצעות הפונקציה VECTOR_SEARCH.
  • כדי לשפר את הביצועים של חיפוש וקטורי, אפשר להשתמש באינדקס וקטורי.
  • ביצוע חיפוש שמשתמש באינדקס וקטורי וחיפוש שלא משתמש באינדקס.
  • כדי להעריך את ההחזרה, משווים בין תוצאות של חיפושים עם אינדקס לבין חיפושים בלי אינדקס.

עלויות

הפונקציה VECTOR_SEARCH משתמשת בתמחור של BigQuery Compute. אתם מחויבים על חיפוש דמיון לפי תמחור לפי דרישה או לפי מהדורות.

  • על פי דרישה: אתם מחויבים על כמות הבייטים שנסרקו בטבלת הבסיס, באינדקס ובשאילתת החיפוש.
  • תמחור מהדורות: אתם מחויבים על המשבצות שנדרשות להשלמת העבודה במהדורה שהזמנתם. חישובים גדולים ומורכבים יותר של דמיון כרוכים בחיובים גבוהים יותר.

מידע נוסף על התמחור של BigQuery

לפני שמתחילים

  1. בדף לבחירת הפרויקט במסוף Google Cloud , בוחרים פרויקט ב- Google Cloud או יוצרים אותו.

    תפקידים שנדרשים כדי לבחור או ליצור פרויקט

    • Select a project: כדי לבחור פרויקט לא צריך תפקיד IAM ספציפי – אפשר לבחור כל פרויקט שקיבלתם בו תפקיד.
    • יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד Project Creator (יצירת פרויקטים) (roles/resourcemanager.projectCreator), שכולל את ההרשאה resourcemanager.projects.create. איך מקצים תפקידים

    כניסה לדף לבחירת הפרויקט

  2. מוודאים שהחיוב מופעל בפרויקט Google Cloud .

  3. מפעילים את BigQuery API.

    תפקידים שנדרשים להפעלת ממשקי API

    כדי להפעיל ממשקי API, נדרשת ההרשאה serviceusage.services.enable. אם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד 'בעלים' (roles/owner). אחרת, תוכלו לקבל את ההרשאה הזו דרך התפקיד 'אדמין בממשק Service Usage' (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידים

    להפעלת ה-API

התפקידים הנדרשים

כדי לקבל את ההרשאות שדרושות להשלמת המדריך הזה, צריך לבקש מהאדמין להקצות לכם את תפקידי ה-IAM הבאים בפרויקט:

להסבר על מתן תפקידים, ראו איך מנהלים את הגישה ברמת הפרויקט, התיקייה והארגון.

יכול להיות שאפשר לקבל את ההרשאות הנדרשות גם באמצעות תפקידים בהתאמה אישית או תפקידים מוגדרים מראש.

יצירת מערך נתונים

כדי ליצור מערך נתונים ב-BigQuery, בוחרים באחת מהאפשרויות הבאות:

המסוף

  1. במסוף Google Cloud , עוברים לדף BigQuery.

    כניסה ל-BigQuery

  2. בחלונית הימנית, לוחצים על כלי הניתוחים:

    הלחצן המודגש של חלונית הסייר.

    אם החלונית הימנית לא מוצגת, לוחצים על הרחבת החלונית הימנית כדי לפתוח אותה.

  3. בסייר, מרחיבים את הפרויקט ואז לוחצים על מערכי נתונים.

  4. בדף Datasets (מערכי נתונים), לוחצים על Create dataset (יצירת מערך נתונים).

  5. בחלונית Create dataset:

    • בשדה Dataset ID (מזהה קבוצת נתונים), מזינים bqml_tutorial.

    • בקטע Data location, בוחרים באפשרות US.

    משאירים את שאר הגדרות ברירת המחדל כמו שהן.

  6. לוחצים על יצירת מערך נתונים.

BQ

כדי ליצור מערך נתונים חדש, משתמשים בפקודה bq mk --dataset.

  1. יוצרים מערך נתונים בשם bqml_tutorial עם מיקום הנתונים שמוגדר ל-US:

    bq mk --dataset \
      --location=US \
      --description "BigQuery ML tutorial dataset." \
      bqml_tutorial
  2. בודקים שמערך הנתונים נוצר:

    bq ls

API

מפעילים את השיטה datasets.insert עם משאב מוגדר של מערך נתונים:

{
  "datasetReference": {
     "datasetId": "bqml_tutorial"
  }
}

יצירת טבלאות לאחסון נתונים והטבעות

בקטע הזה יוצרים את הטבלה patents שמכילה הטמעות של פטנטים. ההטמעות מבוססות על קבוצת משנה של מערך הנתונים הציבורי של Google פטנטים. יוצרים גם את הטבלה patents2 שמכילה הטמעה של פטנט כדי למצוא שכנים קרובים.

כדי ליצור את הטבלאות, פועלים לפי השלבים הבאים:

  1. כדי ליצור את הטבלה patents, מדביקים את השאילתה הבאה בעורך השאילתות ולוחצים על ואז על Run:

    CREATE TABLE bqml_tutorial.patents AS
    SELECT * FROM `patents-public-data.google_patents_research.publications`
    WHERE ARRAY_LENGTH(embedding_v1) > 0
     AND publication_number NOT IN ('KR-20180122872-A')
    LIMIT 1000000;

    תוצג הודעת אישור כמו זו: This statement created a new table named patents.

  2. כדי ליצור את הטבלה patents2 שמכילה הטמעה של פטנט כדי למצוא את השכנים הקרובים ביותר, מדביקים את השאילתה הבאה בעורך השאילתות ולוחצים על Run:

    CREATE TABLE bqml_tutorial.patents2 AS
    SELECT * FROM `patents-public-data.google_patents_research.publications`
    WHERE publication_number = 'KR-20180122872-A';

    תוצג הודעת אישור כמו זו: This statement created a new table named patents2.

יצירת אינדקס וקטורי

כשמשתמשים ב-VECTOR_SEARCH עם אינדקס וקטורי, VECTOR_SEARCH משתמש בשיטה Approximate Nearest Neighbor כדי לשפר את הביצועים של חיפוש וקטורי, אבל יש לכך מחיר: ההחזרה פוחתת, ולכן התוצאות הן יותר משוערות. בלי אינדקס וקטורי, VECTOR_SEARCH משתמש בחיפוש בכוח כדי למדוד את המרחק של כל רשומה.

בקטע הזה יוצרים את my_index אינדקס הווקטור בעמודה embedding_v1 של הטבלה patents. לאחר מכן, מאמתים שהאינדקס זמין.

כדי ליצור את אינדקס הווקטורים, פועלים לפי השלבים הבאים:

  1. כדי ליצור את אינדקס הווקטורים my_index בעמודה embedding_v1 של הטבלה patents, מדביקים את השאילתה הבאה בעורך השאילתות ולוחצים על Run:

    CREATE OR REPLACE VECTOR INDEX my_index ON bqml_tutorial.patents(embedding_v1)
    STORING(publication_number, title)
    OPTIONS(distance_type='COSINE', index_type='IVF');

    תוצג הודעת אישור כמו זו: The vector index creation on table bqml_tutorial.patents was initiated. Please query bqml_tutorial.INFORMATION_SCHEMA.VECTOR_INDEXES to check the progress of the index.

  2. כדי לוודא שאינדקס הווקטור מוכן, מדביקים את הפקודה הבאה בעורך השאילתות ולוחצים על Run:

    SELECT * FROM bqml_tutorial.INFORMATION_SCHEMA.VECTOR_INDEXES;

    בתוצאות השאילתה, מוודאים שהערך של index_status הוא ACTIVE, ושהערך של coverage_percentage הוא 100. יכול להיות שיחלפו כמה דקות עד ש-coverage_percentage יגיע אל 100.

שימוש בפונקציה VECTOR_SEARCH עם אינדקס

אחרי שיוצרים את אינדקס הווקטור ומאכלסים אותו, משתמשים בפונקציה VECTOR_SEARCH כדי למצוא את השכן הקרוב ביותר להטמעה בעמודה embedding_v1 בטבלה patents2. השאילתה הזו משתמשת באינדקס הווקטורי בחיפוש, לכן VECTOR_SEARCH משתמש בשיטה של שכן קרוב משוער כדי למצוא את השכן הקרוב ביותר להטמעה.

כדי להשתמש בפונקציה VECTOR_SEARCH עם אינדקס, מדביקים את הטקסט הבא בעורך השאילתות ולוחצים על Run:

SELECT query.publication_number AS query_publication_number,
  query.title AS query_title,
  base.publication_number AS base_publication_number,
  base.title AS base_title,
  distance
FROM
  VECTOR_SEARCH(
    TABLE bqml_tutorial.patents,
    'embedding_v1',
    TABLE bqml_tutorial.patents2,
    top_k => 5,
    distance_type => 'COSINE',
    options => '{"fraction_lists_to_search": 0.005}');

התוצאות אמורות להיראות כך:

+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+
| query_publication_number |                         query_title                         | base_publication_number |                                                        base_title                                                        |      distance       |
+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-106599080-B          | A kind of rapid generation for keeping away big vast transfer figure based on GIS                                        | 0.14471956347590609 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-114118544-A          | Urban waterlogging detection method and device                                                                           | 0.17472108931171348 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | KR-20200048143-A        | Method and system for mornitoring dry stream using unmanned aerial vehicle                                               | 0.17561990745619782 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | KR-101721695-B1         | Urban Climate Impact Assessment method of Reflecting Urban Planning Scenarios and Analysis System using the same         | 0.17696129365559843 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-109000731-B          | The experimental rig and method that research inlet for stom water chocking-up degree influences water discharged amount | 0.17902723269642917 |
+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+

שימוש בפונקציה VECTOR_SEARCH עם ניסיון לפרוץ סיסמה

בקטע הזה, משתמשים בפונקציה VECTOR_SEARCH כדי למצוא את השכן הקרוב ביותר להטמעה בעמודה embedding_v1 בטבלה patents2. השאילתה הזו לא משתמשת באינדקס הווקטורי בחיפוש, ולכן הפונקציה VECTOR_SEARCH מוצאת את השכן הקרוב המדויק של ההטמעה.

כדי להשתמש ב-VECTOR_SEARCH עם brute force, מדביקים את השאילתה הבאה בעורך השאילתות ולוחצים על Run:

SELECT query.publication_number AS query_publication_number,
  query.title AS query_title,
  base.publication_number AS base_publication_number,
  base.title AS base_title,
  distance
FROM
  VECTOR_SEARCH(
    TABLE bqml_tutorial.patents,
    'embedding_v1',
    TABLE bqml_tutorial.patents2,
    top_k => 5,
    distance_type => 'COSINE',
    options => '{"use_brute_force":true}');

התוצאות אמורות להיראות כך:

+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+
| query_publication_number |                         query_title                         | base_publication_number |                                                        base_title                                                        |      distance       |
+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-106599080-B          | A kind of rapid generation for keeping away big vast transfer figure based on GIS                                        |  0.1447195634759062 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-114118544-A          | Urban waterlogging detection method and device                                                                           |  0.1747210893117136 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | KR-20200048143-A        | Method and system for mornitoring dry stream using unmanned aerial vehicle                                               | 0.17561990745619782 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | KR-101721695-B1         | Urban Climate Impact Assessment method of Reflecting Urban Planning Scenarios and Analysis System using the same         | 0.17696129365559843 |
| KR-20180122872-A         | Rainwater management system based on rainwater keeping unit | CN-109000731-B          | The experimental rig and method that research inlet for stom water chocking-up degree influences water discharged amount | 0.17902723269642928 |
+--------------------------+-------------------------------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------+---------------------+

הערכת היכולת לשחזר מידע

כשמבצעים חיפוש וקטורי עם אינדקס, מקבלים תוצאות משוערות, אבל זה מפחית את ההחזרה. אפשר לחשב את ההחזרה על ידי השוואה בין התוצאות שמתקבלות מחיפוש וקטורי עם אינדקס, לבין התוצאות שמתקבלות מחיפוש וקטורי עם כוח גס. הערך publication_number מזהה באופן ייחודי פטנט, ולכן הוא משמש להשוואה בשאילתה הבאה.

כדי להעריך את ההחזרה, מדביקים את השאילתה הבאה בעורך השאילתות ולוחצים על Run:

WITH approx_results AS (
  SELECT query.publication_number AS query_publication_number,
    base.publication_number AS base_publication_number
  FROM
    VECTOR_SEARCH(
      TABLE bqml_tutorial.patents,
      'embedding_v1',
      TABLE bqml_tutorial.patents2,
      top_k => 5,
      distance_type => 'COSINE',
      options => '{"fraction_lists_to_search": 0.005}')
),
  exact_results AS (
  SELECT query.publication_number AS query_publication_number,
    base.publication_number AS base_publication_number
  FROM
    VECTOR_SEARCH(
      TABLE bqml_tutorial.patents,
      'embedding_v1',
      TABLE bqml_tutorial.patents2,
      top_k => 5,
      distance_type => 'COSINE',
      options => '{"use_brute_force":true}')
)

SELECT
  a.query_publication_number,
  SUM(CASE WHEN a.base_publication_number = e.base_publication_number THEN 1 ELSE 0 END) / 5 AS recall
FROM exact_results e LEFT JOIN approx_results a
  ON e.query_publication_number = a.query_publication_number
GROUP BY a.query_publication_number;

התוצאות אמורות להיראות כך:

+--------------------------+--------+
| query_publication_number | recall |
+--------------------------+--------+
| KR-20180122872-A         |    1.0 |
+--------------------------+--------+

אם ערך ההחזרה נמוך מהרצוי, אפשר להגדיל את הערך fraction_lists_to_search, אבל יכול להיות שזמן האחזור וצריכת המשאבים יהיו גבוהים יותר. כדי לכוונן את החיפוש הווקטורי, אפשר להריץ כמה פעמים את VECTOR_SEARCH עם ערכי ארגומנטים שונים, לשמור את התוצאות בטבלאות ואז להשוות בין התוצאות.

הסרת המשאבים

כדי להימנע מחיובים בחשבון Google Cloud בגלל השימוש במשאבים שנעשה במסגרת המדריך הזה, אפשר למחוק את הפרויקט שמכיל את המשאבים, או להשאיר את הפרויקט ולמחוק את המשאבים בנפרד.

  1. במסוף Google Cloud , נכנסים לדף Manage resources.

    כניסה לדף Manage resources

  2. ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
  3. כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.

לחלופין, כדי לשמור את הפרויקט ולמחוק את המשאבים שבהם השתמשתם במדריך הזה, פועלים לפי השלבים הבאים:

  1. עוברים לדף BigQuery.

    כניסה ל-BigQuery

  2. בחלונית הימנית, מרחיבים את הפרויקט ואז לוחצים על מערכי נתונים.

  3. במערך הנתונים bqml_tutorial, לוחצים על פתיחת הפעולות > מחיקה.

  4. בתיבת הדו-שיח מחיקת מערך נתונים, לוחצים על מחיקה כדי לאשר.

המאמרים הבאים