算法工业界文本分类避坑指南
完整的思维导图关注包包算法笔记回复【避坑指南】获取下载查看链接。
公众号包包算法笔记,包包(包大人)的机器学习笔记,分享算法,机器学习,程序员,职场等算法工程师话题。
背景
说起文本分类,也算是一个老掉牙的话题,之前大家都喜欢琢磨模型。最近从工业界的视角看一下文本分类,看一些从0到1做一些和文本分类项目,可能大家都会踩过的坑,以及经验教训,都是一些比较有意思的问题,主要从问题拆解与数据,算法选型与推荐,细节策略与实现补充。
思维导图回复【避坑指南】获取下载查看链接。
目录
一、问题拆解和数据
-
Q1 构建文本分类标签体系有哪些坑?
-
Q2 初期监督数据不够怎么办?
-
Q3 如何高效的积累标注数据?
-
Q4 如何发现新的类别?扩充类别空间?
二、算法抽象和选型
-
Q5 文本分类任务有哪些难点?
-
Q6 如何定义一个文本分类问题的难度?
-
Q7 文本分类算法选型有何推荐?
-
Q8 如何确定验证集和评价方法?
三、细节策略和实现
-
Q9 如何处理溢出词表词?
-
Q10 文本分类技术演进的明线和暗线?
-
Q11 策略和算法如何结合?
-
Q12 有哪些可以刷分的技巧?
-
Q13 模型inference资源限制条件下,如何挑战算法选型的天花板
问题拆解与数据
Q1 构建文本分类标签体系有哪些坑?
在我们在做真实的业务问题的时候,不像给定一个数据集,标签就是定死的。如何确定一个合理的分类标签体现其实是十分关键的。这个阶段一定要做数据充分的探索性分析。图省事吃大亏。
下面几个基本的原则:
-
稀疏程度合理。一般正常的分类体系都是符合一个长尾分布,大概可以分为1.主要类A,主要类B,xxx,其他类。softmax based分类模型还是主要解决这部分样本比较多的问题。有个小技巧,按照业务上出现问题的频度,分类空间最好预留其他方便迭代。
-
类间可分,类内聚集。不要搞一些分不开的类,最后发现学出来的两个结果,置信度都不高,对我们没有什么意义的。
-
标签的关系明确。是多分类问题呢,还是多类别问题呢,还是层级分类呢?不同的问题有对应不同的方法,尤其是层级分类,坑比较多,这里先不展开了。
Q2 初期监督数据不够?
标注数据总需要一定的时间,这时候除了用规则,词典之类的方法外,或者fewshot learnig的一些思路解决问题,大体的思路是两种。
-
Fewshot Learning 把分类问题转化为匹配或者相似度学习的问题,减小分类空间学习的难度,问一个小孩这个水果是啥比,总要比,选择一个最像的水果要简单。
-
**迁移学习 **Bert在小数据上表现其实挺出色的,除了慢一点,似乎没有其他毛病了。上两个阶段大概只需要几千条数据就可以跑起来了。
Q3 如何高效地积累标注数据?
有了前面起步的baseline,我们至少可以扔到线上把模型跑着了,然后人工标注数据怎么积累又是一个问题,不同的样本对于我们当前的价值是不一样的,类别空间会扩充以及长尾标注样本数量不足是两个最常见的问题。大体的原则是通过不确定性度量和多样性度量两个角度,来选取对当前模型增量送训样本最优价值的样本。
-
不确定的样本 典型的特点是模型输出的置信度不高,没有把握判断是哪一个类别,这种样本需要人工给出真实的类别,指导学习。baseline可以用熵来度量。
-
不一样的样本 典型的特点就是一些与积累数据分布有差异的,玩比赛的常用的adversrial validation,也是一个简单高效的办法。学术界在度量分布差异的时候,总喜欢从数学的角度提出一些奇奇怪怪的指标,甚至还有结合ugly的聚类去做。而adversrial validation直接从监督学习的视角出发,让模型来自动学习给定标签的分布差异,从而有一定的区分能力。并且,这个过程中,特征重要性和预测的置信度两个结果分别完成了特征选择,样本粒度的分度度量置信度评价。看一下uber这篇论文Adversarial Validation Approach to Concept Drift Problem in User Targeting Automation Systems at Uber,在concept drift detection里面,这也是一种神器。本质原理都是一样的,只不过concept drift detection里,我们用的是特征重要性反馈,在分布度量里,我们用的是结果的置信度。
- 图片
Q4 如何发现新的类别,扩充类别空间?
有一些方法还挺不错的,推荐ACL2019的那个论文** Deep Unknown Intent Detection with Margin Loss **
图片非常简洁明了。我们在Kaggle Bengali的比赛里面也用了类似的方法检测新类别,不过用的是arcface异曲同工吧,都是margin softmax,简单又效果非常好。具体可以前情回顾发表在我知乎上的(无法插入跳转链接)
从kaggle看2020的手写体识别:从MISNIT到Bengali.AI 手写体识别大赛
https://zhuanlan.zhihu.com/p/114131221
本质上都是找出,与已知类别不相似(分布差异较大)的样本,其实用前面的adversrial validation也可以解决,实测margin softmax效果更好一点。
算法抽象和选型
Q5 文本分类任务有哪些难点?
图片文本分类的难点也是自然语言的难点,其根本原因是自然语言文本各个层次上广泛存在的各种各样的歧义性或多义性(ambiguity)和演化的问题,下面典型的例子:
-
输入层面:短文本->长文本和超长文本
-
标签层面:复杂语义识别,如阴阳怪气
-
时间演化:川普VS 川普,开车VS开车
-
上下文:美食论坛苹果小米黑莓 VS手机论坛苹果小米黑莓
Q6 如何定义一个文本分类问题的难度?
典型难度排序:主题分类-情感分类-意图识别-细粒度情感识别-复杂语义识别(如阴阳怪气)
-
数据量 典型的例子:one/zero shot VS 海量
-
非线性 典型的例子 :阴阳怪气 VS 垃圾邮件
-
类间距离 典型的例子:细粒度的情感分类 VS 正负情感倾向
Q7 文本分类的算法选型推荐?
算法选型的出发点就是权衡各种约束,考虑模型的天花板能力,选择合适的模型。一般对应任务的难度,权衡计算时效,选择合适的模型。除了忽略一些比千分点的场景,比如竞赛和论文,一般这块在确定算法选型后,就没啥油水了,建议少花精力。有经验的算法工程师,一定能人脑搜索出一个当前选型下的最优结构。一个特别经典的建议大家试一下,concat_emb-> spartial dropout(0.2)->LSTM ->LSTM->concat(maxpool,meanpool)->FC。
结合前面的任务难度定义,推荐的算法选型行为
-
Fasttext(垃圾邮件/主题分类) 特别简单的任务,要求速度
-
TextCNN(主题分类/领域识别) 比较简单的任务,类别可能比较多,要求速度
-
LSTM(情感分类/意图识别) 稍微复杂的任务
-
Bert(细粒度情感/阴阳怪气/小样本识别)难任务
Q8 如何确定验证集和评价方法?
这是个老大难的问题,特别是实际应用中,由于文本分类符合一个长尾分布,常见类别的识别能力其实一般比较ok,长尾识别的稀烂,如果单纯看准确度的话,是个还不错的模型,但你不能说他好吧。对应着指标就是acc很高,macro-f1很低。
-
确定各类别错分的代价 特别是在类别较细或者层级标签的时候,如果在一颗子树上的标签,犯错的成本并不高。要是完全截然相反的类别,犯错的代价就特别大。这里建议通过惩罚矩阵的方法,构建细粒度的惩罚代价。
-
合理采样的验证集 真实的标签分布可能过于不均衡,建议掐头补尾,这样的验证集评价往往更有区分度。
-
**语义压测 **各种花里胡哨的变体输入,未纠错的文本都来一套,实在不行,上adversrial attack 攻击一下。
细节策略和实现
Q9 如何处理溢出词表词(OOV)?
这个在前Bert时代是一个挺关键的问题,以前回答过,还可以参考。从数据中来到数据中去, 要么想办法还原次干,找到可以替换的词向量。要么从sub-word的层次学习出语义,参考Bert BPE的方法。很早很早念书的时候,还没有Bert做过一些文本分类的比赛,在一些任务上搞定OOV提分还是很大的。给之前回答过的一个前Bert时代方法的链接。
WordEmbedding如何处理未登陆词?
https://www.zhihu.com/question/308543084/answer/604729983
Q10 文本分类模型演进的明线和暗线?
针对上文提出来的文本分类的难点,其演进路径大概也是从统计机器学习,词向量+深度学习,预训练语言模型的发展。
-
明线:统计-机器学习-深度学习-更深的深度学习
-
暗线a:简单表达-语义表达-上下文语义表达
-
暗线b:特征输入粒度 从词到subword
-
暗线c:预训练权重从输入层扩展到网络结构内部
关于路线的演进,这里有个前几天画的思维导图:部分截图如
图片<figcaption style="margin: 0.66667em 0px 0px; padding: 0px 1em; outline: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; font-size: 0.9em; line-height: 1.5; text-align: center; color: rgb(153, 153, 153);">思维导图部分截图</figcaption>
Q11 策略和算法怎么结合?
算法工程师不能老鄙视规则,很难一个模型搞定所有问题。
-
串行式 典型的代表是,规则捕捉-分类-匹配兜底,大概这样的流程会比较合理,规则部分负责解决高频,和bad/hard case,分类负责解决长尾中的头部, 匹配负责解决长尾。这样的优点是,效率很高,往往大部分case很快就过完了。
-
并行式 规则,分类,匹配都过,然后进行归一化后的置信度进行PK,有点类似于广告竞价,这样的好处是能充分融合多重策略,结果更可靠。
Q12 有哪些可以刷分的奇技淫巧?
可以尝试的点还蛮多的,搜索空间特别大,感兴趣的可以试试,不保证都有效。这部分的方法大多需要在算法选型敲定后,在模型结构上下功夫,需要遍历一些搜索空间。不建议花太大的精力,具体可以参照之前的回答,而且有了bert之后,他们越来越不重要了,也就没有补充Bert上面的一些操作了:
在文本分类任务中,有哪些论文中很少提及却对性能有重要影响的tricks??
https://www.zhihu.com/question/265357659/answer/582711744
Q13 模型inference资源限制下,如何挑战算法选型的天花板
玩比赛的经常遇到过这个问题,典型的场景Kaggle上要求提交模型,更换测试数据,只给两个小时的推断时间。
除此之外,我们在工业界耗时严格的场景下,Bert总表示遗憾,效果虽好,但是臣妾做不到啊。想要TextCNN的速度,又想要逼近Bert的效果。
图片这时候模型蒸馏就派上用场了,模型蒸馏在Kaggle一些线上推断比赛的top solotion必不可少的。Hinton给的baseline是这样的,通过teacher model产出soft-target。然后student同时学习hard target和teacher model的soft-target。不过要注意的是,用的时候不要leak,先用KFold产出soft-target的oof,然后和GroundTruth一起给student训练。在不少开源代码里看到leak soft-target的情况,用teacher摸过训练标签的样本给student学习。
图片