• 【AI测试】借助自动化框架实现-短文本相似度模型测试(基于LCQMC语料)


    ****************************************************************************

    本文主要介绍借助自动化框架实现-短文本相似度模型测试

      1.测试需求分析

      2.测试环境准备

      3.测试数据准备

      4.测试分析与执行

      5.测试问题总结

    ****************************************************************************

    一、测试需求

    1)原始需求:测试短文本相似度接口能力是否符合指定的模型效果

    2)理解需求:验证接口的功能、模型评估、性能是否符合需求文档

    3)需求思考:短文本相似度是判定2个文本在语义上是否相似,目前使用场景包含信息检索图片、视频、文本等、新闻推荐、智能客服等,本次测试的应用场景是? 研发回答:没有指定场景(这是一个坑!!!)

    二、测试环境准备

    本次测试接口能力均已封装为镜像文件,所以直接拉取镜像启动即可!

    1) 启动能力镜像:

    CPU版本:

    docker run -d -p 5000:5000 -v /dep_pic/wwq/data/TextSimilarity:/home/TextSimilarity/Data text_similarity_cpu:v1

    GPU版本:

    docker run -d --gpus "device=1"(显卡号) -p 5000:5000 -v /dep_pic/wwq/data/TextSimilarity:/home/TextSimilarity/Data text_similarity_gpu:v1

    2) 代码运行日志在映射目录下Log文件夹中startup.log文件中,查看日志命令为cat startup.log,如下则服务已成功启动:

    三、测试数据准备

    1)数据分析:需求分析阶段了解到模型并没有指定使用场景,且模型训练依赖主要CMNLI语料库,通过分析CMNLI语料库场景比较单一,经测试建议增加LCQMC语料库,丰富模型使用场景,使模型效果更理想!

    2)语料库数据展示

    四、测试分析与执行

    1)测试方法分析:功能测试利用Postman工具(不讲),模型评估测试利用公司自动化接口框架实现,性能测试利用JMeter工具(不讲)

    2)模型评估测试执行

    A、获取评估指标预期值:模型评估包含那些指标,通常会在需求文档里面体现出,代表算法工程师自测的结果,如

    B、获取评估指标数据量级与数据分布情况:算法工程师通常有2个数据集,训练集与测试集,如本次测试算法工程师训练集在十几万数据,相似与不相似数据分布比例是1:2,所以我的测试数据设计为:相似1000条,不相似2000条

    C、执行模型评估测试,本次测试利用公司自动化接口框架,具体框架的架构、涉及技术不是本次重点,本次重点说一下模型评估自动化的实现方法,以往模型评估过程都需要测试人员整合测试结果,然后手工统计出指标值,结果准确性无法保证耗时也比较久。话不多说,直接上代码:

    AItool工具类:利用sklearn模块evaluate函数,直接输出模型指标值,如准确率、精确率、召回率、F1 score

    sklearn详细用法参考博客:https://blog.csdn.net/hfutdog/article/details/88085878   

    def evaluate(y_true, y_pred):
        Precision_Statistics = {
            'precsion': {
                'micro': precision_score(y_true, y_pred, average="micro"),
                'macro': precision_score(y_true, y_pred, average="macro"),
                'weighted': precision_score(y_true, y_pred, average="weighted")},
            'recall': {
                'micro': recall_score(y_true, y_pred, average="micro"),
                'macro': recall_score(y_true, y_pred, average="macro"),
                'weighted': recall_score(y_true, y_pred, average="weighted")
            },
            'f1': {
                'micro': f1_score(y_true, y_pred, average="micro"),
                'macro': f1_score(y_true, y_pred, average="macro"),
                'weighted': f1_score(y_true, y_pred, average="weighted"),
            }
        }
        return Precision_Statistics
    
    def evaluate1(y_true, y_pred):
        Precision_Statistics = {
            'precsion': {
                'precsion': precision_score(y_true, y_pred)
            },
            'recall': {
                'recall': recall_score(y_true, y_pred)
            },
            'f1': {
                'f1': f1_score(y_true, y_pred)
            }
        }
        return Precision_Statistics
    
    def appendlist1(label):
        label_list1.append(label)
    
    
    def appendlist2(label):
        label_list2.append(label)

    testCase用例实现:收集预期结果与接口返回结果,追加到列表: AItool.appendlist1(label)、 AItool.appendlist2(isDataYes)

    # 请求目标接口
            (res,headers) = shortTextSimilartiy().getAuthoritys(jsons=data, header={"Content-Type": "application/json"})
            logger.info(headers)
            isSuccess = headers['X-EBAPI-CODE']
            isSuccess1 = headers['X-EBAPI-DESC']
            result1 = Checkpoint().checkIfTextExist(isSuccess, "0000")
            self.assertEqual(result1, True)  # 根据result字段判断接口是否请求成功 如果请求成功继续往下校验是否为预期的相似度
            result2 = Checkpoint().checkIfTextExist(isSuccess1, "success")
            self.assertEqual(result2, True)  # 根据result字段判断接口是否请求成功 如果请求成功继续往下校验是否为预期的相似度
            try:
                isDataYes = res["content"][0]["data"]
            except Exception:
                logger.info('获取被测接口的响应label失败')
                raise KeyError
            result3 = Checkpoint().checkIfTextExist(isDataYes, label)
            if label == 'yes':
                label = 1
            else:
                label = 0
            if isDataYes == 'yes':
                isDataYes = 1
            else:
                isDataYes = 0
         # 追加预期数据与返回数据 AItool.appendlist1(label) AItool.appendlist2(isDataYes) self.assertEqual(result3, True)
    # 根据返回是否相似 与预期值对比 if label == 'yes': # 如果label等于yes 则判断返回值中的相似度是否大于等于0.5(0.5这个阈值可调) result2 = res["content"][1]["data"] >= 0.5 self.assertEqual(result2, True) elif label == 'no': # 如果label等于no 则判断返回值中的相似度是否小于0.5(0.5这个阈值可调) result2 = res["content"][1]["data"] < 0.5 self.assertEqual(result2, True)

    report输出报告:报告中调用工具类evaluate1函数,输出模型评估结果

     1     def getReportAttributes(self, result):
     2         """
     3         Return report attributes as a list of (name, value).
     4         Override this to add custom attributes.
     5         """
     6         startTime = str(self.startTime)[:19]
     7         duration = str(self.stopTime - self.startTime)
     8         status = []
     9         #Accuracy = AItool.evaluate(AItool.label_list1, AItool.label_list2)
    10         # 输出模型评估指标值
    11         Accuracy = AItool.evaluate1(AItool.label_list1,AItool.label_list2)
    12         status.append('总计: %s' % (result.success_count + result.failure_count + result.error_count))
    13         if result.success_count: status.append('通过: %s' % result.success_count)
    14         if result.failure_count: status.append('失败: %s' % result.failure_count)
    15         if result.error_count:   status.append('错误: %s' % result.error_count)
    16         if status:
    17             status = ''.join(status)
    18             # 合入Github:boafantasy代码
    19             if (result.success_count + result.failure_count + result.error_count) > 0:
    20                 self.passrate = str("%.2f%%" % (float(result.success_count) / float(
    21                     result.success_count + result.failure_count + result.error_count) * 100))
    22             else:
    23                 self.passrate = "0.00 %"
    24         else:
    25             status = 'none'
    26         return [
    27             (u'测试人员', self.tester),
    28             (u'开始时间', startTime),
    29             (u'合计耗时', duration),
    30             (u'测试结果', status + ",通过率: " + self.passrate),
    31             (u'统计数据', ''),
    32             # (u'precsion', 'micro=' + str(Accuracy['precsion']['micro']) + ',  macro = ' + str(
    33             #     Accuracy['precsion']['micro']) + '  ,   weighted = ' + str(
    34             #     Accuracy['precsion']['weighted'])),
    35             # (u'recall', 'micro=' + str(Accuracy['recall']['micro']) + ',  macro = ' + str(
    36             #     Accuracy['recall']['micro']) + '  ,   weighted = ' + str(
    37             #     Accuracy['recall']['weighted'])),
    38             # (u'f1', 'micro=' + str(Accuracy['f1']['micro']) + ',  macro = ' + str(
    39             #     Accuracy['f1']['micro']) + '  ,   weighted = ' + str(
    40             #     Accuracy['f1']['weighted']))
    41             (u'precsion','precsion='+str(Accuracy['precsion']['precsion'])),
    42             (u'recall','recall='+str(Accuracy['recall']['recall'])),
    43             (u'f1','f1='+str(Accuracy['f1']['f1']))
    44 
    45         ]

    report结果展示:

    测试报告中结果展示:

    五、测试问题总结

    1)LCQMC语料库获取,模型测试数据获取都是靠运气,一般可通过官方网站进行申请(时间比较久,还需要额外审核),自己百度找,需要这份数据集的小伙伴请评论留言!

    2)本次模型评估测试采用自动化框架,如果有一定python技术的同学,我建议采用这种方式,首先能够解放双手,其次可以缩短测试时间,尽管前期需要投入开发时间,但是一劳永逸,想探讨接口自动化框架的小伙伴请评论留言!

  • 相关阅读:
    Android项目打包
    Video Demystified
    C指针与python bytes 互转
    运筹学笔记 3 线性代数基础
    三角网格上的寻路算法Part.2—A*算法
    三角网格上的寻路算法Part.1—Dijkstra算法
    从二维点集重建平面形状-浅议凹包算法
    二值图像膨胀腐蚀算法的几种实现方式
    浅议像素化与体素化Part.1——平面图形像素化
    寻找图像中的局部极大点
  • 原文地址:https://www.cnblogs.com/xjx767361314/p/13959536.html
Copyright © 2020-2023  润新知