• À propos de Milvus
  • Commencer
  • Concepts
  • Guide d'utilisation
    • Collections
    • Schéma et champs de données
    • Insérer et supprimer
    • Index
    • Rechercher
    • Inférence de fonctions et de modèles
    • Optimisation du stockage
    • Instantanés
  • Importation de données
  • Outils d'IA
  • Guide d'administration
  • Outils
  • Intégrations
  • Tutoriels
  • Foire aux questions
  • API Reference

Fonction MinHashCompatible with Milvus 3.0.x

La fonction MinHash convertit du texte brut en vecteurs binaires qui fournissent une approximation de la similarité de Jaccard entre les documents. Elle applique le découpage de texte (text shingling) et plusieurs fonctions de hachage pour produire des vecteurs de signature de longueur fixe, ce qui permet une détection rapide des quasi-doublons et une déduplication des documents à grande échelle.

En tant que fonction intégrée, MinHash s'exécute au sein de Milvus et ne nécessite ni inférence de modèle externe ni prétraitement. Il vous suffit d'insérer du texte brut pour que Milvus génère automatiquement les vecteurs de signature MinHash.

Contraintes

  • Le champ de sortie doit être un champ de type « BINARY_VECTOR » dont la dimension satisfait à la condition dim % 32 == 0, car chaque signature MinHash est une valeur de hachage de 32 bits.

  • L’ dim du champ de vecteurs binaires doit être égale à 32 * num_hashes. Toute divergence entraîne une erreur.

  • Lorsque l’on utilise l’index « MINHASH_LSH » avec la sortie de la fonction MinHash, « mh_element_bit_width » doit être défini sur « 32 ».

Fonctionnement de MinHash

Développez pour voir comment cela fonctionne

MinHash est une technique de hachage sensible à la localité qui estime la similarité de Jaccard entre des ensembles. Dans Milvus, la fonction MinHash suit ce pipeline : vous fournissez du texte brut en entrée, et Milvus produit un vecteur binaire en sortie — en gérant toutes les étapes intermédiaires en interne.

Le flux de travail global se compose d’un pipeline de traitement de texte partagé, utilisé à la fois pour l’ingestion des documents et le traitement des requêtes, suivi d’opérations spécifiques à chaque phase pour le stockage et la recherche.

Iaqkbfeh8oqggsx6nsocfosondo Iaqkbfeh8oqggsx6nsocfosondo

Pipeline de traitement de texte partagé

L’ingestion de documents et le traitement des requêtes font tous deux passer le texte brut par la même transformation en quatre étapes :

  1. Analyse du texte: le texte est traité par un analyseur (lorsque token_level est "word") ou utilisé directement (lorsque token_level est "char"). La tokenisation au niveau des mots applique l’analyseur configuré sur le champ d’entrée pour segmenter le texte en termes — par exemple, "milvus is vector db" devient ["milvus", "is", "vector", "db"].

  2. Segmentation en « shingles »: les tokens sont divisés en n-grammes (shingles) qui se chevauchent, de taille shingle_size. Par exemple, avec des 3-grammes au niveau des mots, les tokens ["information", "retrieval", "is", "a", "field"] deviennent des shingles tels que ["information retrieval is", "retrieval is a", "is a field"].

  3. Génération de la signature MinHash: plusieurs fonctions de hachage (H1, H2, …, Hn, où n = num_hashes) sont appliquées à l’ensemble des shingles. Pour chaque fonction de hachage, la valeur de hachage minimale parmi tous les « shingles » est sélectionnée. L’ensemble de ces valeurs minimales forme la signature MinHash — une représentation de longueur fixe qui approxime la similarité de Jaccard du document d’origine.

  4. Codage en vecteur binaire: chaque valeur de signature est un hachage de 32 bits, et la signature complète est compressée dans un BINARY_VECTOR de dimension 32 * num_hashes.

Ingestion de documents

Lors de l’insertion, le vecteur binaire produit par le pipeline partagé est stocké dans l’index MINHASH_LSH. L’index gère une table LSH (Locality-Sensitive Hashing) qui regroupe les signatures similaires dans les mêmes compartiments, ce qui permet une récupération rapide des candidats au moment de la requête.

Traitement des requêtes

