在处理文本数据时,经常遇到需要对字符串进行模糊匹配的场景。模糊匹配是指在不完全相同的情况下找到相似字符串的过程,在文本搜索、数据清洗、自然语言处理等领域都极为重要。本文介绍一个高效的模糊字符串匹配技术:Llama Index 。
Llama Index 介绍
Llama Index 是一种基于近似字符串匹配算法的索引结构,用于快速检索与目标字符串相似的字符串集。它利用了数据结构和算法优化,以达到在大规模数据集上进行快速匹配的能力。
工作原理
Llama Index 是一个基于几个核心概念的索引技术。这些核心概念包括倒排索引、n-gram 分析和编辑距离:
- 倒排索引(Inverted Index): 倒排索引是一种常用的索引结构,用于快速查找包含特定词项的文档。它将词项映射到包含该词项的文档列表,以支持高效的全文搜索。
- n-gram 分析: n-gram 是一种文本分析技术,用于将文本切分成连续的 n 个字符或词项。通过使用不同的 n 值,可以捕捉不同长度的文本片段,从而支持更灵活的文本匹配和搜索。
- 编辑距离(Edit Distance): 编辑距离是衡量两个字符串之间相似度的指标。它表示将一个字符串转换为另一个字符串所需的最少编辑操作次数,包括插入、删除和替换字符。编辑距离在文本匹配和拼写纠错等应用中非常有用。
Llama Index 将所有输入字符串转换为 n-gram,并为这些 n-gram 创建一个倒排索引。当执行搜索时,目标字符串也被转换成 n-gram,然后索引被用来快速找出包含这些 n-gram 的字符串。最终,通过计算编辑距离对这些候选字符串进行排名,以确定它们与目标字符串的相似程度。
倒排索引提供了快速的文档检索能力,n-gram 分析可以捕捉文本的局部特征,而编辑距离则用于度量文本之间的相似度。通过结合这些技术,Llama Index 可以提供强大的文本搜索和匹配功能。
查询过程
Llama Index 的查询过程涉及几个关键步骤,每个步骤都旨在加速查找与查询字符串相似的字符串条目。以下是这个流程的详细说明:
1. 查询预处理
查询字符串首先会经过预处理,这通常包括将字符串转换为小写(如果大小写不敏感)、去除空格和标点符号等。之后,它会被分解成 n-gram。
例如,如果使用的是 bi-gram(2-gram),查询字符串 "hello" 会被分解为 ["he", "el", "ll", "lo"]。
2. n-gram 检索
预处理后的 n-gram 会被用来查询 Llama Index。每个 n-gram 都有一个对应的倒排索引列表,这些列表包含了所有包含该 n-gram 的字符串的引用。
对于每个 n-gram,Llama Index 会快速检索出包含该 n-gram 的所有字符串。这些字符串随后汇总成一个候选列表,待进一步处理。
3. 候选字符串筛选
在初步收集了候选字符串之后,Llama Index 可以使用多种策略进一步筛选这些候选项。这可能包括检查 n-gram 之间的重叠、考虑它们在各自字符串中的位置等。
筛选的目的是减少后续编辑距离计算所需处理的字符串数量,从而降低算法的复杂性。
4. 编辑距离计算
对于筛选后的候选字符串,Llama Index 接下来会计算这些字符串与查询字符串之间的编辑距离。编辑距离计算可以判断两个字符串的相似程度。
编辑距离越小,意味着两个字符串越相似。通常,会设置一个门槛值,只有编辑距离小于或等于这个值的字符串才会被认为是匹配的。
5. 排序和选择
根据编辑距离进行排序后,Llama Index 会根据需求返回最佳匹配或一组高度相似的字符串。这个排序步骤确保了查询结果的相关性。
6. 结果返回
最终,经过排序和筛选的匹配结果会被返回给用户。这个结果集可能包括一个最佳匹配项、一组前 N 个最佳匹配项,或者所有编辑距离在某个阈值内的匹配项。
模糊字符串匹配
准备开始
节点(Node)表示源文档的"块",无论是文本块、图像或者其他内容。此外还包含元数据以及与其他节点和索引结构的关系信息。
为了获得精确的结果并单独处理节点,这里避免在它们之间创建任何连接,例在下图中,由于存在连接,使用可能会混淆节点的响应。
在查询时候,从查询中提取相关关键字,并将这些关键字与预先提取的 Node 关键字进行匹配,以获取相应的节点,提取的节点被传递到我们的响应综合模块。
py
from llama_index.schema import TextNode
from langchain.chat_models import ChatOpenAI
from llama_index import LLMPredictor, ServiceContext
products = ["iPhone 15 Pro", "Samsung Galaxy", "Huawei P60 Pro", "Google Pixel 8 Pro", "Sony WH-1000XM4 Headphones", "Logitech MX Master 3 Mouse", "Dell XPS 13 Laptop", "Bose QuietComfort Earbuds", "Logitech MX Master 3 Mouse", "Dell XPS 13 Laptop", "Xbox Series X", "Roomba i7+", "Canon EOS R5 Camera", "Nikon D3500 DSLR", "GoPro HERO9 Black", "Sony Alpha a7 III"]
nodes = []
for product in products:
nodes.append(TextNode(text=product))
llm_predictor = LLMPredictor(llm=ChatOpenAI(temperature=0, model_name="gpt-4"))
service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor)
index = VectorStoreIndex(nodes=nodes, service_context=service_context)
查询
查询还涉及三个基本构建块:检索器(retriever)、后处理(post-processing)、响应合成(response synthesis)。使用 API 可以与每个模块进行交互,并根据需要对其进行自定义,下面使用检索器来查询我的索引。
py
retriever = index.as_retriever(similarity_top_k=1, choice_batch_size=1)
samples = ['dellxps','mxmaster','context express','eos r5',
'd3500','III']
for sample in samples:
results = retriever.retrieve(f"find {sample}")
print(sample,':', results[0].node.text)
print()
如果要匹配实体,则可能希望匹配 ID 以避免反向查找,也可以定义自己的节点 ID。但是只查询索引,则不会得到具体的一个结果:
底层逻辑
通过使用索引直接查看嵌入(embedding)的方法:
检索器的结果会返回分数,即嵌入样本和索引实际节点的余弦相似度,得分最接近 1.0 的就是最佳结果。嵌入只是表示由某个模型计算的文本语义的数字列表。默认情况下,LlamaIndex 使用来自 OpenAI 的 text-embedding-ada-002 模型,它也可以自定义。
结语
Llama Index 提供了一个强大的工具,用于处理模糊字符串匹配问题,它通过智能地结合倒排索引、n-gram 分析和编辑距离计算,能够在维持高效率的同时,提供高度的准确性。无论是在处理大量的文本数据,寻找相似的文档,还是尝试在海量数据库中快速定位信息,Llama Index 都是一个值得考虑的解决方案。