心法利器[115] | bad case治疗术:实践篇

学术   科技   2024-07-28 21:00   广东  

心法利器


本栏目主要和大家一起讨论近期自己学习的心得和体会。具体介绍:仓颉专项:飞机大炮我都会,利器心法我还有

2023年新的文章合集已经发布,获取方式看这里:又添十万字-CS的陋室2023年文章合集来袭,更有历史文章合集,欢迎下载。


往期回顾

之前自己写了一个系列——bad case治疗术,用于详细和大家解释,为什么以及如何做bad case分析,从而逐步更有针对性地优化自己的算法方案,历史传送门在这里:

今天想在这基础上补充一篇,就是实践,借助一个案例,让大家理解整个bad case的修复流程是什么样的,从而让大家更加理解这个系列的内容。

现在开始,我会按照我之前聊的流程,逐步和大家讲这个流程。

案例背景

这次的案例,我选择的是上周讲过的这篇里的方案和数据:心法利器[114] | 通用大模型文本分类实践(含代码)

首先是数据,直接上连接:https://github.com/aceimnorstuvwxz/toutiao-text-classfication-dataset,这个链接里的样本是各个场景下的文章标题,类目则是文章标题所属的领域,里面大概有15个左右,数据集也不小,有38万,此处就是取了1万出来,测试集1000,训练集9000。

方案上,就用的上期提到的大模型文本分类方案,给定一个待分类的文本query,第一步是从训练集中查出与query相似的样本,取TOP N,第二步是交给大模型做最终决策,看属于这个query属于哪个类,思路上还是比较好理解的,具体的方案细节可以参考我的这篇文章(心法利器[114] | 通用大模型文本分类实践(含代码))以及对应的开源项目:https://github.com/ZBayes/poc_project/tree/main/llm_classification。

识别现状

按照bad case治疗术的流程,第一步是识别现状,先回忆一下,我定义的现状是什么样的:

现在有一个基本baseline,baseline自然就有对应的评测集基线方案的效果,这个所谓的效果,就是现状,好or不好,是否需要持续优化,哪个方面需要持续优化,这就是所谓的现状,只有明确了宏观的现状,才能知道我们下一步的动作。

这里有3个要素,评测集、指标、结论。

  • 评测集是评估效果的原料,数量和质量上都有很高的要求,只有评测集正确了,那评估出来的指标才是可靠的。
  • 指标,指标能体现有两个点,一个是好坏,一个是暴露问题,前者很好理解,后者是可以通过构造特地给的指标来观测是什么位置出了问题,这点会在后面展现。
  • 结论,结合指标,给出具体效果好坏以及问题点的初步结论。

然后我们一步步来整。

第一步就是评测集。因为这只是个实验,所以没有生产数据集,只能简单从数据集中随机抽1000条数据作为测试集(请注意,如果是现实应用中,还是应该尽可能拿到和实际应用场景分布一致的测试集,如某个问题在实际应用中出现的概率是1%则测试集也尽量要在1%左右),随机从给定数据里抽是实验是里一个常见的模拟方法了。

第二步是指标,作为多分类问题,常见的指标就是精确率、召回率和F1,详细如下:

              precision    recall  f1-score   support

   科技-科技       0.64      0.90      0.75        96
   国际-国际       0.73      0.71      0.72        79
   娱乐-娱乐       0.69      0.81      0.74        91
   教育-教育       0.71      0.89      0.79        90
   民生-故事       0.54      0.47      0.50        15
   证券-股票       0.00      0.00      0.00         1
   军事-军事       0.80      0.60      0.69        58
   旅游-旅游       0.64      0.84      0.73        58
   文化-文化       0.83      0.74      0.79        74
   体育-体育       0.87      0.84      0.86        89
   房产-房产       0.87      0.73      0.80        45
   财经-财经       0.92      0.37      0.53        89
   农业-三农       0.84      0.73      0.78        49
   电竞-游戏       0.89      0.77      0.83        77
   汽车-汽车       0.92      0.87      0.89        89

   micro avg       0.76      0.76      0.76      1000
   macro avg       0.73      0.69      0.69      1000
weighted avg       0.79      0.76      0.76      1000

可以看到,显然整体效果0.76(weighted avg f1-score)不尽人意,但并能不止于此,进一步分析,要看分类目的F1,可以看到,有一些support比较多的高频类目,效果也并不是很好,比较凸显的“财经-财经”、“军事-军事”都不高,当然低频的类似“证券-股票”、“民生-故事”效果也不是很好,这个跟测试集内的数据量有些关系了。

