短语到过滤器映射:产品过滤器的语义搜索
本文解释了我们如何生成和扩展短语到过滤器的映射,这些映射为我们的过滤器提取系统提供支持。这些映射将搜索查询中的自然语言短语连接到结构化产品过滤器。
问题:从自然语言中提取过滤器
当用户搜索"带16GB内存的迷你电脑"时,我们需要提取:
-
外形规格:迷你电脑
-
内存:16
但用户会用多种方式表达相同的意图:
-
"16GB内存迷你电脑"
-
"16GB内存小型电脑"
-
"迷你计算机16GB内存"
-
"带16G内存的紧凑型台式机"
我们需要一个系统,能够将所有短语变体映射到正确的过滤器值。
两步流程
我们通过两个步骤生成短语映射:
这种混合方法结合了基于规则的精确性和语义的灵活性。
步骤3a:基础短语生成
特性元数据
每个产品特性在特性序列中都有元数据:
-
标题:类别名称(例如,处理器特性用"Processing")
-
单位:计量单位(例如,内存用"GB",频率用"GHz")
这些元数据指导短语生成。
基于排列组合的生成
对于每个特性值,我们生成以下所有排列组合:
-
标题:"processor"
-
特性键:"series"
-
值:"i5"
-
单位:(系列没有单位)
这会产生:
-
"processor series i5"
-
"series processor i5"
-
"i5 processor series"
-
"i5 series processor"
-
"processor i5"
-
"series i5"
-
"i5"
所有排列确保我们匹配查询,无论词序如何。
值 + 单位组合
对于带单位的特性(内存、存储、频率),我们生成带空格和不带空格的变体:
-
"16 gb"(带空格)
-
"16gb"(无空格)
这些与其他组件组合:
-
"16gb ram"
-
"ram 16gb"
-
"processor 16gb"
端口后缀规则
对于连接性特性(USB、HDMI、DisplayPort),我们添加端口后缀:
-
"usb port"
-
"usb ports"
-
"2 usb ports"
-
"hdmi port"
这可以匹配像"带2个HDMI端口的迷你电脑"这样的查询。
特定于特性的规则
每种特性类型都有自定义的短语生成:
处理器系列(i3、i5、N系列):
-
核心处理器指定生成变体:制造商名称、核心品牌、组合形式
-
N系列处理器(N100等)创建类似的模式组合
-
每个都生成多个带"processor"的排列组合
内存:
-
数值生成带空格和不带空格的GB变体("16gb"、"16 gb")
-
自动附加"ram"和"memory"限定词("16gb memory"、"16 gb ram")
SSD存储:
-
数值生成GB变体("512gb"、"512 gb")
-
对于值≥1024,自动生成TB变体(例如,1024GB → 1TB)
-
自动附加"ssd"和"storage"限定词("512gb ssd"、"512 gb storage")
外形规格:
-
迷你电脑 → 多个变体,包括无空格形式
-
一体机 → "all in one"、"aio"、缩写形式
-
瘦客户机 → 带/不带空格的变体
-
工业电脑 → 缩写和完整形式
代次:
- 数值生成值变为:"12th gen"、"12th generation"、"gen 12"
核心数:
-
2 → "dual core"
-
4 → "quad core"
-
6 → "hexa core"
-
8 → "octa core"
-
所有都生成"[n] core processor"变体
以太网:
-
"1000" → ["gigabit ethernet"、"gbe"、"1gbps"]
-
"2500" → ["2.5gbe"、"2.5 gigabit"、"2.5gbps"]
操作系统:
-
"Windows 11" → ["windows"、"windows 11"、"win 11"]
-
"Ubuntu" → ["linux"、"ubuntu"]
-
"FreeDOS" → ["freedos"、"no os"、"without os"]
独立值白名单
只有特定的特性允许独立值匹配,以防止错误匹配:
-
系列:"i3"、"i5"、"N100"(但不包括单个字母)
-
处理器型号:"N100"、"1335U"
-
操作系统:"Windows"、"Linux"、"Ubuntu"
-
代次:"12th"、"13th"、"14th"
-
处理器品牌:"Intel"、"ARM"
例如,当查询是"2 hdmi ports"时,"2"不应该匹配"2 cores"。长度检查防止单个字母或非常短的模糊值被独立匹配。具有明确单位组件的特性,如以太网或端口,仅在带有其单位限定时才生成独立组合。
冲突预防
内存和存储值有重叠(两者都有64、128、256等)。步骤4强制执行值范围规则以消除歧义:
-
≤ 64 GB:内存(RAM)
-
≥ 128 GB:SSD存储
-
65-127 GB范围:跳过(模糊)
带有明确限定词("ram"/"memory"或"ssd"/"storage")的短语覆盖此规则,并且可以匹配任何值。
此外,通过后处理在冲突解决期间排除匹配太多不相关过滤器的模糊通用术语:像"connectivity"、"audio"、"display"、"processor"和"physical"这样的术语在多个方面造成太多歧义。
步骤4:语义扩展
N-gram提取
我们从真实的搜索查询中提取频繁出现的短语,范围从单个单词(1-gram如"mini")到更长的序列(最多6-gram如"mini pc with 16gb ram ssd")。只保留至少出现3次的短语。这种过滤方法减少了噪音,同时保留了真实的用户语言模式。
过滤器搜索文本生成
对于每个过滤器值,我们生成搜索文本:
内存:16:
-
"16gb ram memory"
-
"16 main memory"
-
"main memory 16"
SSD存储:512:
-
"512gb storage ssd"
-
"512 ssd storage"
-
"ssd storage 512"
这些搜索文本在嵌入空间中表示过滤器。
嵌入和匹配
我们将查询短语和过滤器搜索文本都转换为嵌入向量,然后计算它们之间的余弦相似度。相似度得分高于配置阈值的短语被添加到该过滤器的映射中。
手动种子短语
我们在扩展之前注入高置信度的手动种子:
"Series:i5": [
"i5",
"core i5",
"intel i5",
"intel core i5",
"i5 processor",
"cpu i5",
]
这些种子代表我们知道对每个过滤器正确的核心短语。通过以最大相似度得分包含它们,它们指导扩展算法找到具有相似含义的相关短语。这些种子始终获得相似度1.0并指导扩展。
增量嵌入
我们缓存短语和过滤器搜索文本的嵌入向量。当新查询到达时:
- 加载现有嵌入向量
- 仅嵌入新短语
- 追加到缓存
这避免了重新嵌入未更改的数据。详见嵌入策略。
冲突解决
相似度匹配完成后,我们解决内存和存储过滤器之间的冲突:
基于数字的消歧:
-
对于包含数字的模糊短语:如果短语的值≤64,仅保留给内存;如果>64,仅保留给存储
-
这防止"16gb"匹配SSD存储过滤器以及"512gb"匹配内存过滤器
明确限定词覆盖规则:
-
带有"ram"、"memory"、"cpu"、"processor"关键词的短语 → 仅内存
-
带有"ssd"、"storage"、"disk"、"nvme"、"drive"关键词的短语 → 仅存储
-
示例:"processor 8gb"映射到内存,尽管它是数字
模糊术语:
- 删除像"connectivity"、"audio"、"display"这样匹配多个不相关过滤器的短语
输出格式
最终映射按相似度(最高优先)排序,然后按长度(最短优先)排序:
{
"Main Memory:16": [
{"phrase": "16gb ram", "similarity": 1.0},
# ...(实现细节省略)
与过滤器提取的集成
这些映射为过滤器提取算法提供支持:
- 查询到达:"mini pc with 16gb ram"
- 提取短语:["mini pc"、"16gb ram"、"mini"、"pc"、"16gb"、"ram"]
- 使用映射将短语匹配到过滤器
- 返回过滤器:
{"Form Factor": ["Mini PC"], "Main Memory": ["16"]}
详见过滤器提取算法。
存储和分发
短语映射以JSON文件形式持久化,并在整个系统中使用:
-
基础映射文件:在步骤3a生成,包含基于规则的短语
-
扩展映射文件:在步骤4生成,包含语义扩展结果
扩展映射被以下部分使用:
-
查询页面生成:从查询文本提取过滤器
-
搜索服务:实时过滤器提取API
-
产品匹配:通过提取的过滤器过滤产品
性能特征
基础生成(步骤3a):
-
处理时间随过滤器值的数量而变化
-
生成大量基础短语变体
-
生成期间内存使用保持适中
语义扩展(步骤4):
-
处理时间随查询量和嵌入大小而变化
-
输出包含比基础生成多得多的短语
-
由于嵌入向量存储,内存需求增加
由于相似度计算,扩展是CPU密集型的。使用NumPy和BLAS加速显著加快了矩阵运算。
与SEO管道的集成
短语映射生成是SEO管道中的步骤3a和4:
- 步骤0:嵌入源数据 - 产品、部件、文章
- 步骤1:获取查询 - GSC、Google Ads、实时、Algolia
- 步骤2:合并查询 - 合并所有来源
- 步骤3a:生成基础短语映射 ← 您在此处
- 步骤3b:嵌入查询 - 转换为向量
- 步骤4:扩展短语映射 ← 您在此处
- 步骤5:聚类查询 - 分组到页面
- 步骤6:匹配产品 - 查询-产品匹配
- 步骤7:构建查询页面 - 生成HTML
- 步骤8:生成相关搜索 - 查找相关查询
- 步骤11:迁移到Valkey - 加载到搜索服务
详见SEO管道概述了解完整流程。
为什么分两步?
基础生成(步骤3a) 提供:
-
精确性:基于规则的短语精确匹配我们期望的内容
-
覆盖范围:排列确保覆盖所有词序
-
控制:特定于特性的规则处理领域知识
语义扩展(步骤4) 提供:
-
灵活性:发现我们未预料到的短语
-
真实用户语言:从实际搜索查询中学习
-
同义词:找到等效短语("16 gigs"对应"16gb")
两者结合,平衡了精确性和召回率。
参考资料
技术概念
模型文档
-
all-mpnet-base-v2 - Hugging Face
-
Sentence Transformers - 官方文档
相关文章
总结
我们通过两个步骤生成短语到过滤器的映射:
步骤3a(基础生成):
-
生成标题、键、值、单位的所有排列组合
-
应用特定于特性的规则(处理器系列、内存、存储、外形规格)
-
为连接性特性添加端口后缀
-
为特定特性设置独立值白名单
-
从规则输出基础短语集
步骤4(语义扩展):
-
从真实搜索查询中提取n-gram短语
-
嵌入短语和过滤器搜索文本
-
匹配相似度得分高于阈值的短语
-
注入手动种子短语以指导扩展
-
解决内存/存储冲突
-
输出扩展和消歧后的短语集
结果是一个全面的映射,处理了预期的短语(通过规则)和意外的变体(通过语义相似性)。这些映射为查询页面、搜索和产品匹配中的过滤器提取提供支持。