En esta publicación de blog, lo guiaré a través de los fundamentos de las bases de datos vectoriales, la búsqueda de vectores y el paquete Langchain en Python, que facilita el almacenamiento y la recuperación de vectores comparables.
Para embarcarnos en nuestro viaje, comenzaremos con un concepto fundamental conocido como "Incrustaciones".
En este artículo, exploraremos el concepto de incrustaciones, un aspecto fundamental del aprendizaje automático que nos permite representar datos textuales en un formato que las máquinas puedan comprender fácilmente.
Básicamente, las incrustaciones sirven como representaciones vectoriales de texto, convirtiendo la intrincada red de palabras, oraciones y pasajes en un formato numérico que las máquinas pueden procesar.
Surge una cuestión apremiante: ¿pueden los humanos descifrar estas incrustaciones? La respuesta es no. Las incrustaciones son esencialmente secuencias de números que encapsulan información textual.
En consecuencia, comprender y trabajar con un vector de incrustación puede ser una tarea desalentadora para los humanos, mientras que las máquinas la manejan con facilidad.
Existe una gran variedad de técnicas para generar incrustaciones a partir de texto. Los métodos notables incluyen TF-IDF, Word2Vec, Glove y BERT, entre otros. En el ámbito contemporáneo del aprendizaje automático, las incrustaciones de oraciones han ganado popularidad sobre las incrustaciones de palabras.
Estas incrustaciones de oraciones, que representan la esencia de un texto, se pueden obtener a partir de modelos de transformadores de oraciones previamente entrenados como "all-MiniLM-L6-V2" y "all-mpnet-base-v2".
Estos modelos producen incrustaciones con dimensiones fijas, normalmente 384 o 768 dimensiones, para un texto determinado.
Ahora que hemos explorado los fundamentos de las incrustaciones y varias técnicas para su generación, cambiemos nuestro enfoque al desafío de almacenar estos vectores de incrustación de alta dimensión en un almacén de vectores.
Un almacén de datos vectoriales es una base de datos especializada diseñada para almacenar representaciones integradas de alta dimensión de diversos tipos de datos, incluidos audio, video, imágenes, texto y más.
Una de sus funcionalidades principales es la capacidad de buscar de manera eficiente vectores dentro de la tienda que se parezcan mucho a un vector de consulta determinado.
Los almacenes de vectores agilizan el proceso de almacenar incrustaciones y realizar búsquedas de similitud entre estos vectores, simplificando la gestión y recuperación de representaciones de datos de alta dimensión.
En el ámbito de las incrustaciones de vectores, la búsqueda de similitud implica cuantificar la proximidad o relación entre dos o más incrustaciones. Normalmente, esto se logra calculando la similitud utilizando varias métricas de distancia. Algunas métricas de distancia comúnmente utilizadas y ampliamente reconocidas incluyen la distancia euclidiana, la distancia de Manhattan y la distancia del coseno, entre otras. Estas métricas nos ayudan a medir el grado de similitud o disimilitud entre vectores, facilitando búsquedas efectivas de similitud dentro de los datos.
Por ejemplo, al determinar la similitud o cercanía entre dos puntos en un gráfico, comúnmente se emplea la distancia euclidiana. Esta distancia se puede calcular usando la siguiente fórmula:
Distancia euclidiana = [(x2 - x1)^2 + (y2 - y1)^2]^0.5
Aquí, (x1, y1) representa las coordenadas del primer punto y (x2, y2) representa las coordenadas del segundo punto en el gráfico. El resultado de este cálculo proporciona una medida de la separación espacial entre los dos puntos, indicando su similitud o diferencia en términos de sus posiciones dentro del gráfico.
De manera similar, en la búsqueda de similitudes, las incrustaciones se representan dentro de un espacio de alta dimensión, y cada registro sirve como un punto de datos.
La siguiente línea de código demuestra cómo recuperar las cinco incrustaciones similares principales para unos datos de entrada determinados:
distance, n = vector_store.search(input_embedding, k=5)
Este código devolvería una lista de las 5 incrustaciones principales que se parecen mucho a los datos de entrada, lo que lo convierte en una herramienta valiosa para diversas aplicaciones, como sistemas de recomendación, recuperación de contenido y más.
La salida de la función vector_store.search() comprende las k incrustaciones similares top-k junto con sus respectivas distancias desde input_embedding. El parámetro "k" es un valor configurable que determina el número de incrustaciones más cercanas que se recuperarán en la búsqueda de similitud. Puede configurar "k" para controlar la cantidad deseada de resultados devueltos por la operación de búsqueda.
Ahora que hemos establecido una comprensión fundamental de las tiendas de vectores, procedamos a profundizar en el paquete LangChain y FAISS. Estas herramientas mejorarán aún más nuestra capacidad para trabajar con incrustaciones de alta dimensión y realizar búsquedas de similitudes eficientes.
En pocas palabras, LangChain es un marco diseñado para crear aplicaciones que aprovechan las capacidades de los modelos de lenguajes grandes (LLM). Para obtener información y recursos más detallados, puede consultar la documentación oficial de LangChain.
Por el contrario, FAISS, que significa "Facebook AI Similarity Search", es una biblioteca de Python que proporciona a los desarrolladores un medio rápido y eficiente para buscar incrustaciones similares, alejándose de los enfoques convencionales basados en hash.
Esta biblioteca fue desarrollada por el equipo de inteligencia artificial de Facebook y ofrece poderosas capacidades para tareas de búsqueda de similitudes en espacios de alta dimensión.
FAISS es una biblioteca de código abierto que puede alojarse en su propio servidor.
En nuestra exploración de LangChain y FAISS, ahora intentaremos implementar FAISS dentro del marco de LangChain. A continuación se muestran algunas API clave de la integración FAISS de LangChain en las que nos centraremos en este artículo:
add_documents() : Esta función nos permite incorporar documentos adicionales al almacén de vectores.
add_embeddings() : permite agregar más incrustaciones al almacén de vectores.
from_documents() : esta API devuelve un VectorStore basado en los documentos proporcionados.
from_embeddings() : esta función proporciona un índice FAISS generado a partir de las incrustaciones dadas.
load_local() : use esto para cargar el índice FAISS desde el disco.
save_local() : Le permite guardar un índice FAISS en el disco.
similarity_search() : esta función recupera los documentos que son más similares a una consulta determinada.
similarity_search_by_vector() : recupera los documentos que son más similares a una incrustación determinada.
Estas API forman la base para combinar las capacidades de LangChain con FAISS, lo que le permite trabajar con incrustaciones y realizar búsquedas de similitudes eficientes dentro de sus aplicaciones.
El metafiltrado es una técnica valiosa que se utiliza para refinar los resultados de una consulta de búsqueda en LangChain FAISS. Normalmente existen dos tipos de metafiltrado: prefiltrado y posfiltrado. En nuestro marco, admitimos específicamente el filtrado posterior para consultas de búsqueda.
Es importante tener en cuenta que el concepto de metafiltrado para los resultados de búsqueda es una característica disponible en la versión LangChain de FAISS y no está presente en la implementación original de FAISS. Esta capacidad de posfiltrado mejora la precisión y relevancia de los resultados de búsqueda, ofreciendo resultados más personalizados a los usuarios.
Armados con el conocimiento de las API de LangChain FAISS, profundicemos en la implementación de Python de LangChain FAISS. Esta implementación le permitirá trabajar con incrustaciones, realizar búsquedas de similitudes y aplicar técnicas de posfiltrado para ajustar los resultados de su búsqueda dentro del marco de LangChain.
Siéntase libre de explorar y aprovechar estas capacidades para crear aplicaciones que aprovechen el poder de los modelos de lenguaje grandes y la búsqueda avanzada de similitudes con FAISS.
En esta guía instructiva, elegimos el conjunto de datos de Stanford como conjunto de datos base y agregamos algunas columnas para mostrar el trabajo del metafiltrado en LangChain FAISS.
Comenzaremos instalando e importando los paquetes necesarios.
!pip install langchain[all] !pip3 install Langchain[FAISS] !pip install faiss-cpu # WARNING: langchain 0.0.74 does not provide the extra 'faiss'
from langchain import FAISS import pandas as pd import numpy as np import os import time import pickle
Ahora importaremos el conjunto de datos:
passage_data = pd.read_csv("/Users/shyam/Python_Programs/Text Similarity Codes/Standford_Edited.csv") passage_data.drop(columns=["Unnamed: 0"],axis=1, inplace=True) passage_data
Teniendo el conjunto de datos, necesitamos inicializar una función de incrustación para convertir los datos de texto en vectores. Usamos “transformadores de oraciones/todo-MiniLM-L6-V2” que genera incrustaciones en 384 dimensiones,
from langchain.embeddings import SentenceTransformerEmbeddings embedding_function = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
Estableceremos la información de metadatos. En los metadatos, hemos agregado el ID del documento y el idioma del documento para cada incrustación (contenido),
start=time.time() metadatas = [] for index, row in passage_data.iterrows(): doc_meta = { "id": row['Id'], "language": row['Language'] } metadatas.append(doc_meta)
Eso es todo... Construiremos nuestro índice FAISS ahora.
faiss = FAISS.from_texts(passage_data['Content'].tolist(), embedding_function, metadatas) print("Time Taken --> ", time.time()-start)
Ahora intentaremos guardar el índice FAISS en el disco y volver a cargarlo:
faiss.save_local("/Users/shyam/Python_Programs/LangChain_FAISS", "Standford") loaded_faiss = faiss.load_local("/Users/shyam/Python_Programs/LangChain_FAISS",embedding_function, "Standford")
Hemos terminado con la creación, el almacenamiento y la carga del índice FAISS. Es tiempo de inferencia. Intentaremos buscar algunas consultas y probar el índice FAISS.
Primero, obtendremos los cinco principales documentos similares relacionados con el "ateísmo".
start=time.time() loaded_faiss.similarity_search_with_score("What is atheism?",5)
Bueno, los resultados son convincentes. Pero aún así, exploraremos más...
Esta vez, intentaremos realizar una consulta en otro idioma con algunos metafiltrados. Haremos una consulta en ruso indicando que el criterio de filtrado debe ser {lang: 'ru_RU'}.
#Что такое атеизм? - Russian loaded_faiss.similarity_search_with_score("Что такое атеизм?",5, {"language":"ru_RU"}, 10)
Aquí, mencionamos tomar los diez documentos más similares del almacén de vectores y luego aplicar nuestra condición de filtrado para obtener los cinco documentos principales para nuestra consulta.
Al concluir este artículo, confío en que haya adquirido una sólida comprensión de los almacenes de vectores y la búsqueda de vectores. También proporcionamos una demostración de LangChain FAISS para ilustrar su funcionalidad.
Le recomiendo encarecidamente que explore otras tiendas de vectores como ChromaDb, Qdrant, Milvus y más.
Cada tienda de vectores viene con su conjunto único de ventajas y desventajas, así que haga su selección en función de los requisitos específicos de su caso de uso.
¡Le deseamos un viaje de aprendizaje agradable y fructífero!