为了进一步分析,还有一个很好的工具可以使用,那就是混淆矩阵,可以快速定位到一些容易混淆的类目。

from sklearn.metrics import classification_report, confusion_matrix
# 。。。
logger.info("\n{}".format(confusion_matrix(test_list, pred_list, labels=labels)))

执行结果,具体的顺序和上面的classification_report类目顺序是一样:

[[86  1  0  1  0  0  0  2  2  1  0  1  0  1  1]
 [ 1 56  6  4  2  0  4  2  1  1  0  0  1  0  1]
 [ 0  0 74  2  2  0  0  3  3  1  0  0  0  2  1]
 [ 2  0  4 80  0  0  0  3  0  0  0  0  0  1  0]
 [ 2  0  1  0  7  0  0  0  1  2  0  0  1  1  0]
 [ 0  0  0  0  0  0  0  0  0  0  0  1  0  0  0]
 [ 2 12  2  5  0  0 35  0  0  1  0  0  0  0  0]
 [ 1  1  1  1  0  0  0 49  3  0  0  0  1  0  1]
 [ 2  2  4  5  0  0  1  4 55  0  0  0  0  0  1]
 [ 0  0  3  2  0  0  2  0  0 75  0  1  0  2  2]
 [ 5  2  2  1  0  0  0  2  0  0 33  0  0  0  0]
 [23  2  2  5  2 10  0  2  0  2  3 33  4  0  0]
 [ 2  0  2  0  0  0  0  6  1  0  2  0 36  0  0]
 [ 4  0  5  2  0  0  2  2  0  3  0  0  0 59  0]
 [ 4  1  2  4  0  0  0  1  0  0  0  0  0  0 77]]

倒数第四行第四列是33,对应的就是“财经-财经”,这里横向看,第1列和第6列的数比较大,分别是23和10,说明很多“财经-财经”类的内容被这两个类召走,分别是“科技-科技”、“证券-股票”,说明很大程度和这两个类目之间存在混淆,需要重点优化。

相比总体的指标,细分的指标能帮助我们进一步探知关键问题,这就是我前面所说的“暴露问题”,有了细节指标的信息,我们能对问题点有相对清楚的认识,在后续进一步分析bad case的时候,我们充分参考这些信息,能较快找到问题的根源。

分析bad case

然后,我们就可以开始进行bad case的分析了。这次我们直接拿上面的数据来分析,建议是分成4列,分别是case、实际值、预测值以及是否正确,如下面的样例所示:

caserealpredis_right
5月9日15:30 G3017金武段金昌站与水源站之间进行养护维修施工,请注意!汽车-汽车汽车-汽车TRUE
瑜伽服务平台Wake宣布完成数千万元A+轮融资科技-科技科技-科技TRUE
小米、努比亚、360齐上阵,游戏手机,还是手机的“游戏”?科技-科技科技-科技TRUE
深圳地铁“扫码过闸”正式上线:马化腾亲身示范科技-科技科技-科技TRUE
中国迎来第三次留学生“归国潮”,为什么他们都选择回来?教育-教育教育-教育TRUE
美国在亚洲有多少军事基地,分别在哪里?国际-国际军事-军事FALSE

拿到这些数据后,我们可以结合我们上一步分析到的问题类目来进行分析,也可以直接抽is_right的数据来进行分析,我们先考虑后者,并做出记录。

此处,我以其中一个case为例,讲一下分析的过程:"美国在亚洲有多少军事基地,分别在哪里?",这个句子标注结果是“国际-国际”,但是模型预测为“军事-军事”。此处,因为整个分类经历了多个流程,因此把整个流程的日志都给打出来。

