All guides
IntermediateSelf-pacedFree GuideSection 75/95

Embeddings et bases vectorielles

Practise development foundations: programming, web, APIs, data and AI tools. Work through sections and exercises to build your first projects.

The full lessons for this course are currently available in French. Use the section menu to navigate the French course.

💡

Free content, available without an account. Tools and models change: use the current model guide to check their versions. Models and sources

Section 11.4.16 : Embeddings et bases vectorielles

🎯 Objectif pédagogique

Comprendre les embeddings (représentations vectorielles), les bases vectorielles, et les opérations de similarité. Vous serez capable de créer, stocker et rechercher des embeddings pour alimenter vos systèmes RAG et de recommandation.


Les embeddings — L'ADN du texte

Marc a vu les embeddings dans la section RAG. Maintenant, on va en profondeur. Un embedding est un vecteur de nombres (ex: [0.12, -0.34, 0.56, ...]) qui capture le sens d'un texte. Deux textes similaires auront des embeddings proches dans l'espace vectoriel.

Créer et comparer des embeddings

from openai import OpenAI
import numpy as np

client = OpenAI()

def get_embedding(text, model="text-embedding-3-small"):
    """Obtenir l'embedding d'un texte."""
    response = client.embeddings.create(
        model=model,
        input=text
    )
    return np.array(response.data[0].embedding)

def cosine_similarity(a, b):
    """Calculer la similarité cosinus entre deux vecteurs."""
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

# Démonstration
texts = [
    "Data Analyst spécialisé en finance",
    "Analyste de données secteur financier",
    "Chef cuisinier passionné de gastronomie",
    "Python developer with SQL skills",
    "Développeur Python avec compétences SQL"
]

embeddings = \{text: get_embedding(text) for text in texts\}

# Matrice de similarité
print("Similarités :")
for i, t1 in enumerate(texts):
    for j, t2 in enumerate(texts):
        if j > i:
            sim = cosine_similarity(embeddings[t1], embeddings[t2])
            print(f"  \{sim:.3f\} | '\{t1[:40]\}' ↔ '\{t2[:40]\}'")

# Résultats attendus :
# ~0.95 | "Data Analyst finance" ↔ "Analyste données financier"  (synonymes)
# ~0.90 | "Python developer SQL" ↔ "Développeur Python SQL"       (traduction)
# ~0.30 | "Data Analyst finance" ↔ "Chef cuisinier"               (différents)

Modèles d'embedding

ModèleProviderDimensions$/M tokensQualité
text-embedding-3-smallOpenAI15360.02$Bon
text-embedding-3-largeOpenAI30720.13$Excellent
voyage-3Voyage AI10240.06$Très bon
all-MiniLM-L6-v2HuggingFace384Gratuit*Correct
nomic-embed-textNomic768Gratuit*Bon

*Gratuit si exécuté localement (GPU recommandé)

Bases vectorielles — Stocker et rechercher

# ═══ ChromaDB — Simple et local ═══
import chromadb

client = chromadb.PersistentClient(path="./vector_db")

# Créer une collection
collection = client.get_or_create_collection(
    name="job_offers",
    metadata=\{"hnsw:space": "cosine"\}  # Distance cosinus
)

# Indexer des offres d'emploi
offers = [
    \{"id": "offer_1", "text": "Data Analyst Python SQL Paris 50k", "company": "TechCorp"\},
    \{"id": "offer_2", "text": "ML Engineer TensorFlow Remote 70k", "company": "AIStartup"\},
    \{"id": "offer_3", "text": "Business Analyst Excel Finance Lyon 45k", "company": "BankCo"\},
    \{"id": "offer_4", "text": "Data Scientist Python R Deep Learning 65k", "company": "DataLab"\},
    \{"id": "offer_5", "text": "Analyste financier programmation Python 55k", "company": "FinTech"\},
]

collection.upsert(
    ids=[o["id"] for o in offers],
    documents=[o["text"] for o in offers],
    metadatas=[\{"company": o["company"]\} for o in offers]
)

