不期速成 日拱一卒 不期速成 日拱一卒
首页
技术
测试
分类
标签
归档
关于
首页
技术
测试
分类
标签
归档
关于
  • 测试样本

    • 智能算法测试样本管理简介
    • AITDBManger开发指导
    • AITDBClient开发指导
    • AITDBClient使用文档
  • 测试框架

  • AITLibra-智能算法效果测试提效降本的实践
  • NLU(自然语言理解)智能算法测试从1到N的改进
    • 1 前言
      • 1.1 什么是NLP
      • 1.2 什么是NLU
    • 2 如何度量其质量---NLU评估指标
      • 2.1 评估指标
    • 3 如何实现上述维度的客观、高效度量
      • 3.1 我们需要解决的问题
      • 3.2 重难点分析
    • 4 核心改进要点
      • 4.1 基于yaml的语料构造和jsonpath的语料标注
      • 4.2 算法效果测试改进
    • 5 优化效果评价
    • 6 附录
      • 6.1 CorpusFactory核心步骤使用流程图
      • 6.2 CorpusFactory设计流程图
    • 7 致谢
  • 智能算法测试平台基础设施
  • AIT
2020-12-28

NLU(自然语言理解)智能算法测试从1到N的改进

From 智能化产品测试团队

# 1 前言

# 1.1 什么是NLP

在人工智能出现之前,机器只能处理结构化的数据(例如有明确的字段关系表格数据),但互联网中大部分数据都是非结构化的,例如:文章、图片、音频、视频......其中很多信息都是以文本为载体存在的,为了能够利用和分析这些文本信息,我们就需要利用NLP技术,让机器理解这些文本信息,并加以利用。

NLP(Natural Language Process ) ---- 自然语言处理就是人类和机器之间沟通的桥梁。

自然语言就是大家平时在生活中常用的表达方式,大家平时说的“讲人话”就是这个意思。

NLP是个很大的体系,其包含的内容如下图所示:

# 1.2 什么是NLU

我们用一个具体的案例来说明下什么是NLU。

对话系统这个事情在2015年开始突然火起来了,主要是因为一个技术的普及:机器学习特别是深度学习带来的语音识别(ASR)和NLU(自然语言理解)--- 主要解决的是识别人讲的话。这个技术的普及让很多团队都掌握了一组关键技能:意图识别和实体提取。

这意味着什么?我们来看一个例子。

在生活中,如果想要订机票,人们会有很多种自然的表达:

"订一张去北京的机票";

“有去北京的航班吗?”;

“看看航班,下周二出发去北京”;

“要去北京出差,帮我查下机票”;

……

可以说“自然的表达”有无穷多的组合(自然语言)都在代表“订机票”这个意图,而听到这些表达的人,可以准确理解这些表达指的是“订机票”这件事。

而要理解这么多不同的表达,对机器是个挑战。在过去,机器只能处理“结构化的数据”(比如关键词),也就是说如果要听懂人在说什么,必须要用户输入精确的指令。所以,无论你说“我要出差”还是“帮我看看去北京的航班”,只要这些字里面没有包含提前设定的关键词“订机票”,系统都无法处理。而且,只要出现了关键词,比如“我要退订机票”里也有这三个关键词,也会被处理成用户想要订机票。

我们本文将要分享的内容即为NLU(Natural Language Understanding)--- 自然语言理解的智能算法测试方法的改进思考和实践。

自然语言理解这个技能出现后,可以让机器从各种自然语言的表达中,区分出来,那些话归于这个意图,而哪些表达不是归于这一类的,而不再依赖那么死板的关键词。比如经过训练后,机器能够识别“帮我推荐一家附近的餐厅”,就不属于“订机票”这个意图的表达。

并且,通过训练,机器还能够在句子当中自动提取出来“北京”,这两个字指的是目的地这个概念(即实体),“下周二”指的是出发时间。

这样一来,看上去机器就能听懂人话了。

# 1.2.1 烽火在公安领域NLU相关的概念

我司在NLU领域探索开拓的有两个团队,IAO和KG,两个团队的NLU体系标准和定义有所区别,我们以较为复杂的烽火IAO-NLU体系为例进行讲解阐述。

对于”查询13301791708的酒店同房间人员“这个测试语料,其NLU算法服务处理返回结果为:

{
    "code": 200,
    "data": [
        {
            "apps": {
                "app_op_seq": []
            },
            "content": {
                "des": {
                    "phone_number": "13301791708"
                },
                "ont": "SIM_Card",
                "rel": [
                    {
                        "des": {},
                        "ont": [
                            "SIM_Card",
                            "Person"
                        ],
                        "rel": [
                            {
                                "behavior": [
                                    {
                                        "category": "伴随分析",
                                        "location": [],
                                        "modifiers": [],
                                        "number": [],
                                        "target": null,
                                        "time": [],
                                        "traffic": []
                                    }
                                ],
                                "des": {
                                    "intent": [
                                        "full"
                                    ]
                                },
                                "intentPro": [
                                    "entity"
                                ],
                                "ont": [
                                    "Person",
                                    "Person"
                                ],
                                "relIdx": [
                                    0,
                                    "14-19"
                                ],
                                "relName": "酒店同房间同宿",
                                "segs": [
                                    "查询13301791708的酒店同房间人员"
                                ]
                            }
                        ],
                        "relIdx": [
                            0,
                            "13-19"
                        ],
                        "relName": "使用人",
                        "segs": [
                            "查询13301791708的酒店同房间人员"
                        ]
                    }
                ],
                "segs": [
                    "查询13301791708的酒店同房间人员"
                ]
            },
            "content_op": "查询"
        }
    ],
    "data_op": {
        "data_rel": [
            ""
        ],
        "data_rel_property": []
    },
    "msg": "",
    "unknown": [
        {
            "keyword": "酒店",
            "ont": "unknown"
        }
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

结合NLU的业界标准,以及我司在公安领域的深耕和应用场景,我们对NLU的识别结果分为以下几个类别。

# 1.2.1.1 本体

本体(ontology,缩写为ont),在计算机科学与信息学领域,理论上,本体是指一种”形式化的,对于共享概念体系的明确而又详细的说明“,

我们可以简化的理解为自然语言中的诸多对象。

举个例子,对于”查询13301791708的酒店同房间人员“这句话,其中的本体为:

  • SIM_Card
  • ['SIM_Card', 'Person']
  • ['Person', 'Person']
# 1.2.1.2 属性

属性(ontology_attribute),即指的是各个本体的属性。

举个例子,对于”查询13301791708的酒店同房间人员“这句话,其中的属性为:

  • phone_number,其属性值为”13301791708“
# 1.2.1.3 关系

关系(relname),是指多个本体之间的关系名词。

举个例子,对于”查询13301791708的酒店同房间人员“,其中的关系为:

  • 酒店同房间同宿

# 1.2.1.4 行为

行为(behavior),此为我们公司结合公安领域的特性定义的识别结果分类

举个例子,对于”查询13301791708的酒店同房间人员“,其中的行为类别为:

  • category,其值为”伴随分析“
# 1.2.1.5 意图

意图(intention),即为一句话或一段话的目的是什么,烽火IAO-NLU体系对其定义为几个有限集合,便于上层业务查询使用。

举个例子,对于”查询13301791708的酒店同房间人员“,其中的意图为:

  • ['full']

# 2 如何度量其质量---NLU评估指标

首先,我们需要明确从哪些维度去客观、严谨、全面的评估NLU算法质量。这里我们通过对NLU实现过程的深入了解,以及对标行业内在相关领域的实践经验,结合我司网安领域的业务场景,对IAO-NLU体系的NLU能力确定了如下维度的评估指标。

# 2.1 评估指标

# 2.1.1 本体识别

$$ 本体识别精确率 = \frac {识别正确的本体个数} {识别出来的本体个数} \times 100% $$

$$ 本体识别召回率 = \frac {识别正确的本体个数} {期望识别出来的本体个数} \times 100% $$

$$ 本体识别错误率 = \frac {识别错误的本体个数} {识别出来的本体个数} \times 100% $$

举例说明:

100条测试问句中,覆盖Person本体50个

  • 识别出40个Person本体;
  • 识别正确的38个Person本体;
  • 识别错误的2个Person本体;

Person本体识别精确率=38 / 40

Person本体识召回率=38 / 50

Person本体识错误率=2 / 40

# 2.1.2 属性识别

$$ 属性识别精确率 = \frac {识别正确的属性个数} {识别出来的属性个数} \times 100% $$

$$ 属性识别召回率 = \frac {识别正确的属性个数} {期望识别出来的属性个数} \times 100% $$

$$ 属性识别错误率 = \frac {识别错误的属性个数} {识别出来的属性个数} \times 100% $$

举例说明:

100条测试问句中,覆盖person_name属性50个(假设其中1个元素重复了5次)

  • 识别出person_name属性共计40个;

  • 识别正确的的38个(重复元素正确识别3次);

  • 识别错误的2个(重复元素错误识别1次,重复元素漏识别1次);

person_name属性识别精确率=38 / 40

person_name属性识别召回率=38 / 50

person_name属性识别错误率=2 / 40

# 2.1.3 关系识别

解释说明:

关系所在层级及关系值均正确,即视为正确。

$$ 关系识别精确率 = \frac {识别正确的关系个数} {识别出来的关系个数} \times 100% $$

$$ 关系识别召回率 = \frac {识别正确的关系个数} {期望识别出来的关系个数} \times 100% $$

$$ 关系识别错误率 = \frac {识别错误的关系个数} {识别出来的关系个数} \times 100% $$

# 2.1.4 行为识别

解释说明:

行为包括:category、location、modifiers、number、target、time、traffic;

当行为中的category、location、modifiers、traffic均正确时,即认为一个行为正确。

$$ 行为识别精确率 = \frac {识别正确的行为个数} {识别出来的行为个数} \times 100% $$

$$ 行为识别召回率 = \frac {识别正确的行为个数} {期望识别出来的行为个数} \times 100% $$

$$ 行为识别错误率 = \frac {识别错误的行为个数} {识别出来的行为个数} \times 100% $$

# 2.1.5 意图识别

解释说明:

一句话中同时出现Apps、Content、Content_op、data_rel时,需全部正确才判断为一个意图正确:

  • Apps:多组{action、module_name、module_type}均正确即认为意图正确;

  • Content:intentPro、des.intent、behavior中的target所在层级及内容均正确即认为意图正确;

  • Content_op:内容正确即认为正确;

  • data_rel:data_rel正确即认为正确;

$$ 意图识别正确率 = \frac {意图识别正确的问句个数} {测试问句总数} \times 100% $$

# 2.1.6 场景识别正确率

根据业务使用场景,对各场景下的测试语料测试结果分别统计其正确率,可以更清晰的体现NLU能力对上层业务的价值。 $$ 核心业务场景正确率 = \frac {识别正确的核心业务场景问句条数} {核心业务场景问句条数} \times 100% $$

$$ 非核心业务场景正确率 = \frac {识别正确的非核心业务场景问句条数} {非核心业务场景问句条数} \times 100% $$

$$ 多实体关系分析识别正确率 = \frac {多实体关系分析识别正确的问句数} {多实体关系分析测试问句总数} \times 100% $$

# 3 如何实现上述维度的客观、高效度量

在2019年,我们已经进行了NLU智能算法测试的探索,实现了从0到1的突破,积累了一批测试语料,也实现了一定程度上的各指标维度的分析计算。

但随着NLU智能算法服务能力的丰富,其识别结果的数据结构愈发的复杂,需要对已有的测试方法和工具进行优化改进:

  • 降低测试语料准备工作的复杂度,

  • 降低测试语料标注的成本,

  • 提高测试语料标注的效率,

  • 降低测试结果分析、统计和指标计算的代码难度,

我们需要实现从1到N的优化。

# 3.1 我们需要解决的问题

我们主要面临三个大方向的问题:

一、由于我司NLU的应用领域为公安领域,相关语料的获取渠道极为受限,无法从互联网采集,也难以从现有的线上业务系统中获取(对应的业务应用处于刚刚起步阶段,线上用户量很少,从用户使用日志中能获取的信息少)。

二、获取到所需的语料文本后,我们还需要根据我司的NLU体系定义进行(本体、属性、关系、意图、行为、业务场景等维度)语料标注(且我司目前有两套NLU体系定义:IAO和KG)。

三、我们需要对大量的语料测试结果进行各个维度的分析统计,进行各类指标的计算,并且快速的分析其各个指标维度下的失效原因,提供样例用于研发定位和改进NLU算法服务。

# 3.1.1 克服高效简单语料生成和语料标注难题

# 3.1.1.1 语料生成的局限性

语料生成的基本原理为通过语料模板和语料素材的组合生成问句。

举个例子,通过以下语料模板和语料素材:

【模板】查询{中文姓名}和手机号为{手机号码},{长时间段}的住宿记录,{酒店名称}
【素材】中文姓名 ['赵刚', '刘芳', '李白']
【素材】长时间段 ['一九九七年', '2020年1月', '2018年三月之后', '2020年2月份之后']
【素材】手机号码 ['13033918279', '13612349005', '8613368366846', '+8613532340976']
【素材】酒店名称 ['珠江路汉庭酒店', '珠江路如家酒店', '新模范马路香格里拉', '新城科技园桔子水晶']
1
2
3
4
5

我们可以生成以下语料

查询赵刚和手机号为13033918279,一九九七年的住宿记录,珠江路汉庭酒店
查询刘芳和手机号为13612349005,2020年1月的住宿记录,珠江路如家酒店
查询李白和手机号为8613368366846,2018年三月之后的住宿记录,新模范马路香格里拉
查询赵刚和手机号为+8613532340976,2020年2月份之后的住宿记录,新城科技园桔子水晶
1
2
3
4

在2019年的方案中,我们的语料素材存储方式为“文件夹+txt文本”,但语料素材有分类,有标签,有根据项目不同的归一化内容等诸多附加信息,使用“文件夹+txt文本”的存储方式有如下困难需要克服:

  • 不利于表达多层级,多并列的语料素材信息;
  • txt文本缺乏语法校验,手动编辑容易出错,需要通过编写代码对语料素材的导入内容进行预检查、归一化等处理,增加了代码量和维护成本;
  • 各类附件信息体现在txt文件名中,通过#等各类自定义的符号进行分隔,程序代码需要按照阅读切分字符串读取信息;
  • 随着语料素材的调整修正,维护成本逐步提高;
# 3.1.1.2 语料标注的局限性

在2019年的方案中,通过语料模板和语料素材生成的语料,我们的语料标注方案为自定义的一套语法规则,通过对语料的理解,手动编写标注规则信息

image-20201229095348936

语料模板对应的标注信息示例:

image-20201229102717855

从工具维护开发人员的角度来讲,这种标注方式需要有对应的代码将NLU服务的相应体解析为对应的格式进行比对,需要较强的代码能力。

从测试工程师使用的角度来讲,有以下事项需要优化改进,提高测试效率降低测试成本:

  • 需要对每一条语料模板根据工具定义约定的规则(如上图所示),编写其标注信息,学习成本较高;
  • 由于每条模板都需要手动编写,其成本较高,使用这套规则标注效率较低,且在此方案下,无法实现通过自动化预标注+人工审查的方式来提高标注效率;
  • 标注质量有待提高,因为标注信息全靠手写,导致标注出错概率高;
  • 语料内容与其标注信息深度绑定,不可解耦,同一批语料,随着NLU算法的迭代,以及不同的NLU算法项目,其标注信息是有变化的,需要将语料内容与标注信息进行解耦。

# 3.1.2 缺乏深度多维的测试结果分析

在2019年的方案中,我们的语料模板和语料素材生成的语料和语料标注信息示例如下:

image-20201229103901847

可以看到,其语料标注信息是根据语料模板的标注规则回填的,其测试结果也需要将NLU算法服务的返回的json数据解析为对应的节点信息进行比对研判,这就有一定的局限性:

  • 测试代码要递归解析json结构的NLU服务响应体,提取对应的各个NLU识别关键信息,与标注结果进行比对,递归代码的编写维护难度高,不易修改和根据测试需求拓展;

# 3.2 重难点分析

# 3.2.1 重点分析

  • 语料素材库的组织方式要更加合理,提高其可维护性;
  • 语料标注的成本要降低,效率要提升;
  • 对生成的语料数据集进行各维度的分布统计;
  • 降低测试结果分析比对的开发难度,降低开发门槛,提高工具的可拓展性和易维护性;
  • 给出宏观的NLU各个维度指标的结果;
  • 给出每条语料各个指标维度的分析结果;

# 3.2.2 难点分析

# 3.2.2.1 如何将语料生成与语料标注解耦

将语料生成和语料标注解耦,可以对同一批语料进行不同标准体系的标注。就像图像类测试样本的标注,图片是不变的,但标注的维度却可以变化,标注信息与被标注对象可以是多对一的关系。

对每一条语料的标注,是由语料模板、语料素材、语料模板标注信息共同完成的,只需要将该语料的语料模板和语料素材组成一个数据对,与该语料文本进行映射存储,即可方便的完成标注,可以根据标注定义和标注标准的变更实现独立语料标注。

# 3.2.2.2 如何提供自动化的预标注能力

NLU智能算法经过几个版本的迭代,其能力与质量已经得到了一定的提升,具备了相当的使用价值。大胆设想,我们是否可以根据NLU算法服务的输出结果,自动回填各个维度(本体、属性、关系、意图、行为)的标注信息?再辅以人工对标注结果审核查验,进行修正确认,即可快速高效的完成文本标注工作。

这种自动化的标注的效率会随着NLU能力的逐步提升、产品质量的逐步优化,得到很大的提升,人工标注成本逐步降低。

但自动化预标住是把双刃剑,我们必须考虑风险:基于被测NLU服务进行预标注的正确性,将完全依赖于测试工程师对预标注的结果的严谨仔细审核。

# 3.2.2.3 如何实现测试结果比对分析的代码难度降低(平铺代码逻辑替代多层递归)

如何将递归解析NLU服务的响应体json替代掉呢?分析其本质,递归是为了找到对应的各个节点信息,然后基于自定义的规则进行比对分析。

如何将层层嵌套的json做一维的展开?可以使用jsonpath。

使用jsonpath将层层嵌套结构复杂的json结构展开,然后根据kv结构的节点路径和值进行结果比对,即可将递归逻辑给消解掉,使得代码编写调试更容易(本质上没有消灭递归,不过递归交由jsonpath库来做,降低了代码的维护成本)。

# 3.2.3 难点总结

经过上述三个难点的分析,我们发现了一个主要矛盾:标注信息的表达形式。

我们可以通过将标注信息用jsonpath来表达,即可与被测NLU服务返回结果形成直接的映射关系,不再需要记忆各种定义,手写各种标注规则关系了,且jsonpath可以通过json数据结构自动生成。

IAO和KG两个NLU体系并不互通,公司目前没有统一NLU的标准,因此标注信息只需对应其体系维护即可。

从哪些维度评估语音识别的质量,是我们首要解决的问题。

其次,智能化算法测试若是依托纯手工测试、亦或是半自动化测试,将面临着在执行效率、结果可靠性方面的局限性。

# 4 核心改进要点

经过本次优化,NLU的核心测试流程如下,整个测试过程中大部分环节都实现了自动化

image-20201229194344479

# 4.1 基于yaml的语料构造和jsonpath的语料标注

当前NLP类智能算法服务测试的测试语料构造均可使用CorpusFactory项目来提供能力,其标注的语料亦可用于ASR类智能算法的音频测试样本录制。

# 4.1.1 语料素材的组织形式

2019年方案的语料素材组织形式,如以下的示例:

image-20201229154528899

现在我们将“文件夹 + txt文件“形态的语料素材组织形式使用yaml格式文件替代,为什么选择yaml?

  • yaml的可读性好、扩展性好;

  • yaml和脚本语言的交互性好;

  • yaml使用实现语言的数据类型;

  • yaml有一个一致的信息模型;

  • yaml易于实现;

使用yaml来管理组织语料素材的形态如下示例:

image-20201229155109431

我们通过yaml实现了以下语料素材组织管理的能力:

  • 实现了语料素材的灵活组合复用,避免了重复维护;
  • 支撑对语料素材进行优先级的划分;
  • 对同一语料素材支持区分不同NLU体系的标准化值;
# 4.1.1.1 语料素材优先级定义优化

M1~M4,从元素的常见程度、复杂程度、解析难度等方面综合判断

注:目前对于元素优先级的定义,以测试人员的主观判断为主,待真实用户日志数据累计到一定数量时,可结合数据分析结果进行调整;

# 4.1.2 语料模板的编写方式优化

因使用jsonpath来对语料进行标注,所以对语料模板也进行了变更,其变更形式如下:

image-20201229160704305

核心内容即为语料模板,语料标注模板,其中的语料标注模板可以根据根据自动化预标注生成,我们将在接下来的章节阐述。

语料标注模板的编写,其``jsonpath也可以通可视化的方式使用工具从json`数据结构中直接获取

image-20201229165143292

# 4.1.3 支持多种组合策略的全自动化语料生成

根据语料素材级别和模板等级的组合,控制各类语料的生成数量

image-20201229162553971

语料生成的方式即为根据模板进行参数化组合,目前支持4种组合策略,默认策略为uniq

image-20201229191646801

下面将语料的生成过程举个例子阐述下:

有如下语料模板

{查询操作}{手机号11位}的{伴随关系}人员
1

其对应的语料素材数据为【这是核心改进内容】

{
    "查询操作": {
        "md5_id": "5053080618ac09de144bd37b9568f9a6",
        "value": "查询",
        "father_tag": "辅助操作",
        "child_tag": "查询操作",
        "level": "M1",
        "normalization": {},
        "is_compose": 0,
        "compose_object_list": [],
        "yaml_file": "辅助操作.yml"
    },
    "手机号11位": {
        "md5_id": "51a8a32c32aa59a6deeb0d38613e35d9",
        "value": "13301791708",
        "father_tag": "手机号",
        "child_tag": "手机号11位",
        "level": "M1",
        "normalization": {},
        "is_compose": 0,
        "compose_object_list": [],
        "yaml_file": "手机号.yml"
    },
    "伴随关系": {
        "md5_id": "6c745dd7853666f83f0609f7e8f151ba",
        "value": "酒店同房间",
        "father_tag": "伴随关系",
        "child_tag": "酒店同宿",
        "level": "M1",
        "normalization": {
            "IAO": "酒店同房间同宿"
        },
        "is_compose": 0,
        "compose_object_list": [],
        "yaml_file": "伴随关系.yml"
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

生成一条语料信息用于预标注

查询13301791708的酒店同房间人员
1

有了语料模板和语料素材数据结构的绑定,我们即可根据不同的NLU体系标准,实现标注信息的重新生成。

# 4.1.4 基于jsonpath的自动化语料预标注

语料标注模板可以使用CorpusFactory自动生成预标住信息,仅需在配置文件中填写对应的配置即可

image-20201229161303316

# 4.1.4.1 实现逻辑

通过语料模板和语料素材生成一条测试语料,请求NLU被测服务API,获取其API响应体json数据,将其转为jsonpath,根据语料生成的模板和素材,对生成的jsonpath进行变量替换,得到标注模板。

举个例子说明:

语料生成的示例见4.1.3小节,在生成语料的环节,我们得到了以下三个要素数据:

  • 语料模板值
  • 语料素材数据结构
  • 语料文本实例

我们使用生成的语料用户预标注

查询13301791708的酒店同房间人员
1

该语料请求被测NLU服务API后,得到响应json数据

{
    "code": 200,
    "data": [
        {
            "apps": {
                "app_op_seq": []
            },
            "content": {
                "des": {
                    "phone_number": "13301791708"
                },
                "ont": "SIM_Card",
                "rel": [
                    {
                        "des": {},
                        "ont": [
                            "SIM_Card",
                            "Person"
                        ],
                        "rel": [
                            {
                                "behavior": [
                                    {
                                        "category": "伴随分析",
                                        "location": [],
                                        "modifiers": [],
                                        "number": [],
                                        "target": null,
                                        "time": [],
                                        "traffic": []
                                    }
                                ],
                                "des": {
                                    "intent": [
                                        "full"
                                    ]
                                },
                                "intentPro": [
                                    "entity"
                                ],
                                "ont": [
                                    "Person",
                                    "Person"
                                ],
                                "relIdx": [
                                    0,
                                    "14-19"
                                ],
                                "relName": "酒店同房间同宿",
                                "segs": [
                                    "查询13301791708的酒店同房间人员"
                                ]
                            }
                        ],
                        "relIdx": [
                            0,
                            "13-19"
                        ],
                        "relName": "使用人",
                        "segs": [
                            "查询13301791708的酒店同房间人员"
                        ]
                    }
                ],
                "segs": [
                    "查询13301791708的酒店同房间人员"
                ]
            },
            "content_op": "查询"
        }
    ],
    "data_op": {
        "data_rel": [
            ""
        ],
        "data_rel_property": []
    },
    "msg": "",
    "unknown": [
        {
            "keyword": "酒店",
            "ont": "unknown"
        }
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

将此响应json文件转为jsonpath结构(根据预标注信息,有些json结构对测试结果的比对是无意义的,已经根据配置规则忽略掉)

[
    "code=200",
    "$.data.[0].content_op='查询'",
    "$.data.[0].content.ont='SIM_Card'",
    "$.data.[0].content.des.phone_number='13301791708'",
    "$.data.[0].content.rel.[0].ont=['SIM_Card','Person']",
    "$.data.[0].content.rel.[0].relName='使用人'",
    "$.data.[0].content.rel.[0].rel.[0].intentPro=['entity']",
    "$.data.[0].content.rel.[0].rel.[0].ont=['Person','Person']",
    "$.data.[0].content.rel.[0].rel.[0].relName='酒店同房间同宿'",
    "$.data.[0].content.rel.[0].rel.[0].behavior.[0].category='伴随分析'",
    "$.data.[0].content.rel.[0].rel.[0].des.intent=['full']"
]
1
2
3
4
5
6
7
8
9
10
11
12
13

此时需要根据语料素材数据和语料模板对其还原为标注模板

[
    "code=200",
    "$.data.[0].content_op='查询'",
    "$.data.[0].content.ont='SIM_Card'",
    "$.data.[0].content.des.phone_number='{手机号11位}'",
    "$.data.[0].content.rel.[0].ont=['SIM_Card','Person']",
    "$.data.[0].content.rel.[0].relName='使用人'",
    "$.data.[0].content.rel.[0].rel.[0].intentPro=['entity']",
    "$.data.[0].content.rel.[0].rel.[0].ont=['Person','Person']",
    "$.data.[0].content.rel.[0].rel.[0].relName='{伴随关系}'",
    "$.data.[0].content.rel.[0].rel.[0].behavior.[0].category='伴随分析'",
    "$.data.[0].content.rel.[0].rel.[0].des.intent=['full']"
]
1
2
3
4
5
6
7
8
9
10
11
12
13

此时需要测试工程师审核其预标注信息是否正确合理!

通过这种预标注的设计,语料标注工作将是具备”加速度“的,随着NLU能力的提升,标注效率会逐步提高,标注成本逐步降低。

# 4.1.5 带有标注信息的测试语料输出

将生成的海量带有标注信息的语料输出到json line文件,即可用于测试,其输出的标注数据结构示例如下(其中一行语料测试数据):

{
    "sentence": "进入水晶球",
    "template": "{打开操作}{应用名称}",
    "level": "S1",
    "project": "IAO",
    "key_word": [
        "应用名称"
    ],
    "is_core_scene": "是",
    "first_transaction": "操作指令",
    "second_transaction": "应用操作",
    "third_transaction": "打开应用",
    "annotation": [
        "code=200",
        "$.data.[0].apps.app_op_seq.[0].action='打开'",
        "$.data.[0].apps.app_op_seq.[0].module_name='水晶球'",
        "$.data.[0].apps.app_op_seq.[0].module_type='app'"
    ],
    "material_info_dict_with_variable": {
        "打开操作": {
            "md5_id": "e068e68e0344f059aff3ee206334b6fe",
            "value": "进入",
            "father_tag": "辅助操作",
            "child_tag": "打开操作",
            "level": "M1",
            "normalization": {},
            "is_compose": 0,
            "compose_object_list": [],
            "yaml_file": "辅助操作.yml"
        },
        "应用名称": {
            "md5_id": "80e6fe6bac09d577b3d36b8871e3c4bf",
            "value": "水晶球",
            "father_tag": "应用名称",
            "child_tag": "应用名称",
            "level": "M1",
            "normalization": {
                "IAO": "水晶球"
            },
            "is_compose": 0,
            "compose_object_list": [],
            "yaml_file": "应用名称.yml"
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

输出的json line文件示例:

image-20201229170841184

此jl文件即可作为NLU测试工具的输入文件,且可以将每一条测试语料的测试结果补充到json line文件中,这样即可对每一条测试数据进行完整的声明周期跟踪和定位,便于结果分析,语料构造策略调整,工具开发debug等。

# 4.1.6 自动化语料分布统计

为了科学客观的对NLU能力进行评估,需要明确其语料构成分布情况,统计效果如下:

# 4.1.6.1 素材库概况统计示例

image-20201229200849841

# 4.1.6.2 模板生成句子统计示例

image-20201229174403087

# 4.1.6.3 业务场景维度句子统计示例

image-20201229200826979

# 4.1.6.4 IAO本体&本体属性覆盖情况统计示例

image-20201229200715956

# 4.1.6.5 IAO行为属性覆盖情况统计示例

image-20201229174637105

# 4.1.6.6 IAO操作属性覆盖情况统计示例

image-20201229174707348

# 4.1.6.7 IAO行为(category)覆盖情况统计示例

image-20201229200644895

# 4.1.6.8 IAO关系(relname)覆盖情况统计示例

image-20201229200634506

# 4.2 算法效果测试改进

# 4.2.1 比对规则的设计开发

  • 通过面向对象的设计方法,定义各个指标维度的DataClass
  • 设计jsonpath通用比对方法,对各个维度的比对规则进行封装定制,使用不同的函数将各评估所关注个NLU输出结果与标注结果的jsonpath进行比对,替代了晦涩难懂的递归解析比对,便于定位分析debug。

此处主要是代码的设计实现,篇幅较大,细节较多,就不展开阐述了,有兴趣可以查阅项目代码:IAO-TOOLKITS-IntellDialog (opens new window)

image-20201229173527378

# 4.2.2 指标统计输出

# 4.2.2.1 定义各个指标期望阈值用于自动研判

通过配置文件定义各个指标阈值,自动研判指标是否通过

indicator_expectation:
  # 冒烟用例正确率
  smoke_test_correct_rate: 0.9
  # 核心业务场景正确率
  core_scene_correct_rate: 0.8
  # 非核心业务场景正确率
  not_core_scene_correct_rate: 0.7
  # 多实体关系分析识别正确率
  ……
1
2
3
4
5
6
7
8
9
# 4.2.2.2 宏观指标统计结果示例

宏观指标即为NLU各个维度指标统计结果,并展示其各个分子分母的个数,便于分析影响指标的具体因素。

image-20201231110324440

# 4.2.2.3 各语料详情分析结果示例

详情分析结果,可以根据各个指标维度的测试结果,进行筛选,分析其失败原因,并且可以看到该语料各个维度的分类标签信息,便于进行深入分析。

image-20201229175348476

# 4.2.2.4 各三级业务场景统计示例

各业务场景是与上层业务沟通确认的,基于此维度进行指标分析,可以有效评估其在业务系统的应用情况,对业务侧提供有效的研判情报。

image-20201229200527126

# 4.2.2.5 本体属性识别分析详情统计示例

image-20201229200547013

# 4.2.2.6 关系识别分析详情统计示例

image-20201229200558046

# 4.2.2.7 行为识别分析详情统计示例

image-20201229180122128

# 5 优化效果评价

本次优化设计较以往的不同之处

  1. 基于实际结果:使用JSONPATH定义标注数据,代替之前的递归解析JSON响应体,降低结果比对部分的代码复杂度和维护成本;

  2. 基于预期结果:使用JSONPATH辅助以路径提取工具,对JSONPATH进行预标注,人工审核修正,提高标注效率和正确率,降低数据标注成本;

  3. 基于测试数据:将语料库(测试数据)的管理进行定义和分类优化,结合新的模板定义编写方式,降低编写的复杂度;

  4. 基于语料库(测试数据)管理:将语料生成和语料标注解耦开来,建立语料库基线,标注数据随被测项目进行更新迭代,提高NLP语义理解测试样本的可维护性和持续性;

整体上,代码可维护性提高30%,测试数据构造成本降低80%

IAO-TOOLKITS-IntellDialog-V3.2.0.0项目,测试准备了243种约28.7万的测试素材和900条不同优先级的测试语料模板,可在30分钟完成7000+的测试问句生成以及预期标注,1小时内完成算法指标的计算和统计分析(主要耗时为IAO被测服务性能较低,TPS仅为2)。

# 6 附录

# 6.1 CorpusFactory核心步骤使用流程图

CorpusFactory核心步骤和使用流程图

# 6.2 CorpusFactory设计流程图

CorpusFactory设计图

# 7 致谢

感谢以下同学,在整体框架设计、优化、应用过程中的努力付出,以及提出的宝贵意见,以下排名不分先后:

郭群、姜越、陈岑

#NLP#NLU#智能算法测试
上次更新: 7/26/2026, 4:44:44 PM
AITLibra-智能算法效果测试提效降本的实践
智能算法测试平台基础设施

← AITLibra-智能算法效果测试提效降本的实践 智能算法测试平台基础设施→

最近更新
01
测试覆盖度量全景图
11-30
02
Prism测试覆盖度量
11-30
03
AITDBClient使用文档
11-15
更多文章>
Theme by Vdoing | Copyright © 2021-2026 toddlerya | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式