slot_combination是一个快速的, 支持模糊匹配的, 多模正则语义解析引擎; 尤其适合中文解析。
- 解析速度非常快 (ms级)
- 支持正则语法
- 支持自定义函数来控制匹配过程 (可以实现很多正则难以实现的表达)
- 支持模糊匹配,带泛化能力, 大大减少开发工作量
- 基于词库的组织方式,便于不同项目复用
- 语义模板功能, 在不同领域间可以快速迁移语义; 大大加快开发速度
atom 播放方式 = 随机|重复|循环
atom 播放 = 听|播放|放
atom 量词 = 一首?|一个
atom 歌曲 = 歌曲|歌
atom 的 = 的|地
rule 类型 = <{.作者}?, {.专辑}?, {.风格}?>
export r1 = [{播放方式}?, {播放}, {量词}?, {类型}, {的}?, {歌曲}|{.歌曲名}] => {intent="播放歌曲", 播放方式=$1, 类型=$4, 歌曲=$6}
"{}"是变量,表示引用;
其中{.作者}, {.专辑}, {.风格}, {.歌曲名}, "."点开始的变量是词典文件, 没有定义在规则中
一条规则能覆盖如下的句子:
循环 播放 一首 周杰伦 七里香 里的 止战之殇
随机 播放 一首 周杰伦 七里香 里的 歌曲
随机 播放 周杰伦 七里香 里的 歌
随机 播放 周杰伦 的 歌
随机 播放 周杰伦 的 **风 歌
给我放下 七里香 里的 止战之殇
给我放下 七里香专辑 周杰伦 的 歌曲
听 一下 稻香
听 那 稻香
...
从例子中可以看出,表达能力主要来源于以下几点:
- 词汇的替换
- 正则语法:"?", 表示可有可无; "|" 表示"或"
[ele1, ele2, ele3, ..]
元素之间可以跳过一定长度的文字(通过配置文件调整;默认为3,若为0就是严格匹配)<ele1?, ele2?, ele3?>
三个元素可有可无,且顺序随机; 元素之间也可以跳过一定长度的字
在不同任务(领域)间, 虽然词汇可能相差很大,但是句子结构可以是非常类似的, 比如:
播放 周杰伦 的 歌曲 稻香 (音乐)
朗诵 李白 的 绝句 静夜思 (诗歌)
----------------------
查询 手机 剩余流量
查询 信用卡 额度
打开 汽车 天窗
上面的音乐
和诗歌
, 不同领域的查询
句子结构是一致的, 如果已有音乐的规则,要开发诗歌领域,直接把音乐领域的句式抽象出来, 扩展到诗歌领域即可。
模板化核心**就是提取出句式结构, 通过修改不同领域的词表映射,自动生成新的规则,来达到快速的语义开发效果。 具体见lex_generator文件夹
- python3.7+
- ahocorasick (pip3 install pyahocorasick)
命令行方式:
python3 engine/app.py -i ${lexFiles} -d ${dictDirPathes} -f ${queryFile} -s ${query}
lexFiles: 规则文件, 可以是逗号分割的文件列表; 或者是个目录,目录中所有lex后缀文件将作为输入 dictDirPathes: 词典目录文件,逗号分割的目录列表, 所有目录中的txt后缀的文件都会被加载; 文件名作为加载的词典名 query: query字符串 queryFile: query文件,用作批量调用
接口调用: 调用engine/app.py里的Engine类
engine = Engine(lexFiles, dictDirPathes)
ans = engine.apply(query)
print(ans)
- 程序结构见engine/IMPL.md文件
- 规则语法说明见syntax.md
- 测试例子见test目录
slot_combination的规则强制要求所有用于匹配的文本关键字都来自于词表或者atom定义的变量(atom可以看作简易词表); 这样有几方面考虑:
- 牺牲了规则的灵活度的同时也约束了开发者的随意性,提升项目的规范度
- 解耦了词汇与完整规则的关系,大大方便复用
- 能提升引擎解析的速度
- 语义模板化基于词汇与规则的解耦
- 与其他词表匹配方式(比如百度unit的词表模板)相比,功能要强大的多, 可以做更多定制开发
- 与常见正则匹配引擎相比,支持常见正则语法的同时,增加了基于词表组织的强制约束和默认的模糊匹配,另外有比正则语法更强大的功能
* 短句多模模式匹配
* 任务式对话语义解析