经过几十年的发展,文本分类在学术界已经是一个比较成熟的技术,目前自然语言处理(NLP)的研究热点已经不在文本分类上面。然而,作为内容安全检测的一个重要技术手段,文本分类在实际业务中还是有不少的挑战。

首先,内容安全场景对分类的准确度要求极高,不但要求较低的误判率,任何一个漏判都有可能给产品方带来严重的后果。其次,众所周知数据不平衡对分类模型的影响很大,而内容安全场景恰恰存在非常严重的数据不平衡问题。本文主要讨论文本分类在内容安全应用中遇到的数据不平衡问题以及常用的解决办法。

数据不平衡问题是分类算法在实际应用中经常遇到的一个问题,它指的是在训练语料或真实数据中,各个类别的数据量相差较大,我们知道模型的训练本质上就是最小化一个损失函数,如果各个类别的样本规模不一样,损失函数的值较大部分由大类别贡献,那么最终得到的模型分类将偏向于大类别。

举个例子,假如训练语料中正样本数量为100个,负样本数量为100000个,那么你很可能得到这么一个模型:不管输入什么样的数据,分类结果都是负例,这个模型准确率>99.9%看起来相当不错,可实际上这个模型有跟没有没啥区别。上面是一个比较极端的例子,可很不幸的是,内容安全领域的数据不平衡现象就是这么极端,有害内容占比一般低于千分之一。

对于数据不平衡问题,目前还未看到比较理想的解决方法,现有的方法按照其着眼点可以分为数据重采样、修改损失函数、模型改造3大类。其中模型改造这一类的方法都是与某一特定模型紧密耦合的,由于缺少通用性实际应用中使用的较少,本文只对前面两种方法进行介绍:

一、数据重采样

数据重采样是处理数据不平衡问题时首先能想到的方法,既然各个类别数量不平衡,那我们想办法让每个类的数量都差不多不就行了吗?

数据重采样方法在只有训练数据的基础上,对训练数据进行采样,从而让各个类别数量接近,具体分为过采样和欠采样两种思路。需要注意的是,如果你的模型对业务产生的价值较大,并且数量少的类别线上数据并不少,只是缺少标签,那么也别想着用技术手段解决不平衡问题了,收集点数据找人去打标才是最佳选择。

1.过采样

最简单的过采样方法小类别的样本进行重复随机采样,补充到小类别当中,直到小类别样本数据量增大到符合要求为止。可以看出这种方法只是单纯增加小类别样本数量,并不能扩大小类别样本的多样性。

SMOTE一种近邻插值方法,它使用下面的公式对小类别的两个相似样本进行线性组合:

其中0≤u≤1, x^R是x的5近邻中的随机一个。可以看到,SMOTE生成了新的样本,扩大了小类别样本的多样性,同时生成样本的总体期望值与原来的分布相同。

由于SMOTE是直接对向量化的数据进行插值,不能直接应用于文本分类任务的离散空间插值。作为替代方案,我们可以在小类别样本上面进行LDA概率主题模型建模,然后利用LDA模型生成新的样本。

LDA模型认为文档的主题并不是确定的,而是一个多项式概率分布,这个概率分布本身又是根据Dirichlet分布产生的,Dirichlet分布的参数可以通过Gibbs Sampling方法从提供的语料上面学习得到。

有了LDA模型以后,文本生成过程如下:对文本中的每个词,根据Dirichlet分布随机生成一个主题分布,然后根据主题分布随机抽样出具体的词汇,重复上述过程直到满足文本长度要求。

改进过采样小类别样本多样性的另一种思路是对小类别样本使用文本增强方法。文本增强是在NLP低资源任务中经常使用到的一种技术,主要是通过对原文本进行小幅度的修改,使得修改后的文本跟原文本在内容上有一定的差异,同时又与原文本保持相同语义。常用的文本增强方法有词汇替换、随机噪声插入、样本混合、回译、句法变换等。

2.欠采样

与过采样方法相反,欠采样对大类别的样本进行随机删减,直到规模与小类别相近为止。欠采样方法一般运用在大类别样本规模和多样性足够大的场合,否则建议优先尝试过采样方法。

