Discovery article (#459)
* article * Add most images * improve images and text * add preview, icon, and header images * add weird dragon image * Improve analogy * kacper review fixes * improve discovery-search image * switch discovery example, improve triplet loss explanation * better wrapup * more improvements * more improvements * improve readability, thanks to @mjang for the close inspection * Set date to Jan 31st, 2024 at 8AM
@@ -0,0 +1,94 @@
|
||||
---
|
||||
title: "Discovery needs context" #required
|
||||
short_description: Discover points by constraining the space
|
||||
description: Qdrant released a new functionality that lets you constrain the space in which a search is performed, relying only pure vectors #required
|
||||
social_preview_image: /articles_data/discovery-search/social_preview.jpg # This image will be used in social media previews, should be 1200x630px. Required.
|
||||
small_preview_image: /articles_data/discovery-search/icon.svg # This image will be used in the list of articles at the footer, should be 40x40px
|
||||
preview_dir: /articles_data/discovery-search/preview # This directory contains images that will be used in the article preview. They can be generated from one image. Read more below. Required.
|
||||
weight: -100 # This is the order of the article in the list of articles at the footer. The lower the number, the higher the article will be in the list.
|
||||
author: Luis Cossío # Author of the article. Required.
|
||||
author_link: https://coszio.github.io # Link to the author's page. Required.
|
||||
date: 2024-01-31T08:00:00+03:00 # Date of the article. Required.
|
||||
draft: false # If true, the article will not be published
|
||||
keywords: # Keywords for SEO
|
||||
- why use a vector database
|
||||
- specialty
|
||||
- search
|
||||
- discovery
|
||||
- state of the art
|
||||
- vector search
|
||||
---
|
||||
|
||||
When Christopher Columbus and his crew sailed to cross the Atlantic Ocean, they were not looking for America. They were looking for a new route to India, and they were convinced that the Earth was round. They didn't know anything about America, but since they were going west, they stumbled upon it.
|
||||
|
||||
They couldn't reach their _target_, because the geography didn't let them, but once they realized it wasn't India, they claimed it a new "discovery" for their crown. If we consider that sailors need water to sail, then we can establish a _context_ which is positive in the water, and negative on land. Once the sailor's search was stopped by the land, they could not go any further, and a new route was found. Let's keep this concepts of _target_ and _context_ in mind as we explore the new functionality of Qdrant: __Discovery search__.
|
||||
|
||||
In version 1.7, Qdrant [released](/articles/qdrant-1.7.x/) this novel API that lets you constrain the space in which a search is performed, relying only on pure vectors. This is a powerful tool that lets you explore the vector space in a more controlled way. It can be used to find points that are not necessarily closest to the target, but are still relevant to the search.
|
||||
|
||||
You can already select which points are available to the search by using payload filters. This by itself is very versatile because it allows us to craft complex filters that show only the points that satisfy their criteria deterministically. However, the payload associated with each point is arbitrary and cannot tell us anything about their position in the vector space. In other words, filtering out irrelevant points can be seen as creating a _mask_ rather than a hyperplane –cutting in between the positive and negative vectors– in the space.
|
||||
|
||||
This is where a __vector _context___ can help. We define _context_ as a list of pairs. Each pair is made up of a positive and a negative vector. With a context, we can define hyperplanes within the vector space, which always prefer the positive over the negative vectors. This effectively partitions the space where the search is performed. After the space is partitioned, we then need a _target_ to return the points that are more similar to it.
|
||||
|
||||

|
||||
|
||||
While positive and negative vectors might suggest the use of the <a href="/documentation/concepts/explore/#recommendation-api" target="_blank">recommendation interface</a>, in the case of _context_ they require to be paired up in a positive-negative fashion. This is inspired from the machine-learning concept of <a href="https://en.wikipedia.org/wiki/Triplet_loss" target="_blank">_triplet loss_</a>, where you have three vectors: an anchor, a positive, and a negative. Triplet loss is an evaluation of how much the anchor is closer to the positive than to the negative vector, so that learning happens by "moving" the positive and negative points to try to get a better evaluation. However, during discovery, we consider the positive and negative vectors as static points, and we search through the whole dataset for the "anchors", or result cantidates, which fit this characteristic better.
|
||||
|
||||

|
||||
|
||||
[__Discovery search__](#discovery-search), then, is made up of two main inputs:
|
||||
|
||||
- __target__: the main point of interest
|
||||
- __context__: the pairs of positive and negative points we just defined.
|
||||
|
||||
However, it is not the only way to use it. Alternatively, you can __only__ provide a context, which invokes a [__Context Search__](#context-search). This is useful when you want to explore the space defined by the context, but don't have a specific target in mind. But hold your horses, we'll get to that [later ↪](#context-search).
|
||||
|
||||
## Discovery search
|
||||
|
||||
Let's talk about the first case: context with a target.
|
||||
|
||||
To understand why this is useful, let's take a look at a real-world example: using a multimodal encoder like [CLIP](https://openai.com/blog/clip/) to search for images, from text __and__ images.
|
||||
CLIP is a neural network that can embed both images and text into the same vector space. This means that you can search for images using either a text query or an image query. For this example, we'll reuse our [food recommendations demo](https://food-discovery.qdrant.tech/) by typing "burger" in the text input:
|
||||
|
||||

|
||||
|
||||
This is basically nearest neighbor search, and while technically we have only images of burgers, one of them is a logo representation of a burger. We're looking for actual burgers, though. Let's try to exclude images like that by adding it as a negative example:
|
||||
|
||||

|
||||
|
||||
Wait a second, what has just happened? These pictures have __nothing__ to do with burgers, and still, they appear on the first results. Is the demo broken?
|
||||
|
||||
Turns out, multimodal encoders <a href="https://modalitygap.readthedocs.io/en/latest/" target="_blank">might not work how you expect them to</a>. Images and text are embedded in the same space, but they are not necessarily close to each other. This means that we can create a mental model of the distribution as two separate planes, one for images and one for text.
|
||||
|
||||

|
||||
|
||||
This is where discovery excels, because it allows us to constrain the space considering the same mode (images) while using a target from the other mode (text).
|
||||
|
||||

|
||||
|
||||
Discovery also lets us keep giving feedback to the search engine in the shape of more context pairs, so we can keep refining our search until we find what we are looking for.
|
||||
|
||||
Another intuitive example: imagine you're looking for a fish pizza, but pizza names can be confusing, so you can just type "pizza", and prefer a fish over meat. Discovery search will let you use these inputs to suggest a fish pizza... even if it's not called fish pizza!
|
||||
|
||||

|
||||
|
||||
## Context search
|
||||
|
||||
Now, second case: only providing context.
|
||||
|
||||
Ever been caught in the same recommendations on your favourite music streaming service? This may be caused by getting stuck in a similarity bubble. As user input gets more complex, diversity becomes scarce, and it becomes harder to force the system to recommend something different.
|
||||
|
||||

|
||||
|
||||
__Context search__ solves this by de-focusing the search around a single point. Instead, it selects points randomly from within a zone in the vector space. This search is the most influenced by _triplet loss_, as the score can be thought of as _"how much a point is closer to a negative than a positive vector?"_. If it is closer to the positive one, then its score will be zero, same as any other point within the same zone. But if it is on the negative side, it will be assigned a more and more negative score the further it gets.
|
||||
|
||||

|
||||
|
||||
Creating complex tastes in a high-dimensional space becomes easier, since you can just add more context pairs to the search. This way, you should be able to constrain the space enough so you select points from a per-search "category" created just from the context in the input.
|
||||
|
||||

|
||||
|
||||
This way you can give refeshing recommendations, while still being in control by providing positive and negative feedback, or even by trying out different permutations of pairs.
|
||||
|
||||
## Wrapping up
|
||||
|
||||
Discovery search is a powerful tool that lets you explore the vector space in a more controlled way. It can be used to find points that are not necessarily close to the target, but are still relevant to the search. It can also be used to represent complex tastes, and break out of the similarity bubble. Check out the [documentation](/documentation/concepts/explore/#discovery-api) to learn more about the math behind it and how to use it.
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: Vector Similarity beyond Search
|
||||
short_description: Harnessing the full capabilities of vector embeddings
|
||||
description: We explore some of the promissing new techniques that can be used to expand use-cases of unstructured data and unlock new similarities-based data exploration tools.
|
||||
description: We explore some of the promising new techniques that can be used to expand use-cases of unstructured data and unlock new similarities-based data exploration tools.
|
||||
preview_dir: /articles_data/vector-similarity-beyond-search/preview
|
||||
small_preview_image: /articles_data/vector-similarity-beyond-search/icon.svg
|
||||
social_preview_image: /articles_data/vector-similarity-beyond-search/preview/social_preview.jpg
|
||||
|
||||
@@ -587,12 +587,12 @@ In this API, Qdrant introduces the concept of `context`, which is used for split
|
||||
The interface for providing context is similar to the recommendation API (ids or raw vectors). Still, in this case, they need to be provided in the form of positive-negative pairs.
|
||||
|
||||
Discovery API lets you do two new types of search:
|
||||
- **Discovery search**: Uses a target and context pairs of examples to get the points closest to the target, but constrained by the context.
|
||||
- **Discovery search**: Uses the context (the pairs of positive-negative vectors) and a target to return the points more similar to the target, but constrained by the context.
|
||||
- **Context search**: Using only the context pairs, get the points that live in the best zone, where loss is minimized
|
||||
|
||||
The way positive and negative examples should be arranged in the context pairs is completely up to you. So you can have the flexibility of trying out different permutation techniques based on your model and data.
|
||||
|
||||
<aside role="alert">The speed of search is linearly related to the amount of examples</aside>
|
||||
<aside role="alert">The speed of search is linearly related to the amount of examples you provide in the query.</aside>
|
||||
|
||||
### Discovery search
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 157 KiB |
|
After Width: | Height: | Size: 714 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 955 KiB |
|
After Width: | Height: | Size: 64 KiB |
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.0"
|
||||
width="512.000000pt"
|
||||
height="512.000000pt"
|
||||
viewBox="0 0 512.000000 512.000000"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
id="svg18"
|
||||
sodipodi:docname="earth-grid.svg"
|
||||
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs22" />
|
||||
<sodipodi:namedview
|
||||
id="namedview20"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#999999"
|
||||
borderopacity="1"
|
||||
inkscape:pageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="true"
|
||||
inkscape:document-units="pt"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.42267342"
|
||||
inkscape:cx="-4.7317856"
|
||||
inkscape:cy="676.64535"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1011"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g16" />
|
||||
<g
|
||||
transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000"
|
||||
stroke="none"
|
||||
id="g16">
|
||||
<path
|
||||
d="M773 5109 c-297 -35 -568 -258 -658 -541 -65 -206 -49 -422 46 -611 28 -55 90 -144 314 -452 126 -172 150 -220 185 -360 37 -150 55 -182 120 -215 92 -48 215 -13 263 75 6 11 23 72 39 135 15 63 39 137 52 165 14 27 108 165 210 305 217 300 241 337 277 439 89 252 51 515 -106 736 -165 232 -454 358 -742 324z m237 -160 c80 -15 225 -89 292 -149 78 -69 151 -182 184 -283 23 -69 28 -100 28 -197 1 -201 -25 -256 -290 -620 -102 -140 -203 -290 -224 -333 -21 -43 -48 -122 -61 -175 -28 -126 -32 -134 -72 -130 l-32 3 -30 120 c-16 66 -44 150 -62 185 -17 36 -120 187 -228 335 -205 284 -244 349 -271 455 -22 86 -22 236 0 319 72 269 289 450 581 484 37 5 112 -1 185 -14z"
|
||||
id="path2"
|
||||
style="fill:#ffffff" />
|
||||
<path
|
||||
d="M724 4716 c-74 -27 -105 -49 -167 -115 -151 -161 -144 -425 15 -584 247 -246 663 -108 720 239 18 104 -20 260 -67 278 -32 12 -62 6 -83 -17 -26 -28 -27 -51 -6 -124 38 -129 -21 -259 -146 -324 -69 -36 -176 -33 -248 6 -95 52 -142 132 -142 242 0 162 113 272 278 273 64 0 76 3 97 25 14 13 25 36 25 50 0 14 -11 37 -25 50 -22 23 -32 25 -107 24 -61 0 -99 -6 -144 -23z"
|
||||
id="path4"
|
||||
style="fill:#ffffff" />
|
||||
<path
|
||||
d="M4038 5110 c-139 -25 -263 -88 -368 -187 -84 -79 -114 -127 -104 -167 8 -31 23 -44 61 -52 28 -5 38 2 119 83 64 63 108 97 155 120 184 90 392 80 559 -28 167 -107 260 -280 260 -479 0 -142 -35 -237 -139 -379 -34 -47 -61 -95 -61 -108 0 -33 42 -73 78 -73 33 0 57 23 125 121 104 148 147 278 147 443 0 119 -18 201 -64 299 -88 190 -264 339 -461 392 -71 19 -240 28 -307 15z"
|
||||
id="path6"
|
||||
style="fill:#ffffff" />
|
||||
<path
|
||||
d="M2335 4820 c-214 -16 -498 -77 -543 -115 -47 -40 -23 -125 36 -125 14 0 82 14 153 32 71 17 131 29 134 27 3 -3 -11 -45 -30 -92 -67 -167 -160 -530 -191 -749 -3 -27 -8 -48 -10 -48 -32 0 -247 -33 -267 -42 -51 -20 -61 -70 -23 -115 l24 -27 121 15 121 15 0 -26 c-1 -14 -7 -81 -14 -150 -7 -69 -10 -134 -6 -145 12 -31 37 -48 72 -47 57 1 67 23 83 183 22 207 18 197 73 206 61 10 815 10 864 0 27 -6 39 -14 43 -30 17 -74 50 -511 61 -789 l7 -178 -547 0 -546 0 7 193 c6 190 6 194 -15 215 -32 32 -85 29 -111 -4 -17 -22 -21 -41 -21 -109 0 -45 -3 -130 -7 -188 l-6 -107 -379 0 -378 0 0 50 c0 37 -5 55 -20 70 -53 53 -130 9 -130 -76 l0 -44 -262 0 -261 0 6 98 c8 119 38 289 72 405 32 110 32 130 -1 156 -33 26 -65 27 -93 4 -36 -30 -96 -267 -121 -478 -14 -115 -14 -404 0 -520 63 -523 285 -980 655 -1350 302 -302 645 -498 1050 -600 191 -48 350 -67 560 -67 241 0 422 24 641 87 123 36 334 121 361 147 31 29 30 72 -2 104 -14 14 -25 29 -25 35 0 5 -11 21 -25 34 -43 44 -68 34 -164 -60 -82 -80 -92 -86 -167 -109 -100 -30 -234 -60 -240 -54 -2 3 7 29 20 59 39 90 102 295 139 460 53 231 53 234 23 264 -32 32 -75 33 -103 2 -14 -14 -27 -53 -38 -107 -46 -238 -115 -467 -187 -621 l-40 -86 -106 -5 c-59 -3 -145 -3 -192 1 l-85 6 -37 75 c-70 140 -152 417 -198 670 -11 63 -22 122 -24 131 -3 15 26 16 338 12 187 -3 392 -1 455 5 100 8 117 12 133 32 24 29 23 69 -3 96 l-20 22 -332 -5 c-290 -4 -578 5 -593 20 -16 16 -57 499 -69 820 l-7 167 624 0 c614 0 625 0 646 20 30 29 29 82 -2 112 -23 22 -24 29 -35 293 -10 238 -23 405 -47 636 l-6 66 98 -13 c186 -26 551 -102 595 -125 9 -5 19 -19 21 -31 46 -211 69 -328 77 -398 16 -122 18 -128 51 -145 37 -19 76 -11 97 22 14 21 15 36 4 123 -7 54 -25 160 -40 235 l-28 136 25 -6 c83 -21 317 -126 449 -203 l61 -35 25 -101 c14 -56 30 -135 36 -176 7 -41 14 -90 17 -108 6 -38 39 -72 70 -72 12 0 33 9 48 21 33 26 34 71 6 225 -167 922 -876 1649 -1787 1833 -188 38 -437 55 -618 41z m301 -150 l51 0 41 -87 c74 -162 154 -435 197 -678 8 -49 18 -99 20 -110 4 -20 -1 -20 -449 -20 l-453 0 19 105 c52 292 146 608 220 743 l23 42 75 6 c41 4 104 5 140 3 36 -2 88 -4 116 -4z m324 -45 c36 -8 104 -27 153 -42 86 -26 89 -28 171 -113 187 -194 340 -439 451 -724 24 -61 42 -112 41 -114 -2 -1 -51 9 -110 23 -113 27 -331 66 -476 85 l-85 11 -23 132 c-45 255 -126 555 -188 696 -13 29 -24 55 -24 57 0 7 24 4 90 -11z m747 -327 c230 -158 448 -386 597 -628 57 -92 146 -262 146 -280 0 -6 -17 -2 -37 9 -77 39 -241 106 -348 142 l-110 36 -37 106 c-79 228 -174 424 -292 600 -36 55 -66 101 -66 104 0 6 59 -30 147 -89z m-2813 -1950 c9 -165 33 -354 66 -518 15 -74 26 -137 24 -139 -12 -14 -354 137 -471 207 l-61 37 -21 87 c-32 129 -50 241 -58 351 l-6 97 260 0 260 0 7 -122z m910 -35 c10 -243 26 -484 41 -637 20 -185 20 -184 -7 -180 -234 36 -318 50 -448 79 -243 54 -226 47 -244 108 -45 156 -89 441 -102 665 l-7 122 381 0 380 0 6 -157z m-904 -754 l135 -47 52 -143 c68 -187 183 -418 276 -558 41 -61 72 -111 70 -111 -3 0 -49 28 -102 63 -315 207 -567 489 -738 825 -29 58 -53 108 -53 113 0 4 51 -16 113 -44 61 -28 173 -72 247 -98z m422 -123 c124 -29 292 -60 447 -81 63 -8 116 -16 117 -18 0 -1 11 -58 23 -127 45 -257 111 -506 176 -668 19 -47 33 -87 30 -90 -6 -6 -147 26 -239 55 -69 22 -89 33 -144 87 -161 154 -339 420 -441 661 -39 93 -81 205 -76 205 2 0 50 -11 107 -24z"
|
||||
id="path8"
|
||||
style="fill:#ffffff" />
|
||||
<path
|
||||
d="M4041 4744 c-134 -47 -208 -147 -151 -204 31 -31 75 -26 122 15 53 45 96 58 169 53 47 -3 66 -10 96 -35 103 -82 120 -192 46 -299 -48 -71 -25 -134 48 -134 30 0 43 6 65 33 72 84 100 216 70 323 -46 162 -180 264 -346 263 -41 0 -95 -7 -119 -15z"
|
||||
id="path10"
|
||||
style="fill:#ffffff" />
|
||||
<path
|
||||
d="M3860 2701 c-367 -80 -664 -376 -748 -745 -25 -112 -22 -328 7 -441 39 -156 75 -202 138 -176 51 21 57 51 28 142 -36 114 -48 210 -42 314 14 199 84 363 217 507 106 115 204 179 352 229 80 28 111 33 223 37 109 3 144 1 220 -17 300 -72 537 -305 616 -606 43 -166 23 -385 -51 -542 -36 -77 -43 -89 -310 -458 -119 -165 -229 -320 -243 -345 -40 -68 -76 -173 -103 -295 -26 -118 -50 -155 -98 -155 -47 0 -63 28 -99 177 -22 90 -50 173 -75 225 -51 105 -434 635 -468 648 -27 11 -63 0 -84 -24 -33 -40 -19 -66 182 -343 108 -149 213 -302 233 -342 22 -44 47 -121 66 -199 36 -153 52 -194 95 -231 75 -67 182 -77 268 -27 68 40 91 84 125 236 21 93 43 160 70 215 24 47 139 217 280 410 253 347 312 446 350 585 143 524 -151 1049 -674 1206 -122 36 -345 44 -475 15z"
|
||||
id="path12"
|
||||
style="fill:#ffffff" />
|
||||
<path
|
||||
d="M3960 2249 c-63 -12 -178 -71 -233 -119 -178 -157 -223 -431 -104 -639 46 -81 136 -165 222 -206 197 -95 414 -60 576 92 106 100 159 223 159 368 0 327 -295 567 -620 504z m257 -174 c74 -32 153 -110 185 -182 18 -38 22 -67 22 -143 1 -84 -2 -102 -28 -157 -31 -68 -98 -138 -162 -171 -218 -110 -479 22 -523 264 -33 182 89 368 273 415 61 16 167 4 233 -26z"
|
||||
id="path14"
|
||||
style="fill:#ffffff" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 197 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 144 KiB |
|
After Width: | Height: | Size: 512 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 64 KiB |