# Recherche sémantique
results = collection.query(
    query_texts=["Poste data avec Python pour quelqu'un venant de la finance"],
    n_results=3,
    where=None  # Pas de filtre metadata
)

print("Top 3 offres similaires :")
for i, (doc, meta) in enumerate(zip(results["documents"][0], results["metadatas"][0])):
    print(f"  \{i+1\}. [\{meta['company']\}] \{doc\}")

# Résultat : "Analyste financier Python" et "Data Analyst Python SQL" en top

Recherche hybride — Sémantique + Filtres

# Combiner similarité sémantique et filtres metadata
results = collection.query(
    query_texts=["Machine learning engineer"],
    n_results=5,
    where=\{"company": \{"$ne": "BankCo"\}\},  # Exclure BankCo
    # Ou : where=\{"salary_min": \{"$gte": 50000\}\}
)

# ChromaDB supporte les opérateurs :
# $eq, $ne : égal, différent
# $gt, $gte, $lt, $lte : comparaisons
# $in, $nin : dans / pas dans une liste
# $and, $or : combinaisons

Applications des embeddings au-delà du RAG

# 1. Système de recommandation
def recommend_similar_offers(offer_id, collection, n=5):
    """Recommander des offres similaires."""
    offer = collection.get(ids=[offer_id])
    
    results = collection.query(
        query_texts=offer["documents"],
        n_results=n + 1  # +1 car l'offre elle-même sera dans les résultats
    )
    
    # Exclure l'offre d'origine
    return [(doc, meta) for doc, meta, id_ in 
            zip(results["documents"][0], results["metadatas"][0], results["ids"][0])
            if id_ != offer_id]

# 2. Détection de doublons
def find_duplicates(collection, threshold=0.95):
    """Trouver les documents quasi-identiques."""
    all_docs = collection.get()
    duplicates = []
    
    for i, doc in enumerate(all_docs["documents"]):
        results = collection.query(query_texts=[doc], n_results=5)
        for j, (sim_doc, distance) in enumerate(
            zip(results["documents"][0], results["distances"][0])
        ):
            if distance < (1 - threshold) and results["ids"][0][j] != all_docs["ids"][i]:
                duplicates.append((all_docs["ids"][i], results["ids"][0][j], 1 - distance))
    
    return duplicates

# 3. Clustering sémantique
def cluster_by_topic(texts, n_clusters=3):
    """Grouper des textes par thème."""
    from sklearn.cluster import KMeans
    
    embeddings = [get_embedding(t) for t in texts]
    kmeans = KMeans(n_clusters=n_clusters, random_state=42)
    labels = kmeans.fit_predict(embeddings)
    
    clusters = \{\}
    for text, label in zip(texts, labels):
        clusters.setdefault(label, []).append(text)
    
    return clusters

Coût des embeddings : dérisoire

text-embedding-3-small coûte 0.02$ par million de tokens. Indexer 10 000 offres d'emploi (~500k tokens) coûte ~0.01$. La recherche est gratuite (calcul local). Les embeddings sont la brique IA la moins chère et la plus utile.

🏋️ Exercice pratique (25 minutes)

  1. →Créez des embeddings pour 10 textes variés et comparez les similarités
  2. →Stockez-les dans ChromaDB et implémentez la recherche
  3. →Testez la recherche hybride (similarité + filtre)
  4. →Implémentez un mini-système de recommandation
Quick Check

Pourquoi deux textes en langues différentes ("Data Analyst" et "Analyste de données") ont-ils des embeddings similaires ?

Quick Check

Quelle est la différence entre une base de données classique et une base vectorielle ?

Your progress

Progress is self-reported and stored in your browser. The final completion record is not a qualification or an independent assessment.

View progress and completion record

Learn AI, from prompts to agents

15 free guidesQuizzes, diagrams and workshopsNo account needed

One practical AI workflow in your inbox

Methods, resources and new exercises. Free, unsubscribe at any time.