原始的欠采样方法对于大类别的样本的删减是无差别的,但在实际应用中大类别内部的样本分布本身也是不均衡的,有些样本分类器很容易就能把它与小类别区分开来,有些样本则更容易被分类器误分为小类别。理想的欠采样方法应该是多删除那些容易分类的冗余样本,尽可能多保留较难分类的样本。为了达到这样的效果,我们可以使用迭代预分类方式不断筛选大类别的样本。

首先从大类别中随机挑选少量的样本作为种子样本,剩下的作为候选样本,然后用种子样本联合小类别样本组成训练集训练出一个分类模型,分类模型对候选样本进行分类,从错分的样本里面随机挑选少量的样本补充到种子样本当中,重复前面的过程直至类别平衡或者候选样本不再被错分为止。通过上面的方法,最终挑选出来的样本都是对分类贡献比较大的样本。

二、修改损失函数

我们在前面提到,数据不平衡对文本分类的影响本质上是由模型训练过程中最小化损失函数这一目标决定的,因此解决数据不平衡问题的第二种思路就是修改损失函数,减少大类别对损失函数的影响。

特别是在深度学习技术流行以后,由于损失函数的定义与具体模型结构较为解耦,对损失函数进行改进后,可以用于所有的分类模型,因此目前这块的研究工作还比较活跃,不断出现较为有代表性的方法。

1.loss类别加权

这是一种比较朴素简单的方法,在计算每个样本的loss的时候根据其类别乘以不同的权重,权重系数一般与类别样本数量成反比。Loss类别加权在本质上跟数据重采样是相通的,两者最终对loss的改变是一致的。

2.Focal loss

focal loss不但考虑了类别规模性差异的因素,而且还同时考虑了容易分类样本和较难分类样本的差别,假设样本的真实label为t,focal loss计算公式如下:

其中p_t是模型输出的label为t的概率,α是类别系数,γ>=0称作focusing parameter,称作调制系数。可以看出,当γ=0时focalloss就退化成普通的类别加权loss。当γ>0时,样本越容易分类,p就越接近1,调制系数就越小,最终loss值就越小,样本越难以分类,p就越接近0,调制系数就越大,最终loss值就越大,因此,调制系数的引入使得loss的计算偏向于那些较难分类的样本。

3.GHM loss

Focal loss是在理想情况下考虑对难分类样本的处理,在现实场景中训练数据往往是有噪声的,比如人工打标失误,这个时候可能模型已经收敛了,focal loss还在死怼这些不能正确分类的噪声样本,最终反而用力过度,得到不是最优的模型。

GHM解决了这个问题,它首先提出梯度模长的定义:

p就是模型预测值,p*就是真实值,模长越大,分类错误越严重。GHM对不同模长的样本数量做了统计,结果如下:

上面y轴是取了log的结果,左边那些代表了大部分较容易分类的样本,右边很难分类的样本也不少。Focal loss的做法是忽略左边那些容易分类样本,重点关注右边那些难分类的样本,GHM的思路却是右边这些样本太难了,应该是异常的,不如先忽略这部分样本。具体做法就是根据梯度上面的样本量,样本数量越多的梯度给的权重越小,公式如下:

其中GD(g)称作梯度密度,密度越大说明这个梯度区间的样本量越多。

三、效果评估

常规情况下文本分类模型的开发流程是这样:

1)从真实业务数据中收集一批数据,如果没有标签则进行人工标注。

2)把这些数据分成3份:训练集、验证集(或叫开发集)、测试集。

3)算法人员在训练集上面训练模型,在验证集上面验证效果,过程中夹杂着选模型、调参、各种魔改等等。

4)最终得到一个比较满意的模型,在测试集上面跑一下效果,如果ok那就上线,不行那就重来。

上述流程之所以行得通,是因为我们假设训练集、验证集、测试集数据分布都与真实业务数据一致,验证集和测试集代表了对真实数据的一个采样,模型在测试集上的表现与在真实场景是一样的。在内容安全检测场景,由于极度的数据不平衡问题上面的流程就不适用了:测试集中如果保持正常内容和有害内容比例跟线上一致,要么需要标注巨量的正常样本,要么有害样本数量太少,得到的召回率可信度不高,如果两者比例与线上脱轨,那么得到的准确率、精确度、召回率这些指标必然与在线上数据的表现不一致。

