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

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

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

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

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

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

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

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

באפליקציה לדוגמה הבאה, וקטורים מתויגים ב-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)

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

  • מרחבי שמות ריקים של שאילתות הם תווים כלליים לחיפוש שתואמים לכל. לדוגמה, שאילתה:{} מתאימה למסד נתונים:{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
      

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