引言
许多电子商务网站都希望提升其食谱搜索体验。语义搜索如果应用得当,可以使客户能够根据更自然的查询快速找到所需的食材,例如“情人节的菜肴”或“感恩节大餐”。
在本文中,我们将演示如何使用 Elasticsearch 实现支持此类查询的语义搜索。我们将配置一个索引以存储超市的食材和产品目录,并演示如何使用此索引改进食谱搜索。在整个文章中,我们将解释如何创建此数据结构,以及如何应用自然语言处理技术来提供与客户意图相符的相关结果。
本文中提供的所有代码均使用 Python 开发,并在 GitHub 上提供。您可以访问存储库以查看源代码,根据需要进行调整,并在您的开发环境中直接实施解决方案。
开始实施语义搜索
要开始实施语义搜索,我们首先需要定义自然语言模型。Elastic 提供了自己的模型,ELSER,但也支持集成来自各种提供商(例如 Hugging Face)的 NLP 模型。这种灵活性使您可以选择最适合您需求的选项。
在本文中,我们将使用 ELSER,这降低了部署和管理 NLP 模型的复杂性。此外,Elastic 提供了 semantic_text 功能,这极大地简化了流程。使用 semantic_text,整个嵌入生成过程变得简单直观且自动化。您只需定义一个推理点,并在索引映射中指定接收嵌入的字段。在文档索引过程中,嵌入将被生成并自动与指定的字段关联。
设置步骤
以下是创建支持语义搜索的索引的步骤。按照这些说明,您将拥有一个配置好的索引,可以进行语义搜索。
- 创建 推理点.
- 创建索引,将 description 字段设置为 semantic_text,以便它可以接收嵌入。
- 索引数据 到 grocery-catalog 索引中,该索引将存储产品目录。此目录是从 此处 提供的数据集中获取的。
语义搜索在杂货店的应用
现在,我们已经使用杂货店产品数据填充了索引,我们将测试和验证查询,以使用语义搜索改进搜索结果。我们的目标是提供更智能的搜索体验,了解上下文和用户意图,提供更相关和准确的结果。
语义搜索解决的挑战
基于产品目录,让我们探讨语义搜索如何通过解决传统词汇搜索经常难以处理的词汇和上下文问题来改变杂货店的搜索体验。
1. 解释烹饪意图
问题 01:客户可能会搜索“适合烧烤的海鲜”,但词汇搜索系统可能无法完全理解查询背后的意图。它可能无法识别所有适合烧烤的海鲜产品,只会返回产品标题中包含“海鲜”或“烧烤”的确切术语的产品。
首先,我们将执行词汇搜索并分析结果。然后,我们将使用语义搜索执行相同的操作,比较相同搜索词的结果。
词汇搜索查询
response = client.search(
index="grocery-catalog",
size=5,
source_excludes="description_embedding",
query={
"multi_match": {
"query": "seafood for grilling",
"fields": [
"name",
"description"]
}
}
)
结果
搜索类型 | 名称 | 分数 |
---|---|---|
词汇 | 西北渔业阿拉斯加白氏雪蟹 | 10.453125 |
词汇 | 吉田先生原创美食酱 | 7.2289705 |
词汇 | 高级海鲜拼盘 - 20 件 | 7.1924105 |
词汇 | 美国红鲷鱼 - 整条,带头,清洁 | 6.998647 |
词汇 | 龙虾钳和臂,可持续野生捕捞 | 6.438654 |
词汇搜索返回了一些适合烧烤的海鲜产品,例如美国红鲷鱼和西北渔业阿拉斯加白氏雪蟹。但是,词汇搜索在结果列表顶部返回了不太相关的产品,例如吉田先生的酱汁,这并不是海鲜产品,而是一种肉酱,表明词汇算法难以完全理解“适合烧烤”的上下文。
语义搜索解决方案
我们使用一个查询,将“海鲜”与“烧烤”等准备上下文结合起来,以返回全面的选项列表,例如鱼片、虾和扇贝,这些都非常适合烧烤——即使产品名称中没有直接出现“烧烤”或“海鲜”字样。这确保搜索结果更符合客户的意图。
语义搜索查询
es_client.search(
index="grocery-catalog-elser",
size=size,
source_excludes="description_embedding",
query={
"semantic": {
"field": "description_embedding",
"query": "seafood for grilling"
}
})
搜索类型 | 名称 | 分数 |
---|---|---|
语义 | 带头去鳞清洁的欧洲鲈鱼 | 16.175909 |
语义 | 阿拉斯加黑鳕鱼(银鳕鱼) | 15.855331 |
语义 | 美国红鲷鱼 - 整条,带头 | 15.454779 |
语义 | 西北渔业阿拉斯加白氏雪蟹 | 15.855331 |
语义 | 美国红鲷鱼 - 整条,带头 | 15.3892355 |
语义搜索不仅返回了与“海鲜”直接相关的产品,还理解了“烧烤”的上下文,带来了适合烧烤的整鱼和鱼片。这里的关键在于结果的精确性,其中包括欧洲鲈鱼和阿拉斯加黑鳕鱼等整鱼选项,这两种鱼都常用于烧烤。
问题 02 :许多客户在工作了一天后会寻找快速简便的晚餐解决方案,使用诸如“简单的平日晚餐”之类的术语。传统的词汇搜索可能无法完全捕捉到快速餐点的概念,通常只关注名称中包含“简单”一词的产品。
与上一个问题一样,我们将首先执行词汇搜索。之后,我们将应用语义搜索解决方案。
词汇搜索查询
response = client.search(
index="grocery-catalog",
size=5,
source_excludes="description_embedding",
query={
"multi_match": {
"query": "easy weeknight meals",
"fields": [
"name",
"description"]
}
}
)
结果
搜索类型 | 名称 | 分数 |
---|---|---|
词汇 | 艾弗里易剥标签,4200 张 | 8.017723 |
词汇 | Omeals 自加热应急/便携式餐食 32 个 | 6.592727 |
词汇 | 海岸海鲜黄鳍金枪鱼丁 | 5.836883 |
词汇 | 耐用超重 12 盎司泡沫 | 5.8116536 |
词汇 | 名流日常餐巾,双层,110 张 | 5.752989 |
词汇搜索返回的结果相关性较低,包括与餐食完全无关的商品,例如艾弗里易剥标签和名流日常餐巾。这些产品不能满足用户对快速餐点的需求。虽然词汇搜索确实返回了一个有用的产品(Omeals 自加热应急餐食),但其他结果,如餐巾和标签,只与其描述中的“简单”或“平日”字样匹配,而没有真正解决用户对快速餐食解决方案的意图。
语义搜索解决方案
我们实现了一个查询,可以理解快速简便餐点背后的意图。它关联可以快速准备的产品,例如预煮肉类、冷冻意大利面或简易餐食盒,即使它们在名称中没有明确包含“简单”一词。这种方法确保客户找到最适合快速平日晚餐的选项,满足对便捷性的需求。
语义搜索查询
es_client.search(
index="grocery-catalog-elser",
size=size,
source_excludes="description_embedding",
query={
"semantic": {
"field": "description_embedding",
"query": "easy weeknight meals"
}
})
结果
搜索类型 | 名称 | 分数 |
---|---|---|
语义 | Omeals 自加热应急/便携式餐食 32 个 | 14.610006 |
语义 | 日清杯面,虾味,2.5 盎司 | 13.751424 |
语义 | Namaste 无麸质华夫饼和煎饼粉 | 13.73376 |
语义 | 爱达荷土豆,黄金烤土豆泥 | 12.549422 |
语义 | 日清杯面,鸡肉味,24 个装 | 12.034527 |
语义搜索返回了与快速便捷餐点明显相关的产品,例如方便面(杯面)、预煮土豆和煎饼粉,这些都是快速平日晚餐的典型选择。这表明语义搜索可以理解“简单的平日晚餐”短语背后的概念,捕捉用户寻找快速便捷餐点的意图。有趣的是,当其他类别的产品(例如“苏打水”)在上下文中相关时,也可能会包含在内(例如,与餐点搭配的饮料)。
2. 地区术语和词汇变化
问题:一个客户可能会搜索“苏打水”,而另一个客户可能会使用“汽水”来指代相同的产品。传统的词汇搜索无法识别这两个术语都指代同一商品。
词汇搜索查询
response = client.search(
index="grocery-catalog",
size=5,
source_excludes="description_embedding",
query={
"multi_match": {
"query": "refreshing pop drink low sugar",
"fields": [
"name",
"description"]
}
}
)
结果
搜索类型 | 名称 | 分数 |
---|---|---|
词汇 | Prime Hydration+ 棒状电解质饮料粉 | 14.492869 |
词汇 | 卡布里苏100%果汁,多种口味组合装 | 12.340851 |
词汇 | Joyburst 能量饮料,Frose Rose,12 个装 | 11.839179 |
词汇 | 家乐氏Pop-Tarts,覆霜红糖肉桂味 | 9.97788 |
词汇 | Kind 迷你棒,多种口味组合装,0.7 盎司 | 9.336912 |
词汇搜索侧重于精确的词语匹配。虽然它返回了像Prime Hydration和Capri Sun这样的产品,但与“pop”一词的直接匹配也导致了一些不相关的结果,例如Kellogg’s Pop-Tarts,这是一种零食而不是饮料。这突显了当一个词有多个含义或可能模棱两可时,词汇搜索的效率可能较低。
语义搜索解决方案
在语义查询中,我们可以克服词汇搜索无法解决的词汇变化问题。通过扩展搜索词,我们可以根据上下文含义获得结果,从而提供更相关和全面的响应。
查询示例
es_client.search(
index="grocery-catalog-elser",
size=size,
source_excludes="description_embedding",
query={
"semantic": {
"field": "description_embedding",
"query": "refreshing pop drink low sugar"
}
})
结果
搜索类型 | 名称 | 分数 |
---|---|---|
语义 | Olipop 12盎司益生元苏打水组合装 | 14.776867 |
语义 | Bai抗氧化椰香融合饮料组合装,18瓶 | 14.663253 |
语义 | Monster能量饮料,Zero Ultra,24瓶 | 14.486348 |
语义 | Joyburst能量饮料组合装,12 盎司 | 14.007214 |
语义 | Joyburst 能量饮料,Frose Rose,12 个装 | 13.641038 |
语义搜索返回的产品直接匹配“pop”作为“苏打水”(例如Olipop益生元苏打水)的同义词的概念,即使产品名称中可能不存在“pop”这个确切的词语。搜索理解了用户的意图——一种清爽的低糖饮料——并且能够返回相关产品,包括益生元苏打水(Olipop)和无糖能量饮料(Monster能量饮料)等选项。
结论
在杂货店环境中实施语义搜索已被证明在理解诸如“适合烧烤的海鲜”和“简单的平日晚餐”之类的复杂查询方面非常有效。这种方法使我们能够更准确地解读用户意图,并返回高度相关产品。
通过使用Elasticsearch并利用ELSER简化流程,我们能够快速有效地应用语义搜索,显著改善搜索结果,并提供更灵活和更有针对性的购物体验。这不仅优化了搜索过程,还提高了为客户提供的搜索结果的相关性。
参考文献
模型 ELSER
https://elastic.ac.cn/guide/en/elasticsearch/reference/current/put-inference-api.html
https://elastic.ac.cn/guide/en/elasticsearch/reference/current/infer-service-elser.html
语义文本
https://elastic.ac.cn/guide/en/elasticsearch/reference/current/semantic-text.html
https://elastic.ac.cn/guide/en/elasticsearch/reference/current/semantic-search.html
数据集
https://www.kaggle.com/datasets/bhavikjikadara/grocery-store-dataset?select=GroceryDataset.csv
语义搜索
https://elastic.ac.cn/guide/en/elasticsearch/reference/current/semantic-search.html
https://elastic.ac.cn/guide/en/elasticsearch/reference/current/semantic-search-semantic-text.html
Elasticsearch 拥有众多新功能,可帮助您为您的用例构建最佳搜索解决方案。深入了解我们的示例笔记本以了解更多信息,开始免费云试用,或立即在您的本地机器上试用 Elastic。
想获得 Elastic 认证?了解下一场Elasticsearch 工程师培训何时开始!