2024-07-28 16:11:53.825 | INFO     | __main__:predict:27 - request: 美国在亚洲有多少军事基地,分别在哪里?
2024-07-28 16:11:54.494 | DEBUG    | __main__:predict:30 - [[370, ['世界上被美国驻军的国家有哪些?', ['6552991347354108167''110''news_military''世界上被美国驻军的国家有哪些?''''军事-军事']], 219.74318, 0.7373642921447754], [3601, ['南美洲大军事强国', ['6553019751621198344''110''news_military''南美洲大军事强国''南美洲,阿根廷,哥伦比亚,军事强国,智利''军事-军事']], 254.86084, 0.692778468132019], [6285, ['南美洲 大军事强国', ['6553019696919085581''110''news_military''南美洲大军事强国''军事强国,智利,南美洲,阿根廷,哥伦比亚''军事-军事']], 254.86084, 0.692778468132019], [2935, ['欧洲人怎么看待出现在欧洲的美国军队?', ['6552130324262813956''113''news_world''欧洲人怎么看待出现在欧洲的美国军队?''''国际-国际']], 254.54695, 0.6925537586212158], [752, ['美国一反常态,帮助日本提高海军实力', ['6553052718921941517''110''news_military''美国一反常态,帮助日本提高海军实力''旗风级,军事实力,日本,驱逐舰,军舰''军事-军事']], 271.53687, 0.6715511083602905]]
2024-07-28 16:11:54.498 | INFO     | __main__:predict:58 - 你是一个优秀的句子分类师,能把给定的用户query划分到正确的类目中。现在请你根据给定信息和要求,为给定用户query,从备选类目中选择最合适的类目。

下面是“参考案例”即被标注的正确结果,可供参考:
世界上被美国驻军的国家有哪些?——军事-军事
南美洲大军事强国——军事-军事
欧洲人怎么看待出现在欧洲的美国军队?——国际-国际
美国一反常态,帮助日本提高海军实力——军事-军事

备选类目:
军事-军事,国际-国际

类目概念:
【军事-军事】:权威军事资讯、追踪军事热点、反映军事动态、介绍国内外最新武器发展动态
【国际-国际】:世界新闻、国际博览、新闻人物、评论分析、媒体聚焦

用户query:
美国在亚洲有多少军事基地,分别在哪里?

请注意:
1. 用户query所选类目,仅能在【备选类目】中进行选择,用户query仅属于一个类目。
2. “参考案例”中的内容可供推理分析,可以仿照案例来分析用户query的所选类目。
3. 请仔细比对【备选类目】的概念和用户query的差异。
4. 如果用户quer也不属于【备选类目】中给定的类目,或者比较模糊,请选择“拒识”。
5. 请在“所选类目:”后回复结果,不需要说明理由。

所选类目:
2024-07-28 16:11:55.010 | INFO     | __main__:predict:62 - llm response: 军事-军事
2024-07-28 16:11:55.011 | INFO     | __main__:predict:70 - parse result: 军事-军事
2024-07-28 16:11:55.012 | INFO     | __main__:predict:73 - response: 军事-军事
2024-07-28 16:11:55.013 | INFO     | __main__:<module>:80 - 军事-军事

我一段段解释,首先是这段:

2024-07-28 16:11:54.494 | DEBUG    | __main__:predict:30 - [[370, ['世界上被美国驻军的国家有哪些?', ['6552991347354108167''110''news_military''世界上被美国驻军的国家有哪些?''''军事-军事']], 219.74318, 0.7373642921447754], [3601, ['南美洲大军事强国', ['6553019751621198344''110''news_military''南美洲大军事强国''南美洲,阿根廷,哥伦比亚,军事强国,智利''军事-军事']], 254.86084, 0.692778468132019], [6285, ['南美洲 大军事强国', ['6553019696919085581''110''news_military''南美洲大军事强国''军事强国,智利,南美洲,阿根廷,哥伦比亚''军事-军事']], 254.86084, 0.692778468132019], [2935, ['欧洲人怎么看待出现在欧洲的美国军队?', ['6552130324262813956''113''news_world''欧洲人怎么看待出现在欧洲的美国军队?''''国际-国际']], 254.54695, 0.6925537586212158], [752, ['美国一反常态,帮助日本提高海军实力', ['6553052718921941517''110''news_military''美国一反常态,帮助日本提高海军实力''旗风级,军事实力,日本,驱逐舰,军舰''军事-军事']], 271.53687, 0.6715511083602905]]

这个是向量召回的TOP5,可以看到,他们和原始的句子"美国在亚洲有多少军事基地,分别在哪里?",多少都存在一些相似性,说明向量召回这块的问题好像并不是很大,然而无论是前面几个的“军事-军事”的,可见似乎类似的句子,标注上都会划分到这个类,而非'国际-国际'类,这里仅有一条样本是'国际-国际'类,显然就比较少,而且相似度也比不过前几个结果。

__main__:predict:58下的是prompt,初步看和预期的结果一致,没什么大问题。

后续连续的3行分别就是大模型的回复、解析结果以及最终的的回复了,可以看见都没什么问题:

