Spaces:
Sleeping
Sleeping
| import numpy as np | |
| from collections import defaultdict | |
| from typing import List, Tuple, Callable | |
| from aimakerspace.openai_utils.embedding import EmbeddingModel | |
| import asyncio | |
| def cosine_similarity(vector_a: np.array, vector_b: np.array) -> float: | |
| """Computes the cosine similarity between two vectors.""" | |
| dot_product = np.dot(vector_a, vector_b) | |
| norm_a = np.linalg.norm(vector_a) | |
| norm_b = np.linalg.norm(vector_b) | |
| return dot_product / (norm_a * norm_b) | |
| class VectorDatabase: | |
| def __init__(self, embedding_model: EmbeddingModel = None): | |
| self.vectors = defaultdict(np.array) | |
| self.embedding_model = embedding_model or EmbeddingModel() | |
| def insert(self, key: str, vector: np.array) -> None: | |
| self.vectors[key] = vector | |
| def search( | |
| self, | |
| query_vector: np.array, | |
| k: int, | |
| distance_measure: Callable = cosine_similarity, | |
| ) -> List[Tuple[str, float]]: | |
| scores = [ | |
| (key, distance_measure(query_vector, vector)) | |
| for key, vector in self.vectors.items() | |
| ] | |
| return sorted(scores, key=lambda x: x[1], reverse=True)[:k] | |
| def search_by_text( | |
| self, | |
| query_text: str, | |
| k: int, | |
| distance_measure: Callable = cosine_similarity, | |
| return_as_text: bool = False, | |
| ) -> List[Tuple[str, float]]: | |
| query_vector = self.embedding_model.get_embedding(query_text) | |
| results = self.search(query_vector, k, distance_measure) | |
| return [result[0] for result in results] if return_as_text else results | |
| def retrieve_from_key(self, key: str) -> np.array: | |
| return self.vectors.get(key, None) | |
| async def abuild_from_list(self, list_of_text: List[str]) -> "VectorDatabase": | |
| embeddings = await self.embedding_model.async_get_embeddings(list_of_text) | |
| for text, embedding in zip(list_of_text, embeddings): | |
| self.insert(text, np.array(embedding)) | |
| return self | |
| if __name__ == "__main__": | |
| list_of_text = [ | |
| "I like to eat broccoli and bananas.", | |
| "I ate a banana and spinach smoothie for breakfast.", | |
| "Chinchillas and kittens are cute.", | |
| "My sister adopted a kitten yesterday.", | |
| "Look at this cute hamster munching on a piece of broccoli.", | |
| ] | |
| vector_db = VectorDatabase() | |
| vector_db = asyncio.run(vector_db.abuild_from_list(list_of_text)) | |
| k = 2 | |
| searched_vector = vector_db.search_by_text("I think fruit is awesome!", k=k) | |
| print(f"Closest {k} vector(s):", searched_vector) | |
| retrieved_vector = vector_db.retrieve_from_key( | |
| "I like to eat broccoli and bananas." | |
| ) | |
| print("Retrieved vector:", retrieved_vector) | |
| relevant_texts = vector_db.search_by_text( | |
| "I think fruit is awesome!", k=k, return_as_text=True | |
| ) | |
| print(f"Closest {k} text(s):", relevant_texts) | |