什么是多标签分类?
在分类问题中,我们已经接触过二分类和多分类问题了。所谓二(多)分类问题,指的是y值一共有两(多)个类别,每个样本的y值只能属于其中的一个类别。对于多标签问题而言,每个样本的y值可能不仅仅属于一个类别。 举个简单的例子,我们平时在给新闻贴标签的时候,就有可能把一篇文章分为经济和文化两个类别。因此,多标签问题在我们的日常生活中也是很常见的。 对于多标签问题,业界还没有很成熟的解决方法,主要是因为标签之间可能会存在复杂的依赖关系,这种依赖关系现阶段还没有成熟的模型来解决。我们在解决多标签问题的时候,一种办法是认为标签之间互相独立,然后把该问题转化为我们熟悉的二(多)分类问题。 本文以 2020语言与智能技术竞赛:事件抽取任务 中的数据作为多分类标签的样例数据,借助多标签分类模型来解决。 整个项目的结构如下图所示: 首先,让我们来看一下样例数据。
数据分析
首先,让我们来看一下样例数据的几个例子:
司法行为-起诉|组织关系-裁员 最近,一位前便利蜂员工就因公司违规裁员,将便利蜂所在的公司虫极科技(北京)有限公司告上法庭。 组织关系-裁员 思科上海大规模裁员人均可获赔100万官方澄清事实 组织关系-裁员 日本巨头面临危机,已裁员1000多人,苹果也救不了它! 组织关系-裁员|组织关系-解散 在硅谷镀金失败的造车新势力们:蔚来裁员、奇点被偷窃、拜腾解散
从上面的例子中我们可以看出,同样的描述文本,有可能会属于多个事件类型。比如上面的在硅谷镀金失败的造车新势力们:蔚来裁员、奇点被偷窃、拜腾解散
,该句话中包含了组织关系-裁员
和组织关系-解散
两个事件类型。 该数据集中的训练集一共有11958个样本,65个事件类型,我们对该训练集进行简单的数据分析,来看看多事件类型的个数和占比,以及每个事件类型的数量。数据分析的脚本如下:
# -*- coding: utf-8 -*-
# author: Jclian91
# place: Pudong Shanghai
# time: 2020-04-09 21:31
from collections import defaultdict
from pprint import pprint
with open("./data/multi-classification-train.txt", "r", encoding="utf-8") as f:
content = [_.strip() for _ in f.readlines()]
# 每个事件类型的数量统计
event_type_count_dict = defaultdict(int)
# 多事件类型数量
multi_event_type_cnt = 0
for line in content:
# 事件类型
event_types = line.split(" ", maxsplit=1)[0]
# 如果|在事件类型中,则为多事件类型
if "|" in event_types:
multi_event_type_cnt += 1
# 对应的每个事件类型数量加1
for event_type in event_types.split("|"):
event_type_count_dict[event_type] += 1
# 输出结果
print("多事件类型的样本共有%d个,占比为%.4f。" %(multi_event_type_cnt, multi_event_type_cnt/len(content)))
pprint(event_type_count_dict)
输出结果如下:
多事件类型的样本共有1121个,占比为0.0937。
defaultdict(<class 'int'>,
{'交往-会见': 98,
'交往-感谢': 63,
'交往-探班': 69,
'交往-点赞': 95,
'交往-道歉': 149,
'产品行为-上映': 286,
'产品行为-下架': 188,
'产品行为-发布': 1196,
'产品行为-召回': 287,
'产品行为-获奖': 139,
'人生-产子/女': 106,
'人生-出轨': 32,
'人生-分手': 118,
'人生-失联': 105,
'人生-婚礼': 59,
'人生-庆生': 133,
'人生-怀孕': 65,
'人生-死亡': 811,
'人生-求婚': 76,
'人生-离婚': 268,
'人生-结婚': 294,
'人生-订婚': 62,
'司法行为-举报': 98,
'司法行为-入狱': 155,
'司法行为-开庭': 105,
'司法行为-拘捕': 712,
'司法行为-立案': 82,
'司法行为-约谈': 266,
'司法行为-罚款': 224,
'司法行为-起诉': 174,
'灾害/意外-地震': 119,
'灾害/意外-坍/垮塌': 80,
'灾害/意外-坠机': 104,
'灾害/意外-洪灾': 48,
'灾害/意外-爆炸': 73,
'灾害/意外-袭击': 117,
'灾害/意外-起火': 204,
'灾害/意外-车祸': 286,
'竞赛行为-夺冠': 430,
'竞赛行为-晋级': 302,
'竞赛行为-禁赛': 135,
'竞赛行为-胜负': 1663,
'竞赛行为-退役': 95,
'竞赛行为-退赛': 141,
'组织关系-停职': 87,
'组织关系-加盟': 335,
'组织关系-裁员': 142,
'组织关系-解散': 81,
'组织关系-解约': 45,
'组织关系-解雇': 93,
'组织关系-辞/离职': 580,
'组织关系-退出': 183,
'组织行为-开幕': 251,
'组织行为-游行': 73,
'组织行为-罢工': 63,
'组织行为-闭幕': 59,
'财经/交易-上市': 51,
'财经/交易-出售/收购': 181,
'财经/交易-加息': 24,
'财经/交易-涨价': 58,
'财经/交易-涨停': 219,
'财经/交易-融资': 116,
'财经/交易-跌停': 102,
'财经/交易-降价': 78,
'财经/交易-降息': 28})
模型训练
我们利用sklearn模块中的MultiLabelBinarizer进行多标签编码,如果文本所对应的事件类型存在,则将该位置的元素置为1,否则为0。因此,y值为65维的向量,其中1个或多个为1,是该文本(x值)对应一个或多个事件类型。 我们采用ALBERT对文本进行特征提取,最大文本长度为200,采用的深度学习模型如下: