橘智橘智
FakeOrange
预计阅读时间:4分钟48秒

使用Sentence-BERT和Elasticsearch构建跨语言搜索

本文详细介绍如何利用Sentence-BERT构建跨语言搜索

0
0

简介


使用 Elasticsearchsentence-transformers 库可以实现多语言的向量化搜索功能。在该方案中,我们将使用 sentence-transformers 提供的模型将文本转化为向量,存储在 Elasticsearch 中,并通过向量相似度来进行搜索。

以下是一个实现多语言搜索功能的完整步骤。



1. 安装依赖


确保安装了 Elasticsearch、sentence-transformers 库以及 elasticsearch Python 客户端。


pip install sentence-transformers elasticsearch



2. 准备 Elasticsearch 索引


我们需要在 Elasticsearch 中创建一个索引,并在其中定义一个向量字段,用于存储文本向量。为了简化操作,我们使用 dense_vector 字段,该字段可以直接用于计算相似度。


from elasticsearch import Elasticsearch

# 创建 Elasticsearch 连接
es = Elasticsearch(hosts=["http://localhost:9200"])

# 定义索引的映射
index_name = "multilingual_index"
mapping = {
    "mappings": {
        "properties": {
            "text": {"type": "text"},           # 原始文本字段
            "text_vector": {
                "type": "dense_vector",
                "dims": 768                     # 假设模型输出768维向量
            },
            "language": {"type": "keyword"}      # 语言字段
        }
    }
}

# 创建索引
if not es.indices.exists(index=index_name):
    es.indices.create(index=index_name, body=mapping)

注意


  • text_vector 字段用于存储向量(在此示例中,模型输出是 768 维向量)。


  • language 字段用于存储语言信息,这样可以在查询时根据语言过滤数据。



3. 使用 sentence-transformers 进行文本向量化


sentence-transformers 提供了多种预训练模型支持多语言搜索,这里选择 paraphrase-multilingual-MiniLM-L12-v2,该模型支持 50 多种语言。


from sentence_transformers import SentenceTransformer

# 加载多语言模型
model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')



4. 插入数据


我们将文本转换成向量并插入到 Elasticsearch 中。插入时,Elasticsearch 将根据向量字段 text_vector 来存储文本的向量表示。


# 示例数据
data = [
    {"text": "Python is a great programming language.", "language": "en"},
    {"text": "Python 是一种很棒的编程语言。", "language": "zh"},
    {"text": "Python es un gran lenguaje de programación.", "language": "es"}
]

# 插入数据
for i, doc in enumerate(data):
    # 将文本转化为向量
    vector = model.encode(doc["text"]).tolist()

    # 插入到 Elasticsearch 中
    es.index(index=index_name, id=i, document={
        "text": doc["text"],
        "language": doc["language"],
        "text_vector": vector
    })

注意


  • 将向量转换为列表(.tolist())以符合 Elasticsearch 的 JSON 格式。


  • 使用 id 可以控制插入的数据,确保每个文本对应的 ID 唯一。



5. 实现搜索功能


为了实现多语言的搜索功能,我们首先将查询文本转换为向量,并在 Elasticsearch 中使用 cosineSimilarityl2Norm 来计算向量之间的相似度。


def search(query_text, language=None, top_k=5):
    # 将查询文本转化为向量
    query_vector = model.encode(query_text).tolist()

    # 构建查询语句
    query = {
        "size": top_k,
        "query": {
            "bool": {
                "must": [
                    {
                        "script_score": {
                            "query": {"match_all": {}},
                            "script": {
                                # 使用 cosineSimilarity 计算相似度
                                "source": "cosineSimilarity(params.query_vector, 'text_vector') + 1.0",
                                "params": {"query_vector": query_vector}
                            }
                        }
                    }
                ]
            }
        }
    }

    # 添加语言过滤(可选)
    if language:
        query["query"]["bool"]["filter"] = [{"term": {"language": language}}]

    # 执行查询
    response = es.search(index=index_name, body=query)
    
    # 返回结果
    results = [
        {"text": hit["_source"]["text"], "score": hit["_score"]}
        for hit in response["hits"]["hits"]
    ]
    return results

参数说明


  • query_text:要搜索的文本。


  • language:语言过滤选项,例如 enzh,若为空则搜索所有语言。


  • top_k:返回的结果数量。


示例


# 搜索英文结果
results = search("Python programming language", language="en")
for result in results:
    print(f"Text: {result['text']}, Score: {result['score']}")



6. 测试效果


可以尝试不同语言的查询,查看返回的多语言文本内容。模型会根据相似度排序,返回与查询最相关的文档。


示例查询


# 使用中文搜索
results = search("编程语言")
for result in results:
    print(f"Text: {result['text']}, Score: {result['score']}")

# 使用西班牙语搜索
results = search("lenguaje de programación")
for result in results:
    print(f"Text: {result['text']}, Score: {result['score']}")

注意事项


  • 向量维度:确保 dense_vector 字段的维度与 sentence-transformers 模型的输出维度一致。


  • 性能优化:多语言模型较大,向量计算耗时,可以考虑缓存常用查询向量或使用更高效的近似向量计算方法(例如 ANN)。


  • 分布式系统:若使用多节点 Elasticsearch 集群,建议合理规划分片和副本数,以提升查询速度和容错能力。


  • 语言过滤:在查询时可指定语言过滤,以保证查询结果符合用户语言需求。


通过 sentence-transformers 将文本转化为语义向量,并借助 Elasticsearch 的 dense_vector 和脚本相似度计算,可以有效地实现一个支持多语言的语义搜索功能。


资料


不同类型的sentence_transformer有不同的效果,比如同义词近义词,跨语言,可以按需挑选:这里链接huggingface


除了语义检索,elasticsearch支持不同权重的文本字段匹配。参考这篇文章:点击这里

评论