Eine minimale Vektordatenbank für Bildungszwecke.
Slogan: Halten Sie es einfach und sie werden lernen ...
Möchten Sie mehr lernen? Schauen Sie sich den Abschnitt "Referenzen" unten an?

In diesem Beispiel verwenden wir den Datensatz der Grundschule Math 8K (GSM8K)
from datasets import load_dataset
# Number of samples we want to process
N_SAMPLES = 100
# Load dataset
# https://huggingface.co/datasets/openai/gsm8k
ds = load_dataset ( "openai/gsm8k" , "main" , split = "train" )[: N_SAMPLES ]
questions = ds [ 'question' ]
answers = ds [ 'answer' ] die "qualitativ hochwertige sprachlich vielfältige Mathematikwortprobleme" in Form von question-answer enthält, wie die unten gezeigten
### Question
Natalia sold clips to 48 of her friends in April, and then she sold half as many clips in May.
How many clips did Natalia sell altogether in April and May?
### Answer
Natalia sold 48/2 = <<48/2=24>>24 clips in May.
Natalia sold 48+24 = <<48+24=72>>72 clips altogether in April and May. #### 72
Unser Ziel ist es, diese question-answer in Einbettungen zu verwandeln, sie in Vektordb zu speichern und einige Operationen auszuführen.
Einbettungen sind nur numerische Darstellungen einer Information, normalerweise in Form von Vektoren. Sie können irgendwelche Daten in Einbettung umwandeln (z. B.? Umpf?) Und sie erhalten die Bedeutung der ursprünglichen Daten. Wenn Sie mehr über Einbettungen erfahren möchten , sehen Sie sich die Mapping -Einbettungen an: von Bedeutung zu Vektoren und zurück.
Definieren wir eine Helferfunktion, um Cohere -Embett -Modelle über das Amazon -Grundgestein aufzurufen
import json
import boto3
# Initialize Bedrock client
bedrock = boto3 . client ( "bedrock-runtime" )
def embed ( texts : list , model_id = "cohere.embed-english-v3" ):
"""Generates embeddings for an array of strings using Cohere Embed models."""
model_provider = model_id . split ( '.' )[ 0 ]
assert model_provider == "cohere" ,
f"Invalid model provider (Got: { model_provider } , Expected: cohere)"
# Prepare payload
accept = "*/*"
content_type = "application/json"
body = json . dumps ({
'texts' : texts ,
'input_type' : "search_document"
})
# Call model
response = bedrock . invoke_model (
body = body ,
modelId = model_id ,
accept = accept ,
contentType = content_type
)
# Process response
response_body = json . loads ( response . get ( 'body' ). read ())
return response_body . get ( 'embeddings' )und verwenden Sie es, um Einbettungen für eine kleine Teilmenge unserer Daten zu generieren (nur Antworten, vorerst)
from tqdm import tqdm
# Text call limit for Cohere Embed models via Amazon Bedrock
# https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-embed.html
MAX_TEXTS_PER_CALL = 96
embeddings = []
for idx in tqdm ( range ( 0 , len ( answers ), MAX_TEXTS_PER_CALL ), "Generating embeddings" ):
embeddings += embed ( answers [ idx : idx + MAX_TEXTS_PER_CALL ])Wir sind jetzt bereit, Vektordb zu initialisieren und Daten zu laden
from vektordb import ANNVectorDatabase
from vektordb . types import Vector
# Initialize database
vector_db = ANNVectorDatabase ()
# Load embeddings into the database
for idx in tqdm ( range ( len ( embeddings )), "Loading embeddings" ):
vector_db . insert ( idx , Vector ( embeddings [ idx ], { 'answer' : answers [ idx ][: 20 ]}))Als Vernunftprüfung können wir ein kleines Beispiel unserer Datenbank drucken
vector_db . display (
np_format = {
'edgeitems' : 1 ,
'precision' : 5 ,
'threshold' : 3 ,
'suppress' : True
},
keys = range ( 10 )
) +-----+-------------------------+------------------------------------+
| Key | Data | Metadata |
+-----+-------------------------+------------------------------------+
| 0 | [-0.00618 ... -0.00047] | {'answer': 'Natalia sold 48/2 = '} |
| 1 | [-0.01997 ... -0.01791] | {'answer': 'Weng earns 12/60 = $'} |
| 2 | [-0.00623 ... -0.0061 ] | {'answer': 'In the beginning, Be'} |
| 3 | [-0.07849 ... 0.00721] | {'answer': 'Maila read 12 x 2 = '} |
| 4 | [-0.01669 ... 0.01263] | {'answer': 'He writes each frien'} |
| 5 | [0.02484 ... 0.05185] | {'answer': 'There are 80/100 * 1'} |
| 6 | [-0.01807 ... -0.01859] | {'answer': 'He eats 32 from the '} |
| 7 | [ 0.01265 ... -0.02016] | {'answer': 'To the initial 2 pou'} |
| 8 | [-0.00504 ... 0.0143 ] | {'answer': 'Let S be the amount '} |
| 9 | [-0.0239 ... -0.00905] | {'answer': 'She works 8 hours a '} |
+-----+-------------------------+------------------------------------+
Unsere Vektordb -Instanz wird durch eine Implementierung der ungefähren Suche nach nächstgelegenen Nachbarn (ANN) unterstützt, die binäre Bäume verwendet, um verschiedene Partitionen/Splits des Hyperraums darzustellen.
Diese Partitionen werden erzeugt, indem zwei Vektoren zufällig ausgewählt werden, die Hyperplane -Äquidistanz zwischen den beiden finden und dann die anderen Punkte left und right aufgeteilt werden, je nachdem, auf welcher Seite sie sich befinden
Dieser Vorgang wird wiederholt, bis wir in jedem Knoten höchstens k -Elemente haben (Partition)
Wir können bessere Ergebnisse erzielen, indem wir einen Baumwald * erzeugen? Und alle von ihnen durchsuchen, also lass uns das machen:
import random
# Set seed value for replication
random . seed ( 42 )
# Plant a bunch of trees ?️
vector_db . build ( n_trees = 3 , k = 3 )
print ( vector_db . trees [ 0 ], " n " )Hier ist eine Darstellung des ersten Baumes in unserem Wald (die Knoten zeigen die Anzahl der Instanzen in jeder Partition)
__________100______________
/
________________________________________________63______ __________37___________
/ /
_51__ _12_ 16____ ___21____
/ / / /
6 45____________________ _7 5 2 _14___ _10_ _11_____
/ / / / / / /
3 3 3 __________42_____________ 4 3 2 3 5 _9 _5 5 4 ___7
/ / / / / / / /
___18____ _____24____ 2 2 3 2 6 3 4 1 2 3 3 1 6_ 1
/ / / / /
_8_ _10_ ___11___ _13_ 3 3 1 3 2 4
/ / / / /
4 4 4 6_ 6_ _5 5 8_ 3 1
/ / / / / / / /
2 2 3 1 1 3 2 4 2 4 4 1 2 3 3 5
/ / / /
1 3 3 1 2 2 2 3
Schließlich können wir eine Abfrage ausführen, indem wir einfach die Datenbank nach Antworten einer Zielfrage durchsuchen.
Wir verwenden Entfernungsfunktionen wie die unten gezeigten, um zu quantifizieren, wie ähnlich zwei Vektoren miteinander sind.
Wenn wir beispielsweise die erste Frage in unserem Trainingsdatensatz stellen
from vektordb . utils import print_similarity_scores
# Extract first question
query = questions [ 0 ]
print ( " n Query:" , query , " n " )
# Run search and display similarity scores
results = vector_db . search ( embed ([ query ])[ 0 ], 3 )
print_similarity_scores ( results ) Wir erwarten, dass die Antwort mit demselben Index ( 0 ) das Top -Ergebnis ist:
Query: Natalia sold clips to 48 of her friends in April, and then she sold half as many clips in May.
How many clips did Natalia sell altogether in April and May?
+-----+---------------------+
| Key | Score |
+-----+---------------------+
| 0 | 0.15148634752350043 |
| 15 | 0.6105711817572272 |
| 83 | 0.6823805943068366 |
+-----+---------------------+
COS 597A (Princeton): Langzeitspeicher in AI - Vektorsuche und DatenbankenCMU 15-445/645 (Carnegie Mellon): Datenbanksysteme