When you swap the queries between the 2 examples above, and use every one with the opposite’s embedding, each will produce the incorrect consequence. This demonstrates the truth that every methodology has its strengths but in addition its weaknesses. Hybrid search combines the 2, aiming to leverage one of the best from each worlds. By indexing information with each dense and sparse embeddings, we will carry out searches that take into account each semantic relevance and key phrase matching, balancing outcomes primarily based on customized weights. Once more, the interior implementation is extra sophisticated, however langchain-milvus makes it fairly easy to make use of. Let’s take a look at how this works:
vector_store = Milvus(
embedding_function=[
sparse_embedding,
dense_embedding,
],
connection_args={"uri": "./milvus_hybrid.db"},
auto_id=True,
)
vector_store.add_texts(paperwork)
On this setup, each sparse and dense embeddings are utilized. Let’s check the hybrid search with equal weighting:
question = "Does Scorching cowl climate modifications throughout weekends?"
hybrid_output = vector_store.similarity_search(
question=question,
ok=1,
ranker_type="weighted",
ranker_params={"weights": [0.49, 0.51]}, # Mix each outcomes!
)
print(f"Hybrid search outcomes:n{hybrid_output[0].page_content}")# output: Hybrid search outcomes:
# In Israel, Scorching is a TV supplier that broadcast 7 days per week
This searches for related outcomes utilizing every embedding operate, offers every rating a weight, and returns the consequence with one of the best weighted rating. We are able to see that with barely extra weight to the dense embeddings, we get the consequence we desired. That is true for the second question as properly.
If we give extra weight to the dense embeddings, we are going to as soon as once more get non-relevant outcomes, as with the dense embeddings alone:
question = "When and the place is Scorching lively?"
hybrid_output = vector_store.similarity_search(
question=question,
ok=1,
ranker_type="weighted",
ranker_params={"weights": [0.2, 0.8]}, # Be aware -> the weights modified
)
print(f"Hybrid search outcomes:n{hybrid_output[0].page_content}")# output: Hybrid search outcomes:
# At this time was very heat throughout the day however chilly at evening
Discovering the proper steadiness between dense and sparse will not be a trivial job, and might be seen as a part of a wider hyper-parameter optimization downside. There’s an ongoing analysis and instruments that making an attempt to resolve such points on this space, for instance IBM’s AutoAI for RAG.
There are various extra methods you may adapt and use the hybrid search strategy. For example, if every doc has an related title, you possibly can use two dense embedding features (presumably with completely different fashions) — one for the title and one other for the doc content material — and carry out a hybrid search on each indices. Milvus presently helps as much as 10 completely different vector fields, offering flexibility for complicated functions. There are additionally further configurations for indexing and reranking strategies. You possibly can see Milvus documentation concerning the obtainable params and choices.