Lors de la recherche, le texte de la requête passe par le même pipeline partagé pour produire un vecteur binaire. Ce vecteur est utilisé pour effectuer une recherche LSH dans l’index MINHASH_LSH, ce qui identifie rapidement les paires de candidats susceptibles d’être similaires. Sans raffinement de Jaccard, Milvus renvoie des candidats LSH qui ne sont pas classés selon la similarité de Jaccard estimée. Lorsque le raffinement Jaccard est activé, Milvus utilise les signatures MinHash brutes stockées pour classer les candidats en fonction de la similarité Jaccard estimée et renvoie les K meilleurs résultats.

Comme les deux méthodes partagent la même logique de transformation, deux documents dont le contenu se recoupe fortement produisent des signatures MinHash similaires. Cela rend cette fonction efficace pour détecter les quasi-doublons, même lorsque les documents diffèrent par l’ordre des mots, la mise en forme ou des nuances de formulation.

Avant de commencer

Avant d’utiliser la fonction MinHash, concevez le schéma de votre collection de manière à inclure les éléments suivants :

  • Un champ de texte pour le contenu brut

    Votre collection doit inclure un champ « VARCHAR » pour stocker le texte brut. Ce champ sert d’entrée à la fonction MinHash.

  • Un analyseur pour le champ de texte (en cas d’utilisation de la tokenisation au niveau des mots)

    Si « token_level » est défini sur « "word" » (par défaut), l’analyseur du champ de texte doit être activé. L’analyseur définit la manière dont le texte est tokenisé avant le shingling. Par défaut, Milvus utilise l’analyseur « standard ». Pour configurer un autre analyseur, consultez la section « Choisir l’analyseur adapté à votre cas d’utilisation ».

  • Un champ de vecteurs binaires pour la sortie MinHash

    Votre collection doit inclure un champ de type « BINARY_VECTOR » pour stocker les vecteurs binaires générés par la fonction MinHash. La dimension doit être égale à « 32 * num_hashes ».

Étape 1 : Créer une collection avec une fonction MinHash

Pour utiliser la fonction MinHash, définissez-la lors de la création de la collection. La fonction est alors intégrée au schéma de la collection et s’applique automatiquement lors de l’insertion et de la recherche de données.

Définir les champs du schéma

Le schéma de votre collection doit inclure au moins trois champs :

  • Champ principal: identifie de manière unique chaque entité de la collection.

  • Champ texte (VARCHAR) : stocke les documents texte bruts. Définissez l’ enable_analyzer=True e afin que Milvus puisse traiter le texte pour la génération de la signature MinHash. Par défaut, Milvus utilise l’analyseur standard pour l’analyse de texte. Pour configurer un autre analyseur, reportez-vous à la section « Choisir l’analyseur adapté à votre cas d’utilisation ».

  • Champ de vecteurs binaires (BINARY_VECTOR) : stocke les vecteurs binaires générés automatiquement par la fonction MinHash. La dimension doit être égale à 32 * num_hashes.

from pymilvus import MilvusClient, DataType, Function, FunctionType

client = MilvusClient(uri="http://localhost:19530", token="root:Milvus")

schema = client.create_schema()

schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True, auto_id=True)
schema.add_field(field_name="document_content", datatype=DataType.VARCHAR, max_length=9000, enable_analyzer=True)
schema.add_field(field_name="binary_vector", datatype=DataType.BINARY_VECTOR, dim=8192)
// java
// nodejs
// go
# restful

Définir la fonction MinHash

La fonction MinHash convertit le texte analysé en vecteurs binaires qui fournissent une approximation de la similarité de Jaccard entre les documents.

Définissez la fonction et ajoutez-la à votre schéma :

minhash_function = Function(
    name="minhash_function",
    input_field_names=["document_content"], # Name of the VARCHAR field containing raw text
    output_field_names=["binary_vector"], # Name of the BINARY_VECTOR field for generated signatures
    function_type=FunctionType.MINHASH,
    params={
        "num_hashes": 256, # Number of hash functions; produces dim = 32 * 256 = 8192
        "shingle_size": 3, # N-gram size for shingling
    }
)

schema.add_function(minhash_function)
// java
// nodejs
// go
# restful

Options de configuration

Le dictionnaire « params » de la fonction MinHash accepte les paramètres suivants. Les noms de paramètres ne sont pas sensibles à la casse.

Paramètre

Type

Valeur par défaut

Description

num_hashes

int