内容安全业务上主要关心误判和漏判的情况,前面的例子也可以看出准确率在这里意义不大,所以我们只重点评估模型的精确度和召回率。

模型重新训练有两种原因,一种是纯粹的技术优化,比如换个神经网络或loss,一种是修正线上的误判漏判badcase,第二种情况训练集是会补充新样本的。我们保持一个相对独立由一些代表性样本构成的测试集,里面的正负样本比较均衡。测试集不会每次都随训练集一起维护,只有在出现一些新类型的样本时才进行维护。

当模型优化完成以后,先在测试集跑一遍,计算召回率指标和总体准确率,这个召回率可以认为是接近真实的,准确率就只能作为模型不同版本定性比较的一个参照值了。由于正常内容的范围实在过于广大,测试集很难覆盖所有可能的误判样例,并且测试集正负样本比例并非真实比例,这导致精确度很难估算并且不准确。在测试集上面根据召回率和准确率评估当前版本模型比上一个版本有改进以后,再使用线上真实数据跑一遍,对命中的数据抽样人工打标,从而计算出一个比较真实的精确度指标。

四、反向利用

内容安全检测数据极度不平衡的特点,在给模型效果优化带来挑战的同时,也给我们优化系统整体RT提供了帮助。深度学习模型相比传统的机器学习模型在精度方面进步很多,但相应的计算量却也增加更多,比如,CNN模型的检测时间是SVM的十倍以上。

在全面升级深度学习模型的同时,硬件的成本也急剧增加,硬件资源严重限制了NLP最新模型与技术的落地。其实线上数据有害内容的比例是很低的,对于大部分正常内容的检测理论上是在浪费硬件算力。理想状态下只要把那些有害内容过一下模型识别出来然后删除即可。基于这样的想法,我们提出了预检-终检二阶段过滤的模式:

在原来的深度学习模型基础上,使用机器学习模型在重新训练出一个预检模型,调整预检模型的分类阈值使得模型对有害样本具有非常高的召回。线上数据先过预检模型,把召回出来的少量可疑数据再用深度学习模型识别。这种模式实际效果非常好,上线后在保持召回基本不变的前提下,RT直接减少75%以上。

五、总结

本文针对内容安全场景中文本分类遇到的数据不平衡问题进行讨论,介绍了应对数据不平衡问题的几种技术方法,包括过采样、欠采样、加权loss、focal loss、GHM loss等,同时分析了数据不平衡对模型效果评估的影响以及我们采取的做法,最后分享了我们利用数据不平衡特点进行RT优化的经验。

在网上,我们会阅读到在各种场景下出现的文字,包括图片标题、账户名称、视频弹幕、社群评论、短信等,这推动着网易易盾不断结合实际场景推出新的技术解决方案。

除文本检测之外,易盾的内容安全服务涵盖图片检测、视频检测、音频检测、人工审核和智能审核系统等产品,以及广告合规、网站内容检测、文档内容检测、历史数据清洗、音视频、社交娱乐、政企、媒体等解决方案。

智能时代,内容安全与技术的结合更加深刻。今后,在关注相关研究的同时,易盾将继续根据自己的业务特点进行探索。(作者:网易易盾NLP算法专家林洋港(菜牛))