2024-07-28 16:11:55.010 | INFO     | __main__:predict:62 - llm response: 军事-军事
2024-07-28 16:11:55.011 | INFO     | __main__:predict:70 - parse result: 军事-军事
2024-07-28 16:11:55.012 | INFO     | __main__:predict:73 - response: 军事-军事

从此可见,整体流程初步看下都没有什么问题,似乎是标注的标准可能存在一定的混淆,类似的问题需要考虑澄清或者是更新标注,但是因为这是公开数据集,肯定难易处理这种问题,其实这种问题在公开数据集内并不少见,但是要修复只能说是无能为力。

刚才有提到“财经-财经”类下的错误有很多,此时我们就筛选real为“财经-财经”,但是pred不是这个的样本来分析一下,此处以“金融炼金术——里根的“大循环””为例进行分析。

2024-07-28 16:43:19.892 | INFO     | __main__:predict:27 - request: 金融炼金术——里根的“大循环”
2024-07-28 16:43:20.471 | DEBUG    | __main__:predict:30 - [[4800, ['新手理财首选:陆金所、小宝金融、宜聚网!', ['6553462877376741901''104''news_finance''新手理财首选:陆金所、小宝金融、宜聚网!''陆金所,工薪
族,金融,平安宝-金色人生,宜聚网'
'财经-财经']], 311.99478, 0.6219339966773987], [8826, ['大田环球贵金属:现货黄金走势分析操作建议', ['6553455628277252616''104''news_finance''大田环球贵金属:现货黄金走势分析操作建议''铀浓缩,止损3,鲍威尔,ma5,第一目标,FOMC,伊朗''财经-财经']], 314.15875, 0.6188830137252808], [4861, ['安达比索微交易——四点技巧分分钟赚钱', ['6553173895879328269''104''news_finance''安达比索微交易——四点技巧分分钟赚钱''微交易,投资者''财经-财经']], 312.19086, 0.6164110898971558], [7637, ['直击全球5大战略金属:最后一种有钱也买不到', ['6552340743468352013''110''news_military''直击全球5大战略金属:最后一种有钱也买不到''国防工业,燃烧弹,耐蚀性,铀235,航天器''军事-军事']], 315.8933, 0.611515998840332], [3833, ['陶以平:以FICC为抓手助力黄金市场高质量发展', ['6553402235752022536''104''news_finance''陶以平:以FICC为抓手 助力黄金市场高质量发展''黄金市场,兴业银行,陶以平,工商银行,FICC,上海黄金交易所''财经-财经']], 330.36914, 0.5959779024124146]]
2024-07-28 16:43:20.474 | INFO     | __main__:predict:58 - 你是一个优秀的句子分类师,能把给定的用户query划分到正确的类目中。现在请你根据给定信息和要求,为给定用户query,从备选类目中选择最合适的类目。

下面是“参考案例”即被标注的正确结果,可供参考:
新手理财首选:陆金所、小宝金融、宜聚网!——财经-财经
大田环球贵金属:现货黄金走势分析操作建议——财经-财经
安达比索微交易——四点技巧分分钟赚钱——财经-财经
直击全球5大战略金属:最后一种有钱也买不到——军事-军事
陶以平:以FICC为抓手助力黄金市场高质量发展——财经-财经

备选类目:
财经-财经,军事-军事

类目概念:
【财经-财经】:股票、债券、基金、期货、信托、理财、管理等服务新闻
【军事-军事】:权威军事资讯、追踪军事热点、反映军事动态、介绍国内外最新武器发展动态

用户query:
金融炼金术——里根的“大循环”

请注意:
1. 用户query所选类目,仅能在【备选类目】中进行选择,用户query仅属于一个类目。
2. “参考案例”中的内容可供推理分析,可以仿照案例来分析用户query的所选类目。
3. 请仔细比对【备选类目】的概念和用户query的差异。
4. 如果用户quer也不属于【备选类目】中给定的类目,或者比较模糊,请选择“拒识”。
5. 请在“所选类目:”后回复结果,不需要说明理由。

所选类目:
2024-07-28 16:43:20.906 | INFO     | __main__:predict:62 - llm response: 金融-财经
2024-07-28 16:43:20.909 | INFO     | __main__:predict:70 - parse result: 拒识
2024-07-28 16:43:20.909 | INFO     | __main__:predict:73 - response: 拒识
2024-07-28 16:43:20.910 | INFO     | __main__:<module>:80 - 拒识

