دالة MinHashCompatible with Milvus 3.0.x
تقوم دالة MinHash بتحويل النص الخام إلى متجهات ثنائية تقارب تشابه جاكارد بين المستندات. وهي تطبق تقنية تقسيم النص إلى أجزاء متداخلة (text shingling) ودوال تجزئة متعددة لإنتاج متجهات توقيع ذات طول ثابت، مما يتيح الكشف السريع عن النصوص شبه المكررة وإزالة التكرارات من المستندات على نطاق واسع.
باعتبارها دالة مدمجة، تعمل MinHash داخل Milvus ولا تتطلب استدلال نماذج خارجية أو معالجة مسبقة. ما عليك سوى إدخال النص الخام، وسيقوم Milvus بإنشاء متجهات التوقيع MinHash تلقائيًا.
القيود
يجب أن يكون حقل الإخراج عبارة عن مصفوفة ذات أبعاد متساوية (
BINARY_VECTOR) ذات أبعاد تستوفي الشرط التالي:dim % 32 == 0، لأن كل توقيع MinHash يمثل قيمة تجزئة ذات 32 بت.يجب أن يساوي عدد العناصر في مصفوفة التوزيع (
dim) لحقل المتجهات الثنائية32 * num_hashes. يؤدي عدم التطابق إلى حدوث خطأ.عند استخدام مؤشر
MINHASH_LSHمع ناتج دالة MinHash، يجب تعيينmh_element_bit_widthإلى32.
كيف تعمل MinHash
MinHash هي تقنية تجزئة حساسة للموقع (locality-sensitive) تُقدّر تشابه جاكارد (Jaccard) بين المجموعات. في Milvus، تتبع دالة MinHash مسار العمل التالي: تقوم بتوفير النص الخام كمدخلات، ويقوم Milvus بإنتاج متجه ثنائي كمخرجات — مع معالجة جميع الخطوات الوسيطة داخليًا.
يتكون سير العمل الإجمالي من مسار معالجة نص مشترك يستخدمه كل من استيعاب المستندات ومعالجة الاستعلامات، تليه عمليات خاصة بكل مرحلة للتخزين والاسترجاع.
Iaqkbfeh8oqggsx6nsocfosondo
مسار معالجة النص المشترك
يمر النص الخام في كل من عملية استيعاب المستندات ومعالجة الاستعلامات عبر نفس عملية التحويل المكونة من أربع مراحل:
تحليل النص: تتم معالجة النص بواسطة محلل (عندما تكون قيمة
token_levelهي"word") أو يتم استخدامه مباشرةً (عندما تكون قيمةtoken_levelهي"char"). تعمل عملية التقطيع على مستوى الكلمة على تطبيق المحلل المُهيأ في حقل الإدخال لتقسيم النص إلى مصطلحات — على سبيل المثال، يتحول النص"milvus is vector db"إلى["milvus", "is", "vector", "db"].التقسيم إلى شرائح (Shingling): يتم تقسيم الرموز إلى n-grams متداخلة (شرائح) بحجم
shingle_size. على سبيل المثال، مع وجود 3-grams على مستوى الكلمة، تصبح الرموز["information", "retrieval", "is", "a", "field"]شرائح مثل["information retrieval is", "retrieval is a", "is a field"].إنشاء توقيع MinHash: يتم تطبيق دوال تجزئة متعددة (H1، H2، …، Hn، حيث n =
num_hashes) على مجموعة الشينغلز. بالنسبة لكل دالة تجزئة، يتم اختيار قيمة التجزئة الدنيا عبر جميع الشظايا. تشكل مجموعة هذه القيم الدنيا توقيع MinHash — وهو تمثيل ذو طول ثابت يقارب تشابه جاكارد (Jaccard) للوثيقة الأصلية.ترميز المتجه الثنائي: كل قيمة توقيع هي تجزئة من 32 بت، ويتم تجميع التوقيع الكامل في متجه ثنائي (
BINARY_VECTOR) بأبعاد32 * num_hashes.
استيعاب المستندات
أثناء الإدراج، يتم تخزين المتجه الثنائي الناتج عن خط الأنابيب المشترك في فهرس MINHASH_LSH. ويحتفظ الفهرس بجدول LSH (التجزئة الحساسة للموقع) الذي يجمع التوقيعات المتشابهة في نفس المجموعات، مما يتيح استرجاع المرشحين بسرعة عند إجراء الاستعلام.
معالجة الاستعلام
أثناء البحث، يمر نص الاستعلام عبر نفس المسار المشترك لإنتاج متجه ثنائي. يُستخدم هذا المتجه لإجراء بحث LSH في فهرس MINHASH_LSH ، والذي يحدد بسرعة أزواج المرشحين التي من المحتمل أن تكون متشابهة. بدون تحسين Jaccard، يعرض Milvus مرشحي LSH غير المصنفين حسب تشابه Jaccard المقدر. عند تمكين تحسين جاكارد، يستخدم Milvus توقيعات MinHash الأولية المخزنة لترتيب المرشحات حسب تشابه جاكارد المقدر وإرجاع أفضل K نتائج.
ونظرًا لأن كلا المسارين يشتركان في نفس منطق التحويل، فإن المستندين اللذين يتداخل محتواهما بشكل كبير ينتجان توقيعات MinHash متشابهة. وهذا يجعل الوظيفة فعالة في العثور على المستندات شبه المكررة حتى عندما تختلف المستندات في ترتيب الكلمات أو التنسيق أو الصياغة الطفيفة.
قبل البدء
قبل استخدام وظيفة MinHash، قم بتخطيط مخطط مجموعتك بحيث يتضمن ما يلي:
حقل نصي للمحتوى الخام
يجب أن تتضمن مجموعتك حقل «
VARCHAR» لتخزين النص الخام. يعمل هذا الحقل كمدخل لدالة MinHash.محلل لحقل النص (عند استخدام التقطيع إلى رموز على مستوى الكلمة)
إذا تم تعيين
token_levelعلى"word"(الافتراضي)، فيجب أن يكون محلل النص مفعلًا في حقل النص. يحدد المحلل كيفية تجزئة النص قبل التجميع. بشكل افتراضي، يستخدم Milvus محللstandard. لتكوين محلل مختلف، راجع اختيار المحلل المناسب لحالة الاستخدام الخاصة بك.حقل متجه ثنائي لإخراج MinHash
يجب أن تتضمن مجموعتك حقل «
BINARY_VECTOR» لتخزين المتجهات الثنائية التي تولدها دالة MinHash. يجب أن يكون البعد مساويًا لـ «32 * num_hashes».
الخطوة 1: إنشاء مجموعة باستخدام دالة MinHash
لاستخدام دالة MinHash، قم بتعريفها عند إنشاء المجموعة. تصبح الدالة جزءًا من مخطط المجموعة ويتم تطبيقها تلقائيًا أثناء إدراج البيانات والبحث.
تحديد حقول المخطط
يجب أن يتضمن مخطط المجموعة ثلاثة حقول على الأقل:
الحقل الأساسي: يحدد بشكل فريد كل كيان في المجموعة.
الحقل النصي (
VARCHAR): يخزن المستندات النصية الأولية. قم بتعيين "enable_analyzer=True" حتى يتمكن Milvus من معالجة النص لإنشاء توقيع MinHash. بشكل افتراضي، يستخدم Milvus محلل "standard" لتحليل النص. لتكوين محلل مختلف، راجع " اختيار المحلل المناسب لحالة الاستخدام الخاصة بك".حقل المتجهات الثنائية (
BINARY_VECTOR): يخزن المتجهات الثنائية التي يتم إنشاؤها تلقائيًا بواسطة دالة MinHash. يجب أن يكون البعد مساويًا لـ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
تحديد دالة MinHash
تقوم دالة MinHash بتحويل النص الذي تم تحليله إلى متجهات ثنائية تقارب تشابه جاكارد بين المستندات.
حدد الدالة وأضفها إلى مخططك:
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
خيارات التكوين
يقبل قاموس " params " الخاص بدالة MinHash المعلمات التالية. جميع أسماء المعلمات غير حساسة لحالة الأحرف.
المعلمة |
النوع |
القيمة الافتراضية |
الوصف |
|---|---|---|---|
|
int |
مشتق من |
عدد دوال التجزئة المستخدمة لتوليد التوقيع. يساوي بُعد المتجه الثنائي الناتج |
|
int |
|
حجم N-gram للتقسيم إلى شرائح. على مستوى الكلمة: 1-3 هو المعتاد. على مستوى الحرف: 2-6 هو المعتاد. |
|
str |
|
دالة التجزئة المراد استخدامها. الخيارات:
|
|
str |
|
مستوى التقطيع إلى رموز. الخيارات:
|
|
int |
|
البذرة العشوائية لتهيئة دالة MinHash. |
تكوين الفهرس
نوع الفهرس الموصى به للمتجهات الثنائية MinHash هو MINHASH_LSH ، مع نوع المقياس 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
اضبط with_raw_data على True إذا كانت عمليات البحث ستستخدم تحسين Jaccard. التوقيعات الأولية لـ MinHash مطلوبة لحساب التشابه التقديري لـ Jaccard للمرشحين الذين تم إرجاعهم بواسطة بحث LSH.
إنشاء المجموعة
قم بإنشاء المجموعة باستخدام معلمات المخطط والفهرس المحددة أعلاه:
client.create_collection(
collection_name="dedup_collection",
schema=schema,
index_params=index_params,
)
// java
// nodejs
// go
# restful
الخطوة 2: إدراج المستندات
بعد إعداد المجموعة، أدخل البيانات النصية. ما عليك سوى توفير النص الخام — حيث تقوم دالة MinHash تلقائيًا بإنشاء المتجه الثنائي لكل مستند.
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
الخطوة 3: البحث باستخدام MinHash
بمجرد إدخال البيانات، ابحث عن المستندات شبه المكررة عن طريق تقديم استعلامات نصية أولية. يقوم Milvus تلقائيًا بتحويل كل استعلام إلى متجه ثنائي MinHash. قم بتمكين تصفية Jaccard لترتيب المرشحين LSH حسب تشابه Jaccard المقدر.
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
اضبط mh_search_with_jaccard على True لتمكين تحسين Jaccard. يتحكم refine_k في سعة مجموعة المرشحين المستخدمة للتحسين. يستخدم Milvus max(refine_k, limit) كسعة، ولكنه قد يقوم بتحسين عدد أقل من المرشحين إذا عاد بحث LSH بعدد أقل من التطابقات. يمكن أن تؤدي زيادة refine_k إلى تحسين جودة النتائج على حساب حسابات إضافية.
الخطوة التالية
البحث عن النص الكامل: استخدم BM25 لترتيب الصلة المعجمية بدلاً من الكشف عن التكرارات شبه المتطابقة.
نظرة عامة على أداة التحليل: قم بتكوين أدوات تحليل مخصصة لتقطيع النص إلى رموز.
فهرس MINHASH_LSH: تعرف على كيفية ضبط معلمات LSH لتحسين معدل الاسترجاع والأداء.