סינון התאמות וקטוריות

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

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

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

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

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

מאפיינים וקטוריים

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

באפליקציה לדוגמה הבאה, וקטורים מתויגים ב-color, ב-price וב-shape:

  • color,‏ price וגם shape הם מרחבי שמות.
  • red ו-blue הם אסימונים ממרחב השמות color.
  • square ו-circle הם אסימונים ממרחב השמות shape.
  • 100 ו-50 הם ערכים ממרחב השמות price.

ציון מאפייני הווקטור

  • כדי לציין "עיגול אדום": {color: red}, {shape: circle}.
  • כדי לציין "ריבוע אדום או כחול": {color: red, blue}, {shape: square}.
  • כדי לציין אובייקט ללא צבע, משמיטים את מרחב השמות color בשדה restricts.
  • כדי לציין הגבלות מספריות לאובייקט, צריך לציין את מרחב השמות ואת הערך בשדה המתאים לסוג. ערך מסוג int צריך להיות מוגדר ב-value_int, ערך מסוג float צריך להיות מוגדר ב-value_float, וערך מסוג double צריך להיות מוגדר ב-value_double. צריך להשתמש רק בסוג מספר אחד למרחב שמות נתון.

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

שאילתות

  • השאילתות מבטאות אופרטור AND לוגי בין מרחבי שמות ואופרטור OR לוגי בתוך כל מרחב שמות. שאילתה שמציינת את {color: red, blue}, {shape: square, circle}, תואמת לכל הנקודות במסד הנתונים שמקיימות את התנאי (red || blue) && (square || circle).
  • שאילתה שמציינת {color: red} תואמת לכל האובייקטים מסוג red, ללא הגבלה על shape.
  • הגבלות מספריות בשאילתות דורשות namespace, אחד מהערכים המספריים מתוך value_int, value_float ו-value_double, ואת האופרטור op.
  • האופרטור op הוא אחד מהאופרטורים LESS, LESS_EQUAL, EQUAL, GREATER_EQUAL ו-GREATER. לדוגמה, אם משתמשים באופרטור LESS_EQUAL, נקודות הנתונים עומדות בדרישות אם הערך שלהן קטן מהערך שמשמש בשאילתה או שווה לו.

בדוגמאות הקוד הבאות מזהים מאפייני וקטור באפליקציה לדוגמה:

[
  {
    "namespace": "price",
    "value_int": 20,
    "op": "LESS"
  },
  {
    "namespace": "length",
    "value_float": 0.3,
    "op": "GREATER_EQUAL"
  },
  {
    "namespace": "width",
    "value_double": 0.5,
    "op": "EQUAL"
  }
]

רשימת ישויות שנחסמו

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

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

לדוגמה, מגדירים את נקודות הנתונים הבאות עם הטוקנים שצוינו:

A: {}                  // empty set matches everything
B: {red}               // only a 'red' token
C: {blue}              // only a 'blue' token
D: {orange}            // only an 'orange' token
E: {red, blue}         // multiple tokens
F: {red, !blue}        // deny the 'blue' token
G: {red, blue, !blue}  // An unlikely edge-case
H: {!blue}             // deny-only (similar to empty-set)

המערכת פועלת באופן הבא:

  • מרחבי שמות ריקים של שאילתות הם תווים כלליים לחיפוש שתואמים לכל. לדוגמה, Q:{} matches DB:{color:red}.
  • מרחבי שמות ריקים של נקודות נתונים לא תואמים לתווים כלליים לחיפוש. לדוגמה, השאלה:{color:red} לא תואמת למסד הנתונים:{}.

    נקודות של שאילתות ומסדי נתונים.

ציון מרחבי שמות וטוקנים או ערכים בנתוני הקלט

מידע על המבנה הכללי של נתוני הקלט זמין במאמר פורמט ומבנה של נתוני קלט.

בכרטיסיות הבאות מוסבר איך מציינים את מרחבי השמות והאסימונים שמשויכים לכל וקטור קלט.

JSON

  • לכל רשומה של וקטור, מוסיפים שדה בשם restricts, שמכיל מערך של אובייקטים, שכל אחד מהם הוא מרחב שמות.

    • לכל אובייקט צריך להיות שדה בשם namespace. השדה הזה הוא TokenNamespace.namespace, מרחב שמות.
    • הערך של השדה allow, אם הוא קיים, הוא מערך של מחרוזות. מערך המחרוזות הזה הוא רשימת TokenNamespace.string_tokens.
    • הערך של השדה deny, אם הוא קיים, הוא מערך של מחרוזות. מערך המחרוזות הזה הוא רשימת TokenNamespace.string_denylist_tokens.

הנה שתי דוגמאות לרשומות בפורמט JSON:

