最小哈希函数Compatible with Milvus 3.0.x
MinHash 函数可将原始文本转换为二进制向量,以接近文档之间的Jaccard 相似性。它应用文本切分和多个哈希函数来生成固定长度的签名向量,从而实现快速的近似重复检测和大规模的文档重复删除。
作为一个内置函数,MinHash 在 Milvus 内部运行,不需要外部模型推断或预处理。你只需插入原始文本,Milvus 就会自动生成 MinHash 签名向量。
限制条件
输出字段必须是维度满足
dim % 32 == 0的BINARY_VECTOR,因为每个 MinHash 签名都是 32 位的哈希值。二进制向量字段的
dim必须等于32 * num_hashes。不匹配会导致错误。在 MinHash 函数输出中使用
MINHASH_LSH索引时,必须将mh_element_bit_width设置为32。
MinHash 如何工作
MinHash是一种对位置敏感的散列技术,可估算集合间的Jaccard 相似性。在 Milvus 中,MinHash 功能遵循以下流程:您提供原始文本作为输入,Milvus 生成二进制向量作为输出--内部处理所有中间步骤。
整个工作流程包括一个共享的文本处理管道,文档摄取和查询处理都会用到,然后是存储和检索的特定阶段操作符。
Iaqkbfeh8oqggsx6nsocfosondo
共享文本处理管道
文档摄取和查询处理都通过相同的四阶段转换来处理原始文本:
文本分析:文本由分析器处理(当
token_level是"word"时)或直接使用(当token_level是"char"时)。词级标记化应用在输入字段上配置的分析器,将文本分割成术语--例如,"milvus is vector db"变成["milvus", "is", "vector", "db"]。分层:词块被分割成大小为
shingle_size的重叠 n-gram(shingles)。例如,在单词级别使用 3-grams 时,令牌["information", "retrieval", "is", "a", "field"]就会变成["information retrieval is", "retrieval is a", "is a field"]这样的词块。MinHash 签名生成:将多个哈希函数(H1、H2、...、Hn,其中 n =
num_hashes)应用于楔形字符集。对于每个哈希函数,都会在所有木片中选择最小哈希值。这些最小值的 Collections 构成了 MinHash 签名--一个固定长度的表示,近似于原始文档的 Jaccard 相似度。二进制向量编码:每个签名值都是一个 32 位的哈希值,完整签名被打包到维度为
BINARY_VECTOR的32 * num_hashes中。
文件输入
在插入过程中,共享管道产生的二进制向量会存储在MINHASH_LSH 索引中。该索引维护一个 LSH(位置敏感散列)表,将类似的签名归入相同的桶中,以便在查询时快速检索候选签名。
查询处理
在搜索过程中,查询文本通过相同的共享管道产生二进制向量。该向量用于在MINHASH_LSH 索引中执行 LSH 查找,从而快速确定可能相似的候选配对。然后根据估计的 Jaccard 相似度对候选结果进行排序,并返回前 K 个结果。
由于两个路径共享相同的转换逻辑,内容高度重叠的两个文档会产生相似的 MinHash 签名。因此,即使文档在词序、格式或细微措辞上存在差异,该功能也能有效查找近似重复的文档。
开始之前
在使用 MinHash 函数之前,请规划好您的 Collections Schema,使其包含以下内容:
原始内容的文本字段
您的 Collections 必须包含一个
VARCHAR字段来存储原始文本。这个字段是 MinHash 函数的输入。文本字段的分析器(使用单词级标记化时)
如果
token_level设置为"word"(默认),则文本字段必须启用分析器。分析器定义在分片前如何对文本进行标记。默认情况下,Milvus 使用standard分析器。要配置不同的分析器,请参阅为用例选择正确的分析器。用于 MinHash 输出的二进制向量字段
您的 Collections 必须包含一个
BINARY_VECTOR字段,用于存储 MinHash 函数生成的二进制向量。维数必须等于32 * num_hashes。
步骤 1:创建带有 MinHash 函数的 Collections
要使用 MinHash 函数,请在创建 Collections 时定义该函数。该函数将成为 Collections Schema 的一部分,并在数据插入和搜索时自动应用。
定义 Schema 字段
你的 Collections 模式必须至少包含三个字段:
主字段:唯一标识 Collections 中的每个实体。
文本字段(
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 函数将分析过的文本转换为二进制向量,以接近文档之间的 Jaccard 相似性。
定义该函数并将其添加到 Schema 中:
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
配置选项
MinHash 函数的params 字典接受以下参数。所有参数名均不区分大小写。
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
int |
从 |
用于生成签名的哈希函数个数。输出二进制向量维数等于 |
|
输入 |
|
用于分层的 N-gram 大小。词级:通常为 1-3。字符级:一般为 2-6。 |
|
字符串 |
|
要使用的哈希函数。选项:
|
|
str |
|
令牌化级别。选项:
|
|
随机种子 |
|
用于 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
创建 Collections
使用上面定义的 Schema 和索引参数创建 Collections:
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 相似度检索最相似的文档。
search_params = {
"metric_type": "MHJACCARD",
"params": {},
}
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
下一步
全文检索:使用 BM25 进行词性相关性排序,而不是近似重复检测。
分析器概述:配置用于文本标记化的自定义分析器。
MINHASH_LSH 索引:了解如何调整 LSH 参数以提高召回率和性能。