Dérivé de dim / 32

Nombre de fonctions de hachage utilisées pour la génération de la signature. La dimension du vecteur binaire de sortie est égale à 32 * num_hashes. Des valeurs plus élevées réduisent la variance dans l'estimation de la similarité mais augmentent la charge de calcul. Recommandé : 256 (dim = 8192).

shingle_size

int

3

Taille du N-gramme pour le shingling. Au niveau des mots : 1 à 3 en général. Au niveau des caractères : 2 à 6 en général.

hash_function

str

"xxhash"

Fonction de hachage à utiliser. Options :

  • "xxhash" (rapide)

  • "sha1" (plus lent, meilleure résistance aux collisions).

token_level

str

"word"

Niveau de tokenisation. Options :

  • "word": utilise l'analyseur du champ pour la tokenisation, puis applique le découpage en n-grammes.

  • "char" / "character": applique le découpage en n-grammes directement sur les caractères bruts (sans analyseur).

    Le niveau « mot » offre une sémantique plus forte et une meilleure efficacité, mais dépend de la tokenisation spécifique à la langue. Le niveau « caractère » est indépendant de la langue, mais produit des segments de dimension plus élevée avec une sémantique plus faible.

seed

int

1234

Graine aléatoire pour l’initialisation de la fonction MinHash.

Configurer l’index

Le type d’index recommandé pour les vecteurs binaires MinHash est « MINHASH_LSH », avec le type de métrique « MHJACCARD ».

index_params = client.prepare_index_params()

index_params.add_index(
    field_name="binary_vector",
    index_type="MINHASH_LSH",
    metric_type="MHJACCARD",
    params={
        "mh_lsh_band": 128,
        "mh_element_bit_width": 32,
        "with_raw_data": True,
    },
)
// java
// nodejs
// go
# restful

Définissez ` with_raw_data ` sur ` True ` si les recherches utilisent le raffinement de Jaccard. Les signatures MinHash brutes sont nécessaires pour calculer la similarité de Jaccard estimée pour les candidats renvoyés par la recherche LSH.

Créer la collection

Créez la collection à l’aide du schéma et des paramètres d’index définis ci-dessus :

client.create_collection(
    collection_name="dedup_collection",
    schema=schema,
    index_params=index_params,
)
// java
// nodejs
// go
# restful

Étape 2 : Insérer des documents

Une fois votre collection configurée, insérez des données textuelles. Il vous suffit de fournir le texte brut : la fonction MinHash génère automatiquement le vecteur binaire pour chaque document.

client.insert(
    "dedup_collection",
    [
        {"document_content": "information retrieval is a field of study that helps users find relevant information in large datasets"},
        {"document_content": "information retrieval is a research field focused on helping users find relevant data in large collections"},
        {"document_content": "information retrieval is a field of research helping users search for relevant information in large datasets"},
    ],
)
// java
// nodejs
// go
# restful

Étape 3 : Effectuer une recherche avec MinHash

Une fois les données insérées, recherchez les documents quasi-duplicatas en saisissant des requêtes sous forme de texte brut. Milvus convertit automatiquement chaque requête en un vecteur binaire MinHash. Activez le raffinement Jaccard pour classer les candidats LSH en fonction de la similarité Jaccard estimée.

search_params = {
    "metric_type": "MHJACCARD",
    "params": {
        "mh_search_with_jaccard": True,
        "refine_k": 3,
    },
}

results = client.search(
    collection_name="dedup_collection",
    data=["information retrieval is a research field focused on helping users find relevant data in large collections"],
    anns_field="binary_vector",
    limit=3,
    output_fields=["document_content"],
    search_params=search_params,
)

for hits in results:
    for hit in hits:
        print(f"ID: {hit['id']}, Distance: {hit['distance']}")
        print(f"Document: {hit['entity']['document_content']}")
// java
// nodejs
// go
# restful

Définissez ` mh_search_with_jaccard ` sur ` True ` pour activer le raffinement Jaccard. ` refine_k ` contrôle la capacité du pool de candidats utilisée pour le raffinement. Milvus utilise ` max(refine_k, limit) ` comme capacité, mais peut raffiner moins de candidats si la recherche LSH renvoie moins de correspondances. Augmenter ` refine_k ` peut améliorer la qualité des résultats au prix d’un surcroît de calcul.

Prochaines étapes