[
  {
    "id": "42",
    "embedding": [
      0.5,
      1
    ],
    "restricts": [
      {
        "namespace": "class",
        "allow": [
          "cat",
          "pet"
        ]
      },
      {
        "namespace": "category",
        "allow": [
          "feline"
        ]
      }
    ]
  },
  {
    "id": "43",
    "embedding": [
      0.6,
      1
    ],
    "sparse_embedding": {
      "values": [
        0.1,
        0.2
      ],
      "dimensions": [
        1,
        4
      ]
    },
    "restricts": [
      {
        "namespace": "class",
        "allow": [
          "dog",
          "pet"
        ]
      },
      {
        "namespace": "category",
        "allow": [
          "canine"
        ]
      }
    ]
  }
]
  • לכל רשומה של וקטור, מוסיפים שדה בשם numeric_restricts, שיכיל מערך של אובייקטים, שכל אחד מהם הוא הגבלה מספרית.

    • לכל אובייקט צריך להיות שדה בשם namespace. השדה הזה הוא NumericRestrictNamespace.namespace, מרחב שמות.
    • לכל אובייקט צריך להיות אחד מהערכים value_int, value_float ו-value_double.
    • אסור שיהיה לכל אובייקט שדה בשם op. השדה הזה מיועד רק לשאילתות.

הנה שתי דוגמאות לרשומות בפורמט JSON:

[
  {
    "id": "42",
    "embedding": [
      0.5,
      1
    ],
    "numeric_restricts": [
      {
        "namespace": "size",
        "value_int": 3
      },
      {
        "namespace": "ratio",
        "value_float": 0.1
      }
    ]
  },
  {
    "id": "43",
    "embedding": [
      0.6,
      1
    ],
    "sparse_embedding": {
      "values": [
        0.1,
        0.2
      ],
      "numeric_restricts": [
        {
          "namespace": "weight",
          "value_double": 0.3
        }
      ]
    }
  }
]

Avro

רשומות Avro משתמשות בסכימה הבאה:

{
  "type": "record",
  "name": "FeatureVector",
  "fields": [
    {
      "name": "id",
      "type": "string"
    },
    {
      "name": "embedding",
      "type": {
        "type": "array",
        "items": "float"
      }
    },
    {
      "name": "sparse_embedding",
      "type": [
        "null",
        {
          "type": "record",
          "name": "sparse_embedding",
          "fields": [
            {
              "name": "values",
              "type": {
                "type": "array",
                "items": "float"
              }
            },
            {
              "name": "dimensions",
              "type": {
                "type": "array",
                "items": "long"
              }
            }
          ]
        }
      ]
    },
    {
      "name": "restricts",
      "type": [
        "null",
        {
          "type": "array",
          "items": {
            "type": "record",
            "name": "Restrict",
            "fields": [
              {
                "name": "namespace",
                "type": "string"
              },
              {
                "name": "allow",
                "type": [
                  "null",
                  {
                    "type": "array",
                    "items": "string"
                  }
                ]
              },
              {
                "name": "deny",
                "type": [
                  "null",
                  {
                    "type": "array",
                    "items": "string"
                  }
                ]
              }
            ]
          }
        }
      ]
    },
    {
      "name": "numeric_restricts",
      "type": [
        "null",
        {
          "type": "array",
          "items": {
            "name": "NumericRestrict",
            "type": "record",
            "fields": [
              {
                "name": "namespace",
                "type": "string"
              },
              {
                "name": "value_int",
                "type": [ "null", "int" ],
                "default": null
              },
              {
                "name": "value_float",
                "type": [ "null", "float" ],
                "default": null
              },
              {
                "name": "value_double",
                "type": [ "null", "double" ],
                "default": null
              }
            ]
          }
        }
      ],
      "default": null
    },
    {
      "name": "crowding_tag",
      "type": [
        "null",
        "string"
      ]
    }
  ]
}

CSV

  • הגבלות על טוקנים

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

      לדוגמה, color=red,color=blue מייצג את TokenNamespace:

      {
        "namespace": "color"
        "string_tokens": ["red", "blue"]
      }
      
    • לכל רשומה של וקטור, מוסיפים זוגות מופרדים בפסיקים בפורמט name=!value כדי לציין ערך מוחרג להגבלות של מרחב שמות של טוקנים.

      לדוגמה, color=!red מייצג את TokenNamespace:

      {
        "namespace": "color"
        "string_blacklist_tokens": ["red"]
      }
      
  • הגבלות מספריות

    • לכל רשומה של וקטור, מוסיפים זוגות מופרדים בפסיקים בפורמט #name=numericValue עם סיומת של סוג מספר כדי לציין הגבלות של מרחב שמות מספרי.

      הסיומת של סוג המספר היא i עבור int,‏ f עבור float ו-d עבור double. אסור לחזור על אותו שם, כי לכל מרחב שמות צריך להיות משויך ערך יחיד.

      לדוגמה, #size=3i מייצג את NumericRestrictNamespace:

      {
        "namespace": "size"
        "value_int": 3
      }
      

      הערך #ratio=0.1f מייצג את NumericRestrictNamespace:

      {
        "namespace": "ratio"
        "value_float": 0.1
      }
      

      הערך #weight=0.3d מייצג את NumericRestriction:

      {
        "namespace": "weight"
        "value_double": 0.3
      }
      
    • הנה דוגמה לנקודת נתונים עם id: "6",‏ embedding: [7, -8.1],‏ sparse_embedding: {values: [0.1, -0.2, 0.5],‏ dimensions: [40, 901, 1111]}}, תג הצפיפות test, רשימת ההיתרים של הטוקן color: red, blue, רשימת הטוקנים החסומים color: purple וההגבלה המספרית ratio עם הערך הצף 0.1:

      6,7,-8.1,40:0.1,901:-0.2,1111:0.5,crowding_tag=test,color=red,color=blue,color=!purple,
      ratio=0.1f
      

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