随着数字化转型与人工智能发展,AI应用软件层出不穷,人们虽然理解人工智能趋势,但是,企业往往很难接受这样AI应用软件,其中质疑点主要有:
- 预测或识别的准确性
- 模型相关性
- 鲁棒性
- 安全性
- 数据隐私
- 性能效率
- 公平性
- 可解释性
接下来,本文将从机器学习模型开发过程、AI应用软件开发过程,结合测试过程,谈谈如何进行机器学习AI模型测试与模型评估方法。
注:为了便于讨论,本文限定在监督学习算法应用范围。
AI应用软件开发过程(不含直接调用算法API接口软件)与传统信息化应用软件、专业软件对比,有个显著的差别,就是算法模型学习过程,通过大数据训练算法模型,算法模型通经过测试评估后,才能与应用软件有机集成上线应用。
另外,AI应用软件所使用的数据,一般需要经过数据预处理,方为算法模型所使用。
对于开发过程中的算法模型学习和数据预处理环节,测试过程则在传统的功能、系统测试基础上,额外增加“测试评估算法模型“”。
随着人工智能的发展与应用,传统的功能测试策略对于算法测试而言,心有余而力不足,难以满足对人工智能 (AI) 的质量保障。
以传统应用软件为例,测试过程包括测试计划、编写测试用例、搭建测试环境、执行测试、编写测试报告、召开里程碑会议等主要节点。 其中,搭建测试环境中,包括准备测试数据,很多时候,准备测试数据是个非常专业、繁重的工作,常用准备方法有:
- 基于GUI操作生成测试数据;
- 通过API调用生成测试数据;
- 通过数据库操作生成测试数据;
- 综合运用API和数据库的方式生成测试数据。
从测试数据创建的时机来看,主要分为On-the-fly(实时创建)和Out-of-box(事先创建测试数据)两类方法。这两类方法都有各自的优缺点,以及适用的最佳场景。
以测试人员视角,AI应用测试过程与传统软件测试过程对比,增加了算法模型测试任务内容,如何进行算法模型测试,AI应用软件测试。 结合探索、实践的过程,AI算法模型测试大致包括如下几个策略。
- 算法测试集数据准备
- 算法模型组件测试
- 算法功能测试
- 算法性能测试
- 算法效果测试(模型评估指标)
- 算法指标结果分析
- 算法测试报告
3.1.1. 测试集准备方法
3.1.1.1. 留出法划分数据集(hold-out)
留出法是比较常用的方法,是指直接将数据集D划分为两个互斥的集合,其中一个集合作为训练集S,另外一个作为测试集T,即D=S∪T,S∩T=空集。在S上训练出模型后,用T来评估其测试误差,作为对泛化误差的估计。
另外,对于留出法,除了划分为测试集,验证集还有两种划分方式。
- 训练数据,验证数据和测试数据按照6:2:2的方式划分数据集
- 当数据量非常大时,可以使用 98 : 1 : 1 的比例划分训练数据,验证数据和测试数据
需要注意的问题:
- 训练/测试集的划分要尽可能的保持数据分布的一致性,避免因数据划分过程引入额外的偏差而对最终结果产生影响。
- 在给定训练/测试集的样本比例后,仍然存在多种划分方式对初始数据集D进行划分,可能会对模型评估的结果产生影响。因此,单次使用留出法得到的结果往往不够稳定可靠,在使用留出法时,一般采用若干次随机划分、重复进行实验评估后取得平均值作为留出法的评估结果
3.1.1.2. 交叉验证法
k 折交叉验证通过对 k 个不同分组训练的结果进行平均来减少方差,因此模型的性能对数据的划分就不那么敏感。
- 第一步,不重复抽样将原始数据随机分为 k 份。
- 第二步,每一次挑选其中 1 份作为测试集,剩余 k-1 份作为训练集用于模型训练。
- 第三步,重复第二步 k 次,这样每个子集都有一次机会作为测试集,其余机会作为训练集。在每个训练集上训练后得到一个模型,用这个模型在相应的测试集上测试,计算并保存模型的评估指标,
- 第四步,计算 k 组测试结果的平均值作为模型精度的估计,并作为当前 k 折交叉验证下模型的性能指标。
3.1.1.3. 自助法
在统计学中,自助法(Bootstrap Method,Bootstrapping或自助抽样法)是一种从给定训练集中有放回的均匀抽样,也就是说,每当选中一个样本,它等可能地被再次选中并被再次添加到训练集中。
数据集D中存在m个样本,运用自助抽样法,对数据集进行有放回的抽样m次后,其中始终不被采到的概率为,取极限得到:
即通过自主采样,初始训练集D中约有36.8%的样本未出现在采样数据集D’中。于是可将D’用作训练集,D/D’用作测试集。
自助法在数据集小,难以划分训练/测试集时有用。
3.1.2. 测试集规范要求
测试集的准备对于整体算法测试而言非常重要,一般测试集准备过程中需考虑以下几点:
- 测试集的覆盖度
- 测试集的独立性
- 测试集的准确性
3.1.2.1. 测试集的覆盖度
如果,测试集准备只是随机的选取测试数据,很容易造成测试结果的失真,降低算法模型评估结果的可靠性。
好比传统软件功能测试,根据功能测试设计,构造对应的数据进行测试覆盖。算法模型测试亦然,以人脸检测算法而言,除了考虑选取正样本、负样本外,还需要考虑正样本中人脸特征的覆盖,如人脸占比、模糊度、光照、姿态(角度)、完整性(遮挡)等特征。
以此类比,构建客户发展预测的测试集(包括训练集),最后按客群分布,再随机抽取训练集,比如按客户会员时长、消费能力、交易间隔、油品偏好、价格敏感、储值习惯等特征。
另外,除了数据特征的覆盖,也需要考虑数据来源的覆盖,结合实际应用环境、场景的数据进行数据模拟、准备。
此外,关于测试数据的数量,一般来讲测试数据量越多越能客观的反映算法的真实效果,但出于测试成本的考虑,不能穷其尽,例如选取了2万左右的图片进行测试、选取10万会员客户测试。
3.1.2.2. 测试集的独立性
测试集的独立性主要考虑测试数据集相互干扰导致测试结果的失真风险。
3.1.2.3. 测试集的准确性
数据集的准确性一般指的是数据标注的准确性,比如Jack的照片不应标注为Tom,照片模糊的特征不应标注为清晰。如果数据标注错误,那么直接影响了算法模型指标计算的结果。
构建机器学习模型的基本过程以及过程中涉及的主要组件如下图所示。 机器学习模型的开发过程需要与数据、学习程序、学习框架等多个组件进行交互,而每个组件都可能包含错误。因此,在进行机器学习测试时,开发人员可能需要尝试查找每个组件中的bug,包括数据、学习程序和框架。特别是,错误传播是一个更严重的问题,机器学习开发,因为组件之间的联系比传统软件更紧密,这表明测试每个机器学习组件的重要性。
3.2.1. 数据
机器学习系统的行为在很大程度上取决于数据。数据中的错误会影响生成的模型的质量,并且可能会被放大,在一段时间内产生更严重的问题。数据中的错误检测检查诸如数据是否足够用于训练或测试模型(也称为数据的完整性)、数据是否代表未来数据、数据是否包含大量噪声(例如有偏见的标签)、训练数据和测试数据之间是否存在偏差、以及是否存在可能影响模型性能的数据中毒或敌意信息等问题。
3.2.1. 框架
框架测试检查机器学习的框架是否有可能导致最终系统出现问题的错误。
3.2.3. 学习程序
学习程序可以分为两个部分:由开发人员设计或从框架中选择的算法,以及开发人员为实现、部署或配置算法而编写的实际代码。学习程序中可能会出现错误,这可能是因为算法设计、选择或配置不正确,或者是因为开发人员在实现所设计的算法时犯了 错误。
在机器学习、深度学习、数据挖掘领域,工业界往往会根据实际的业务场景拟定相应的业务指标。对于算法模型一般分为分类问题、回归问题、优化目标等评估指标。
3.3.1. 评估指标分类
3.3.1.1. 分类问题评估指标
其实,分类问题评估指标是适合多分类情况的,只是举例往往是二分类的,本文虽然介绍指标时是以二分类开始,但是公式可以拓展到多分类。
- 准确率 – Accuracy
- 精确率(差准率)- Precision
- 召回率(查全率)- Recall
- F1分数
- ROC曲线
- AUC曲线
3.3.1.2. 回归问题评估指标:
- MAE
- MSE
3.3.1.3. 优化目标指标:
- 交叉熵 — cross-entropy
- rmse
3.3.2. 评估指标详解
3.3.2.1. 混淆矩阵
混淆矩阵(confusion matrix)也称误差矩阵,是表示精度评价的一种标准格式,用行列的矩阵形式来表示。在人工智能中,特别用于监督学习衡量的是一个分类器分类的准确程度,比较分类结果和实际测得值,可以把分类结果的精度显示在一个混淆矩阵里面。
混淆矩阵适用于多分类器的问题,本文为了让读者理解更加容易,以手写数字“5”分类识别二元分类的混淆矩阵为例说明。
- 真阳性(True Positive,TP):样本的真实类别是正例,并且模型预测的结果也是正例
- 真阴性(True Negative,TN):样本的真实类别是负例,并且模型将其预测成为负例
- 假阳性(False Positive,FP):样本的真实类别是负例,但是模型将其预测成为正例
- 假阴性(False Negative,FN):样本的真实类别是正例,但是模型将其预测成为负例
3.3.2.2. 准确率P、召回率R、F1 值
如果我们想知道类别之间相互误分的情况,查看是否有特定的类别相互混淆,就可以用混淆矩阵画出分类的详细预测结果。对于包含多个类别的任务,可以很清晰的反映各类别之间的错分概率。
- 准确率(Accuracy):。通俗地讲,就是预测正确的结果占总样本的百分比。
虽然准确率可以判断总的正确率,但是在样本不平衡 的情况下,并不能作为很好的指标来衡量结果。举个简单的例子,比如在一个总样本中,正样本占 90%,负样本占 10%,样本是严重不平衡的。对于这种情况,我们只需要将全部样本预测为正样本即可得到 90% 的高准确率,但实际上我们并没有很用心的分类,只是随便无脑一分而已。这就说明了:由于样本不平衡的问题,导致了得到的高准确率结果含有很大的水分。即如果样本不平衡,准确率就会失效。
- 精准率(Precision):。通俗地讲,就是预测正确的正例数据占预测为正例数据的比例。
- 召回率(Recall):。通俗地讲,就是预测为正例的数据占实际为正例数据的比例
- F1值(F1 score):。又称平衡F分数(balanced F Score),它被定义为精确率和召回率的调和平均数。 F1的值同时受到P、R的影响,单纯地追求P、R的提升并没有太大作用。在实际业务工程中,结合正负样本比,的确是一件非常有挑战的事。
3.3.2.3. ROC与AUC曲线
ROC曲线是Receiver Operating Characteristic Curve的简称,中文名为“受试者工作特征曲线”。
ROC曲线的横坐标为假阳性率(False Positive Rate,FPR);纵坐标为真阳性率(True Positive Rate,TPR)。FPR和TPR的计算方法分别为:
- 真阳性率:
- 假阳性率:
ROC是由点(TPR,FPR)组成的曲线,AUC就是ROC的面积。
一般来说,AUC越大越好;如果TPR越高,同时FPR越低(即ROC曲线越陡),那么模型的性能就越好;ROC是光滑的,那么基本可以判断没有太大的overfitting。
为什么使用 ROC 曲线 既然已经这么多评价标准,为什么还要使用 ROC 和 AUC 呢?因为 ROC 曲线有个很好的特性:当测试集中的正负样本的分布变化的时候,ROC 曲线能够保持不变。在实际的数据集中经常会出现类不平衡(class imbalance)现象,即负样本比正样本多很多(或者相反),而且测试数据中的正负样本的分布也可能随着时间变化。
机器学习模型不好做单元测试,核心问题就是因为机器学习缺乏稳定性,导致其中间过程和最终结果不平稳。原因如下:
- 计算的稳定性(Computational Stability)
- 算法稳定性(Algorithmic Stability)与扰动(Perturbation)
- 数据的稳定性(Data Stability)
- 其中一个重要的原因是神经网络总体上是一个黑盒,而且现代的神经网络模型,算力负担很重。
什么情况下可以做单元测试?
机器学习框架最好要有单元测试的,如Tensorflow、Theano之类的深度学习框架。不过从这一类框架的单元测试也可以看到其测试逻辑:模块最小化。
例如使用TensorFlowTestCase进行单元测试。
-
数据隐私性是指模型在面对恶意用户或攻击者企图窃取用户隐私数据或模型参数信息而采取攻击行为时的处理能力。
-
鲁棒性(robustness)也被称为健壮性或者稳健性,它指的是模型对异常情形产生的异常输入的处理能力。缺失值、错误值、数据类型或格式不统一,对抗信息等都可能影响模型的性能,这些都属于模型鲁棒性研究的内容。近年来,学术界对模型的对抗鲁棒性研究较多,它是安全关键领域必须要考虑和解决的问题。
-
安全性有两个英文单词对应:Security和Safety。security强调模型对来自外部或内部“蓄意或恶意”攻击时的处理能力。对抗攻击和数据投毒攻击都属于security的范畴。Safety虽然也有安全性的含义,但它强调模型在面对客观存在的潜在危险时的处理能力。
- 请注意,我们将“测试输入”和“测试数据”的定义分开。特别地,我们使用“测试输入”来指可用于进行机器学习测试的任何形式的输入;而“测试数据”专门指用于验证ML模型行为的数据。因此,ML测试中的测试输入可能是,但是不限于测试数据。当测试学习程序时,测试用例可以是来自测试数据的单个测试实例或玩具训练集;当测试数据时,测试输入可以是学习程序。
- 测试充分性标准用于对已测试的目标软件的程度提供定量度量。
机器学习AI应用软件系统作为软件系统,其测试大多方面与软件工程中已经广泛研究的众所周知的解决方案是相同的,但机器学习系统的统计性质及其自主决策的能力为软件测试提出了额外的、具有挑战性的研究问题:
-
机器学习系统本质上遵循数据驱动的编程范例,其中决策逻辑是通过机器学习算法体系结构下的训练数据的训练过程获得的。该模型的行为可能会随着时间的推移而演变,以响应新数据的频繁提供。
-
AI应用测试工作是个非常有挑战性的任务,解决机器学习系统很难测试的问题,要以数据驱动思维进行测试数据准备,并选择合适的模型评估方法。
由于编者水平有限,欢迎讨论研究。
参考: