规则与词典方法:基于关键词的匹配、正则表达式构建意图规则、词典的构建与维护、优缺点分析

说实话,规则和词典方法,是咱们做查询理解最古老、也最朴实的手段。我入行那会儿,深度学习还没火起来,大家全靠这招吃饭。你想想看,一个用户说“帮我查一下明天北京的天气”,你只要抓到“天气”和“北京”这两个词,基本就能猜个八九不离十。这就是规则与词典的核心——用最直接的方式,把用户的意图给“框”出来。

基于关键词的匹配:最朴素的意图识别

关键词匹配,说白了就是“看词说话”。我定义一个意图叫“查天气”,然后往里面塞一堆关键词:天气、气温、下雨、刮风、预报……用户输入里只要命中其中一个,我就认为他想查天气。

嗯,这里要注意一个坑。我在项目中遇到过,用户说“今天天气不错”,结果系统也触发了“查天气”意图。但人家明明是在闲聊,不是真的想查天气。所以单纯的关键词匹配,精度其实挺有限的。

一个常见的改进方案是加权匹配。给每个关键词赋一个权重,比如“天气”权重0.8,“预报”权重0.6,“不错”权重0.1。只有当总分超过某个阈值,才判定为命中。这样能过滤掉不少误触。

核心要点:关键词匹配适合高频、意图明确的场景。比如“关机”、“重启”、“打开微信”这类指令,命中一个词就够了。但遇到“帮我看看明天会不会下雨”这种复杂表达,单靠关键词就容易翻车。

正则表达式构建意图规则:从“看词”到“看模式”

关键词匹配搞不定的事情,正则表达式可以。正则不是只看有没有某个词,而是看词的组合模式。比如用户说“从北京到上海”,关键词匹配只能抓到“北京”和“上海”,但正则能告诉你:哦,这是一个“从A到B”的出行查询。

我个人习惯把正则规则写成这样:

# 查天气意图
r"(?:查询|查|看|看看)?(?:今天|明天|后天|周末)?(?:的)?(?:天气|气温|温度|下雨|刮风)"

# 导航意图
r"(?:导航|去|到|前往)(?:[\u4e00-\u9fa5]+)(?:的)?(?:路线|路|怎么走)"

# 闹钟意图
r"(?:设置|定|调)(?:个|一个)?(?:闹钟|提醒|闹铃)(?:在|为)?(\d{1,2}[::]\d{2})"

你看,正则把“查询天气”、“看看明天天气”、“查一下今天气温”这些变体全都覆盖了。我当年做智能音箱的时候,光闹钟意图就写了二十多条正则,覆盖了“五分钟后叫我”、“明天早上七点叫我起床”、“帮我定个八点半的闹钟”等等。

我的小技巧:写正则的时候,别想着一条规则打天下。拆成多条小规则,每条覆盖一种典型表达。比如“明天天气”一条,“后天天气”一条,“周末天气”一条。这样后期维护起来,脑子不会乱。

不过正则也有它的脾气。你想想看,用户说“帮我看看明天北京会不会下雨”,你的正则如果写成r"天气",那就抓不到“下雨”这个词。所以正则的覆盖范围,需要你反复打磨。我曾经为了一个“查快递”的意图,迭代了七八版正则,才把“我的快递到哪了”、“包裹什么时候到”、“物流信息查一下”这些说法全兜住。

词典的构建与维护:规则背后的“弹药库”

词典是什么?就是关键词的集合。但词典不是简单地把词堆在一起,它是有结构的。我一般把词典分成几类:

词典类型 示例 用途
实体词典 北京、上海、广州、深圳 识别城市、人名、品牌等
动作词典 查、看、设置、打开、关闭 识别用户想做什么
时间词典 今天、明天、后天、下周、周末 识别时间信息
否定词典 不、别、不要、取消、关闭 识别否定意图

词典的维护,说白了就是“加词”和“删词”。我见过不少团队,词典越堆越大,最后里面全是垃圾词。比如“天气”词典里,有人把“气人”也加进去了,就因为“气”字一样。这显然不对。

避坑指南:我曾经接手过一个项目,词典里光“天气”相关的词就有300多个。一查,里面居然有“天桥”、“天然气”、“天气丹”(化妆品品牌)。这些词明显是误加的。所以词典一定要定期清理,最好每个月做一次“词典瘦身”。

词典的构建,我推荐用半自动化+人工审核的方式。先用爬虫或者日志分析,把用户说过的所有词都捞出来。然后按词频排序,人工筛选哪些词跟意图相关。这样既高效,又不会漏掉用户的新说法。

优缺点分析:规则与词典到底值不值得用?

这个问题,我经常被问到。我的回答是:看场景

先说说优点:

  • 速度快。正则匹配和词典查找,毫秒级就能出结果。不像深度学习模型,还得加载、推理。
  • 可解释性强。用户为什么被分到这个意图?因为命中了“天气”这个词。清清楚楚,明明白白。
  • 冷启动友好。新业务上线,没有历史数据怎么办?写几条规则,建个词典,马上就能跑起来。
  • 容易调试。用户反馈说“我明明说了查天气,为什么没识别?”你打开规则一看,哦,漏了“查一下”这个说法,加上就行。

再来说说缺点:

  • 维护成本高。规则和词典需要人工持续维护。用户每说一种新表达,你就得加一条规则或一个词。时间长了,规则库会变得臃肿不堪。
  • 泛化能力差。规则只能覆盖你想到的表达。用户说“明天会不会下雨”,你的规则里只有“天气”,那就识别不出来。
  • 冲突处理麻烦。一条用户输入可能同时命中多个意图。比如“打开天气”,既命中“打开”意图,又命中“天气”意图。这时候谁优先级高?需要你手动定义。
  • 难以处理复杂语义。比如“帮我看看明天北京和上海哪个更冷”,这种比较型的查询,规则写起来就非常痛苦。

我的建议:规则与词典方法,最适合做兜底方案或者冷启动方案。等数据积累到一定程度,再引入机器学习模型。但即使有了模型,规则和词典也别丢。我现在的做法是:模型做主识别,规则做二次校验。模型说这是“查天气”,规则再确认一下有没有“天气”相关的词。两者互补,效果最好。

好了,这一章的内容就这些。规则与词典方法,虽然看起来“土”,但它是理解整个查询理解体系的基石。你想想看,连关键词都抓不准,还谈什么深度学习?先把基础打牢,后面学模型才会更顺手。