任务方案思考:文本分类篇
0 小系列初衷
自己接触的项目大都是初创,没开始多久的项目,从0到1的不少,2020年快结束,感觉这个具有一定个人特色的技术经验可以在和大家分享一下。
预计会有下面篇章:
文本分类篇。针对NLP文本分类任务。 序列标注(NER)篇。针对命名实体识别、序列标注任务。 文本匹配篇。针对语义相似度计算、向量匹配等问题。 人工特征学习篇。针对多特征的机器、深度学习方案。
1 文本分类的场景
文本分类可以说是NLP的入门级任务,尤其是NLU领域,最简单的就是这个任务了,而在现实应用中,这也是最容易实现的一个任务,因此在面对NLP问题时,如果能抽象为文本分类问题,那实现成本会低很多,下面列举几个比较常见的场景:
搜索、意图识别。 对话的情感情绪、话题、技能识别。 文章主题划分。
可以看到,对文章、句子级别的理解,其实很多都可以抽象为文本分类。
2 方案选型
针对文本分类,可谓是条条大路通罗马,各种奇招怪招很多,这里给大家梳理几个常见、通用参考的方案。
2.1 规则正则
其实很多问题通过一个简单的规则或者是一条简单的正则表达式就能搞定了,例如我要判断一个句子里是否有英文:
[a-zA-Z]+
不会吧不会吧不会吧,应该不会有人想弄个文本分类模型来整这玩意吧?
这应该是最简单的一种文本分类方案了,快速而且一般高准,至少准确率上很容易打标,而且耗时上性能也非常优秀。
2.2 词典模板
词典模板应该是搜索领域最常用的方案了,这种方案相比规则正则具有更高的灵活性,而且由于搜索本身对物料的要求也较高,因此随着物料数据的丰富,词典质量能得到提升,准确保证的前提下,召回也能得到保证。简单说说词典模板的思路:
离线: 通过数据库、用户query等方式挖掘词典和模板。例如“[小说名][免费][全本][阅读]”。 在线: 对于query,根据词典抽取query中存在的关键词,查看是否匹配到对应模板。
2.3 有监督模型
通常前面两个方案就能处理大量高频、简单的分类问题,但对于复杂问题,我们依旧是需要用模型来处理,这里推荐几个比较简单快捷的文本分类模型给大家使用:
fasttext。速度超快,快速实现,但是模型层数浅,效果上其实和模板匹配差不了太多。 textcnn。经典基线,效果提升。模型深度提升,效果提升,当然耗时压力也提升了。 bert-cls。部分场景效果优秀(换言之,不万能,对简单问题的处理能力甚至更差),但是由于性能原因上不了线,只能离线计算后通过词典的方式上线。
有这三招其实对于工程已经完全足够了,如果遇到效果不足的话,其实可以考虑一些规则+模型的方式,结合数据集的精炼,效果基本就能达标了,具体的一些调优手段,在下一章会聊。
2.4 其他方法
当然了,要完成文本分类任务,还会有一些比较奇怪的招数,例如抽象为KNN,即查看最接近的case(语义相似度衡量相近)的类目来判断结果;召回-排序分离等,至于这些方案怎么来?我的经验看来论文、分享上都非常少,大都是在case分析的基础上,慢慢提炼解决方案领悟到的。
3 效果调优
上面你的只是一些比较规范化的方案,然而实际上并不是说我们使用这些方案就一定能得到好的效果,我们需要做的是在上面方案为基线的情况下,分析bad case,找到合适的优化方案使整个文本分类任务效果能够更好。
有关bad case分析的经验,放这里:
现在给大家介绍几个效果优化的策略。
3.1 分级处理
在阿里小蜜的经验分享中我就提到过了这点:前沿重器[5] | 阿里小蜜的数据量分级处理机制,而且是花一篇文章来讨论这个问题,其实他的思想就是,简单问题用简单方案,复杂问题用复杂方案,通过分级措施,简单、高频的query能快速返回结果,让用户的需求更快满足。
另外,建议大家依旧坚持弄一个规则模块,或者是一些黑白名单,毕竟算法这块是需要干预能力的,遇到紧急问题,重训模型不现实,此时对用黑白名单去操作就非常方便了。
3.2 精炼数据
模型效果不好,不好在哪里,可以通过bad case快速分析出来,很多时候通过加入一些bad case对应的数据就能有非常明确的效果,举几个例子:
文本对英文的识别不明确,那就开始给他灌中英文混合或者英文的数据。 特定专名识别不好,那就增加一些专名。 标注样本本身就有很多不准,不要以为标注的数据一定就是对的,此时就要提升标注样本的质量。
3.3 模型缺少什么信息
虽然NLP是可以说是一个对深度学习以来比较深的领域,这让这个任务不需要太多人工特征,但不代表人工分析特征缺失就不需要,通过case分析其实可以看得到模型对哪些类型的句子分类不准,我们就需要让模型针对性的学习,例如模型对序列信息学习不好,那我们就该加点rnn系列的积木进去,具体加的方式,这个有很多,并列的、先后的都行,可以自行尝试。
3.4 模型+规则后处理
模型本身是一个招数,能有很强的泛化能力,但是实际上简单模型或者说特定模型有一些东西不太好解决,一些很明显的问题,我们不要急于直接就该模型、更新数据之类的,而是可以看看是否能通过一个小规则就能解决,如果是,那可太香了。
3.5 召回+排序结构
学习完推荐系统让我感到最震撼的一点是,要让一个东西尽可能精准而又全面,抽象出来其实就是有高准、高招,一个很有用的方案就是把高准确和高召回两个任务分开,分别解决,分别控制,这样去进行调优的空间就会更大,这就是“召回-排序”结构。
召回:通过简单粗略的抽取、过滤手段找到一些可能结果,或者说把肯定不对的结果给过滤了,构造一个相对全集更小的候选集。 排序:通过分类等打分手段,找到这几个候选结果中最可能的结果。
重申这个方案的优点——准招两个任务需求分离,分别控制。当然,也有缺点,缺点来源于灵活性,就和接水管,要求每根水管质量都好才不会漏水,因此控制的难度就会比较差,同时太过复杂的话,可能会有内存和耗时的风险。
4 其他想说的
基线方案其实大家都懂,只要稍加学习基线方案都能轻松完成,而分高下就在于,针对那些错误、没错好的点,能否找到快速、精准解决的方法,这也是打算写这个小系列的目的,多给大家一些思路。