MinHash-FunktionCompatible with Milvus 3.0.x
Die MinHash-Funktion wandelt Rohtext in binäre Vektoren um, die die Jaccard-Ähnlichkeit zwischen Dokumenten approximieren. Sie wendet Text-Shingling und mehrere Hash-Funktionen an, um Signaturvektoren fester Länge zu erzeugen, was eine schnelle Erkennung von Beinahe-Duplikaten und die Deduplizierung von Dokumenten in großem Maßstab ermöglicht.
Als integrierte Funktion läuft MinHash innerhalb von Milvus und erfordert keine externe Modellinferenz oder Vorverarbeitung. Sie geben Rohtext ein, und Milvus generiert die MinHash-Signaturvektoren automatisch.
Einschränkungen
Das Ausgabefeld muss ein „
BINARY_VECTOR“ mit einer Dimension sein, die die Bedingungdim % 32 == 0erfüllt, da jede MinHash-Signatur ein 32-Bit-Hashwert ist.Der „
dim“ des binären Vektorfeldes muss mit „32 * num_hashes“ übereinstimmen. Eine Nichtübereinstimmung führt zu einem Fehler.Bei Verwendung des Indexes „
MINHASH_LSH“ mit der Ausgabe der MinHash-Funktion muss „mh_element_bit_width“ auf „32“ gesetzt werden.
So funktioniert MinHash
MinHash ist eine lokalitätssensitive Hash-Technik, die die Jaccard-Ähnlichkeit zwischen Mengen schätzt. In Milvus folgt die MinHash-Funktion dieser Pipeline: Sie geben Rohtext als Eingabe ein, und Milvus erzeugt einen Binärvektor als Ausgabe – wobei alle Zwischenschritte intern abgewickelt werden.
Der gesamte Workflow besteht aus einer gemeinsamen Textverarbeitungs-Pipeline, die sowohl für die Dokumentenerfassung als auch für die Abfrageverarbeitung genutzt wird, gefolgt von phasenspezifischen Vorgängen für die Speicherung und den Abruf.
Iaqkbfeh8oqggsx6nsocfosondo
Gemeinsame Textverarbeitungspipeline
Sowohl die Dokumentenerfassung als auch die Abfrageverarbeitung leiten den Rohtext durch dieselbe vierstufige Transformation:
Textanalyse: Der Text wird von einem Analysator verarbeitet (wenn „
token_level“ auf „"word"“ gesetzt ist) oder direkt verwendet (wenn „token_level“ auf „"char"“ gesetzt ist). Bei der Tokenisierung auf Wortebene wird der für das Eingabefeld konfigurierte Analysator angewendet, um den Text in Terme zu segmentieren – beispielsweise wird aus „"milvus is vector db"“ „["milvus", "is", "vector", "db"]“.Shingling: Die Token werden in überlappende n-Gramme (Shingles) der Größe
shingle_sizeaufgeteilt. Bei 3-Grammen auf Wortebene werden beispielsweise aus den Token „["information", "retrieval", "is", "a", "field"]“ Shingles wie „["information retrieval is", "retrieval is a", "is a field"]“.Erstellung der MinHash-Signatur: Auf die Shingle-Menge werden mehrere Hash-Funktionen (H1, H2, …, Hn, wobei n =
num_hashes) angewendet. Für jede Hash-Funktion wird der minimale Hash-Wert über alle Shingles ausgewählt. Die Sammlung dieser Minimalwerte bildet die MinHash-Signatur – eine Darstellung fester Länge, die die Jaccard-Ähnlichkeit des Originaldokuments approximiert.Binäre Vektorkodierung: Jeder Signaturwert ist ein 32-Bit-Hash, und die vollständige Signatur wird in ein
BINARY_VECTORder Dimension32 * num_hashesgepackt.
Dokumenteneingabe
Beim Einfügen wird der von der gemeinsamen Pipeline erzeugte Binärvektor im „ MINHASH_LSH “-Index gespeichert. Der Index verwaltet eine LSH-Tabelle (Locality-Sensitive Hashing), die ähnliche Signaturen in denselben Buckets gruppiert und so eine schnelle Abfrage von Kandidaten bei der Suche ermöglicht.
Abfrageverarbeitung
Bei der Suche durchläuft der Suchtext dieselbe gemeinsame Pipeline, um einen Binärvektor zu erzeugen. Dieser Vektor wird verwendet, um eine LSH-Abfrage im „ MINHASH_LSH “-Index durchzuführen, wodurch schnell Kandidatenpaare identifiziert werden, die wahrscheinlich ähnlich sind. Ohne Jaccard-Verfeinerung gibt Milvus LSH-Kandidaten zurück, die nicht nach der geschätzten Jaccard-Ähnlichkeit gereiht sind. Wenn die Jaccard-Verfeinerung aktiviert ist, verwendet Milvus die gespeicherten rohen MinHash-Signaturen, um die Kandidaten nach der geschätzten Jaccard-Ähnlichkeit zu ordnen und die Top-K-Ergebnisse zurückzugeben.
Da beide Verfahren dieselbe Transformationslogik nutzen, erzeugen zwei Dokumente mit stark überlappendem Inhalt ähnliche MinHash-Signaturen. Dadurch eignet sich die Funktion besonders gut zum Auffinden von Beinahe-Duplikaten, selbst wenn sich die Dokumente in der Wortreihenfolge, der Formatierung oder in geringfügigen Formulierungsunterschieden unterscheiden.
Bevor Sie beginnen
Bevor Sie die MinHash-Funktion verwenden, sollten Sie Ihr Erfassungsschema so planen, dass es Folgendes enthält:
Ein Textfeld für Rohinhalte
Ihre Sammlung muss ein Feld vom Typ „
VARCHAR“ enthalten, um Rohtext zu speichern. Dieses Feld dient als Eingabe für die MinHash-Funktion.Einen Analysator für das Textfeld (bei Verwendung der Tokenisierung auf Wortebene)
Wenn „
token_level“ auf „"word"“ (Standard) gesetzt ist, muss für das Textfeld ein Analysator aktiviert sein. Der Analysator legt fest, wie der Text vor dem Shingling tokenisiert wird. Standardmäßig verwendet Milvus den Analysator „standard“. Informationen zum Konfigurieren eines anderen Analysators finden Sie unter „Wählen Sie den richtigen Analysator für Ihren Anwendungsfall“.Ein Binärvektorfeld für die MinHash-Ausgabe
Ihre Sammlung muss ein Feld vom Typ „
BINARY_VECTOR“ enthalten, um die von der MinHash-Funktion generierten Binärvektoren zu speichern. Die Dimension muss „32 * num_hashes“ entsprechen.
Schritt 1: Erstellen Sie eine Sammlung mit einer MinHash-Funktion
Um die MinHash-Funktion zu verwenden, definieren Sie diese beim Erstellen der Sammlung. Die Funktion wird Teil des Sammlungsschemas und wird beim Einfügen und Suchen von Daten automatisch angewendet.
Schemafelder definieren
Ihr Sammlungsschema muss mindestens drei Felder enthalten:
Primärfeld: Identifiziert jede Entität in der Sammlung eindeutig.
Textfeld (
VARCHAR): Speichert Rohtextdokumente. Setzen Sie „enable_analyzer=True“, damit Milvus den Text für die Generierung der MinHash-Signatur verarbeiten kann. Standardmäßig verwendet Milvus den Analyzer „standard“ für die Textanalyse. Informationen zur Konfiguration eines anderen Analyzers finden Sie unter „Wählen Sie den richtigen Analyzer für Ihren Anwendungsfall“.Binärvektorfeld (
BINARY_VECTOR): Speichert Binärvektoren, die automatisch von der MinHash-Funktion generiert werden. Die Dimension muss mit32 * num_hashesübereinstimmen.
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
Definieren Sie die MinHash-Funktion
Die MinHash-Funktion wandelt den analysierten Text in binäre Vektoren um, die die Jaccard-Ähnlichkeit zwischen Dokumenten approximieren.
Definieren Sie die Funktion und fügen Sie sie Ihrem Schema hinzu:
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
Konfigurationsoptionen
Das „ params “-Dictionary der MinHash-Funktion akzeptiert die folgenden Parameter. Bei allen Parameternamen wird die Groß-/Kleinschreibung nicht berücksichtigt.
Parameter |
Typ |
Standard |
Beschreibung |
|---|---|---|---|
|
int |
Abgeleitet von |
Anzahl der Hash-Funktionen zur Signaturerzeugung. Die Dimension des ausgegebenen Binärvektors entspricht |
|
int |
|
N-Gram-Größe für das Shingling. Auf Wortebene: Typischerweise 1–3. Auf Zeichenebene: Typischerweise 2–6. |
|
str |
|
Zu verwendende Hash-Funktion. Optionen:
|
|
str |
|
Tokenisierungsstufe. Optionen:
|
|
int |
|
Zufallsstartwert für die Initialisierung der MinHash-Funktion. |
Konfigurieren Sie den Index
Der empfohlene Indextyp für MinHash-Binärvektoren ist „ MINHASH_LSH “ mit dem Metriktyp „ 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
Setzen Sie „ with_raw_data “ auf „ True “, wenn bei Suchvorgängen die Jaccard-Verfeinerung verwendet wird. Die rohen MinHash-Signaturen werden benötigt, um die geschätzte Jaccard-Ähnlichkeit für die von der LSH-Abfrage zurückgegebenen Kandidaten zu berechnen.
Erstellen Sie die Sammlung
Erstellen Sie die Sammlung unter Verwendung der oben definierten Schema- und Indexparameter:
client.create_collection(
collection_name="dedup_collection",
schema=schema,
index_params=index_params,
)
// java
// nodejs
// go
# restful
Schritt 2: Dokumente einfügen
Fügen Sie nach der Einrichtung Ihrer Sammlung Textdaten ein. Sie müssen lediglich den Rohtext bereitstellen – die MinHash-Funktion generiert automatisch den Binärvektor für jedes Dokument.
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
Schritt 3: Suche mit MinHash
Sobald Sie Daten eingefügt haben, suchen Sie nach nahezu identischen Dokumenten, indem Sie Suchanfragen im Rohtext eingeben. Milvus wandelt jede Suchanfrage automatisch in einen MinHash-Binärvektor um. Aktivieren Sie die Jaccard-Verfeinerung, um die LSH-Kandidaten nach der geschätzten Jaccard-Ähnlichkeit zu ordnen.
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
Setzen Sie „ mh_search_with_jaccard “ auf „ True “, um die Jaccard-Verfeinerung zu aktivieren. „ refine_k “ steuert die Kapazität des Kandidatenpools, der für die Verfeinerung verwendet wird. Milvus verwendet „ max(refine_k, limit) “ als Kapazität, verfeinert jedoch möglicherweise weniger Kandidaten, wenn die LSH-Abfrage weniger Treffer liefert. Eine Erhöhung von „ refine_k “ kann die Ergebnisqualität verbessern, ist jedoch mit zusätzlichem Rechenaufwand verbunden.
Was kommt als Nächstes?
Volltextsuche: Verwenden Sie BM25 für das lexikalische Relevanz-Ranking anstelle der Erkennung von Beinahe-Duplikaten.
Übersicht über Analysatoren: Konfigurieren Sie benutzerdefinierte Analysatoren für die Text-Tokenisierung.
MINHASH_LSH-Index: Erfahren Sie mehr über die Optimierung der LSH-Parameter für Recall und Leistung.