文本分类在内容安全应用中的数据不平衡问题相关推荐

  1. 机器学习中的数据不平衡问题----通过随机采样比例大的类别使得训练集中大类的个数与小类相当,或者模型中加入惩罚项...

    机器学习中的数据不平衡问题 摘自:http://wap.sciencenet.cn/blogview.aspx?id=377102 最近碰到一个问题,其中的阳性数据比阴性数据少很多,这样的数据集在进行 ...

  2. 达观数据携手CCF举办第五届“达观杯”自然语言处理文本分类竞赛 ,开赛报名中!

    作为国内领先的智能文本处理企业,达观数据主办发起"达观杯"人工智能算法竞赛,每年一届,至今已成功举办四届.2021年,在CCF(中国计算机学会)自然语言处理专业委员会的特别支持下, ...

  3. c语言读取网页文本内容,从文本文件中读取数据

    请问如何用c语言从txt文件中读取数据? 请问如何用c语言从txt文件中读取数据? 就是用空格分开的数据,例如:12//其中的in.txt就是你要读取数据的文件,当然把它和程序放在同一目录 - #in ...

  4. 查找和替换文本和其他 Word 文档中的数据(转)

    今天看一段vba代码,目的去除段首空格,替换的时候查找的文字是^w,不知其意,然后搜索去了 参考:http://zhidao.baidu.com/link?url=dPoOamRVLkY-WpD6v5 ...

  5. 分类问题中的数据不平衡问题

    原文地址:http://blog.csdn.net/heyongluoyao8/article/details/49408131 感谢作者   在很多机器学习任务中,训练集中可能会存在某个或某些类别下 ...

  6. qtplaintextedit如何删除内容_数据库中的数据如何进行批量修改

    大家好,今日我们继续VBA数据库解决方案的第29讲:如何批量修改数据库中的记录.在数据库解决方案中,我在从实际应用的角度,把工作中可能遇到的各种情况都尽可能的给罗列上,我们先后讲了: ①如何在数据库中 ...

  7. linux修改数据库内容命令,linux中的数据库命令

    linux中的数据库命令包括链接,重启,关闭等等.下面由学习啦小编为大家整理了linux下的数据库命令的相关知识,希望对大家有帮助! 一.linux下启动mysql数据库的命令 1. mysqladm ...

  8. 如何解决机器学习中的数据不平衡问题?

    在机器学习任务中,我们经常会遇到这种困扰:数据不平衡问题. 数据不平衡问题主要存在于有监督机器学习任务中.当遇到不平衡数据时,以总体分类准确率为学习目标的传统分类算法会过多地关注多数类,从而使得少数类 ...

  9. golang 得到 结构体 struct 标签 tag 内容 结构体中的``数据

    goLang获取struct的tag内容:beego的ORM中也通过tag来定义参数的. 获取tag的内容是利用反射包来实现的.示例代码如下: package main import ("f ...

最新文章

  1. 使用JPA进行Update操作 @Query注解的用法,JPL
  2. 第一代狗狗币教父联合社区挽救狗狗币,并在国内布道狗狗币三年之久
  3. 对C语言islower、isupper、isdigit函数的测试
  4. [Leetcode] Remove duplicates from sorted array ii 从已排序的数组中删除重复元素
  5. 1.14 Java注释:类、方法和字段注释
  6. 关于WS_CLIPCHILDREN和WS_CLIPSIBLINGS的理解
  7. 【转】selector函数指针回调机制
  8. 面试题 04.04. 检查平衡性
  9. 浅析Spring.net 中的Aop使用
  10. Chrome 地址栏如何设置显示 http/https 和 www
  11. 利用spring集成redis使用
  12. UE5实现HTC Vive VR功能
  13. 中国十大最狠的流氓网站曝光!送查杀流氓的工具
  14. 你可以穿裙子,但是请放长你的裙摆
  15. 网站流量不是很多,还有这几十种途径让网站变现转化
  16. 重型音乐金属核后期分轨混音教程教学培训(基础+进阶+重型音色调音指南+剪辑+修音+美感设计+实战+母带处理)|MZD Studios
  17. jQuery DataTables的serverSide选项
  18. 一念逍遥显示服务器列表失败,《一念逍遥》进不去解决方法
  19. Oracle加入NoSQL阵营
  20. Qt 方向键移动焦点

热门文章

  1. IBM T61 系列笔记本,WinXP 系统下驱动程序的简化安装
  2. 【剑指offer】java版题解(持续更新)
  3. 2022年大一下网页期末作业【二十四节气】纯html、css制作
  4. qt多种字体格式并用
  5. 关于showModal的坑
  6. 华为服务器光盘安装操作系统,服务器安装操作系统步骤
  7. k8s资源管理命令与Namespace使用详解
  8. 百度网站如何加快收录?
  9. 时序预测 | MATLAB实现基于Adam算法优化LSTM长短期记忆神经网络时间序列预测
  10. opendaylight-O版本与openstack集成