这里能很明显的看到,大模型的返回并没有给到我们“备选类目”中的结果,给的是“金融-财经”,这导致最终预测的结果是“拒识”,这是出错的根源。

分析不能掰棒子,我们要把每一条分析结果,都记录下来,并且最好是规范化,方便统计的那种。下面给出一些范例:

caserealpredis_right分析
区块链与科技一拍即合,三角形主机开启数字资产的人人时代财经-财经科技-科技FALSE类目标准问题
黑龙江省的基本养老金是什么标准?财经-财经农业-三农FALSE多标签问题
金融炼金术——里根的“大循环”财经-财经拒识FALSE模型输出内容不符合规范
年逾古稀,却要面临着失去房产,是啥逼迫这对老夫妇?财经-财经民生-故事FALSE未召回正确类目
升级后的余额宝还值得我们投资吗?财经-财经科技-科技FALSE类目标准问题
未来几年最有前途的行业是哪个?财经-财经教育-教育FALSE类目标准问题
什么是庞氏骗局?财经-财经科技-科技FALSE相似度阈值

这里给出的是实际值是‘财经-财经’但实际并不是‘财经-财经’这个类目的bad case的分析数据,这里比原始数据多了一列,即分析,分析内给出这个case的归因分析,这里有几个细节需要强调:

  • 可以考虑尽可能用统一的说法,方便归类。
  • 如果出现多个问题,可以都写上去,逗号隔开。
  • 坚持下去,多分析一些,从而体现出各个问题的实际占比,少则50多则100,看得多对问题理解、解决思路都有很大好处。

这个过程毫无疑问是比较枯燥的,但坚持下来,无论是对解决问题,还是对个人成长,都是有巨大好处的,所谓的经验就是从中而来,对问题有了解,在遇到新的问题时能提前预知风险和难题,这都是前期看case积累沉淀下来的,所以这个投入绝对值得。

在逐个对bad case进行分析后,希望大家能够梳理出类似这样的一个文档:

分析X个bad case后,分析出问题按频率排序如下:
1. 类目标准问题,X个,占比30%。
2. 多标签问题,X个,占比20%。
3. 模型输出内容不规范,X个,占比10%。

问题已经定位好了,那我们距离解决就非常接近了。

解决问题

剩下的,就是针对问题提供解决方案了,这是一个非常考验经验和积累的活。上面的问题,其实很多都有一些trick的方式来解决,或者压根就是系统性问题不好解决。

以类目标准问题为例,类目的标准来自开源方,我们无法直接改变这个标准,以及内部的数据标注,但在实际应用中,我们是可以沟通更新解决的,边界明显化不仅是对模型效果收益,在业务层面,也能更加清晰。类似的还有多标签问题,只有把方案升级为多标签方案(包括标签体系),才有机会继续搞。

比较好处理的是分类方案内的细节问题,例如相似度模型错误,相似度阈值,模型输出内容不规范等,都是可以轻松解决的,相似度模型方面可以通过阈值、微调模型之类的来优化,模型输出内容不规范可以优先考虑prompt或者是别的兜底方案,例如参照向量召回的结果。在问题比较明确的情况下,解决问题的方法就逐步明确了。

这里真的非常考验积累,不得不再次强调两个很经典的拷打。

  • 你不会只会微调这招吧。
  • 说得好像微调后,效果就能提升似的。

会针对问题提出方案的能力还是非常重要的,模型外围增加规则或者别的模型进行辅助,根据bad case定向收集更多样本提升覆盖率,调整阈值,增加“垃圾桶”类目(例如拒识)等,都是些技巧,需要多打开思路,也多研究各种分享的案例。

小结

之前的bad case治疗术系列写的比较抽象,这次结合一个具体任务来给大家讲解这里的细节,该分析哪些数据,具体分析哪些方面,具体怎么做有效,怎么对最终的结果有好处,这种思维模式能让我们更聚焦于问题本身,更有针对性,更有利于解决当下问题。

当然,也有缺点,在这里也补充说一下,这个思路容易让我们陷入局部的问题,对更大的,类似模型结构的,大方向上的问题,很容易被忽略,这个还是要注意。

CS的陋室
陋室,用知识装点。房主主要谈论与数学和计算机相关的知识,不定时推送和个人学习进度相关的知识,大数据时代,数学和计算机一个不能拉下。来一起学习和讨论吧!
 最新文章