300万知乎多标签文本分类任务经验分享(附源码)

2023-05-16

点击有惊喜


七月,酷暑难耐,认识的几位同学参加知乎看山杯,均取得不错的排名。当时天池AI医疗大赛初赛结束,官方正在为复赛进行平台调试,复赛时间一拖再拖。看着几位同学在比赛中排名都还很不错,于是决定抽空试一试。结果一发不可收拾,又找了两个同学一起组队(队伍init)以至于整个暑假都投入到这个比赛之中,并最终以一定的优势夺得第一名。

比赛介绍

这是一个文本多分类的问题:目标是“参赛者根据知乎给出的问题及话题标签的绑定关系的训练数据,训练出对未标注数据自动标注的模型”。通俗点讲就是:当用户在知乎上提问题时,程序要能够根据问题的内容自动为其添加话题标签。一个问题可能对应着多个话题标签,如下图所示。

5c8a8221dec989b20d1b6222f1f735d3b4d61704

这是一个文本多分类,多label的分类问题(一个样本可能属于多个类别)。总共有300万条问题-话题对,超过2亿词,4亿字,共1999个类别。

1.1 数据介绍

参考 https://biendata.com/competition/zhihu/data/

https://biendata.com/competition/zhihu/rules/?next_url=%2Fcompetition%2Fzhihu%2Fdata%2F

总的来说就是:

  • 数据经过脱敏处理,看到的不是“如何评价2017知乎看山杯机器学习比赛”,而是“w2w34w234w54w909w2343w1"这种经过映射的词的形式,或者是“c13c44c4c5642c782c934c02c2309c42c13c234c97c8425c98c4c340”这种经过映射的字的形式。
  • 因为词和字经过脱敏处理,所以无法使用第三方的词向量,官方特地提供了预训练好的词向量,即char_embedding.txt和word_embedding.txt ,都是256 维。
  • 主办方提供了1999个类别的描述和类别之间的父子关系(比如机器学习的父话题是人工智能,统计学和计算机科学),但这个知识没有用上。
  • 训练集包含300万条问题的标题(title),问题的描述(description)和问题的话题(topic)
  • 测试集包含21万条问题的标题(title),问题的描述(description),需要给出最有可能的5个话题(topic)

1.2 数据处理

数据处理主要包括两部分:

  • char_embedding.txt 和 word_embedding.txt 转为numpy格式,这个很简单,直接使用word2vec的python工具即可
  • 对于不同长度的问题文本,pad和截断成一样长度的(利用pad_sequence 函数,也可以自己写代码pad)。太短的就补空格,太长的就截断。操作图示如下:

1a1ccf79ed43aa73da0251aa44aa6a872b51dbb2

1.3 数据增强

文本中数据增强不太常见,这里我们使用了shuffle和drop两种数据增强,前者打乱词顺序,后者随机的删除掉某些词。效果举例如图:

5c71e56ac5231eef71cf8d9eb698ec934349a9cc

1.4 评价指标


每个预测样本,提供最有可能的五个话题标签,计算加权后的准确率和召回率,再计算F1值。注意准确率是加权累加的,意味着越靠前的正确预测对分数贡献越大,同时也意味着准确率可能高于1,但是F1值计算的时候分子没有乘以2,所以0.5是很难达到的。

8ab60d6a255f822edd8bb9d6499a5ada241d3185


模型介绍

建议大家先阅读这篇文章,了解文本多分类问题几个常用模型:用深度学习(CNN RNN Attention)解决大规模文本分类问题

https://zhuanlan.zhihu.com/p/25928551

2.1 通用模型结构

文本分类的模型很多,这次比赛中用到的模型基本上都遵循以下的架构:

8f0f1cad92843c03c73f84d1d9cab99e9dd37770

基本思路就是,词(或者字)经过embedding层之后,利用CNN/RNN等结构,提取局部信息、全局信息或上下文信息,利用分类器进行分类,分类器的是由两层全连接层组成的。

在开始介绍每个模型之前,这里先下几个结论:

  • 如果你的模型分数不够高,试着把模型变得更深更宽更复杂
  • 当模型复杂到一定程度的时候,不同模型的分数差距很小
  • 当模型复杂达到一定程度,继续变复杂难以继续提升模型的分数

2.2 TextCNN

这是最经典的文本分类模型,这里就不细说了,模型架构如下图:

8d123cd95c036b105eb9e905f24f00b1111a587e

和原始的论文的区别就在于:

  • 使用两层卷积
  • 使用更多的卷积核,更多尺度的卷积核
  • 使用了BatchNorm
  • 分类的时候使用了两层的全连接

总之就是更深,更复杂。不过卷积核的尺寸设计的不够合理,导致感受野差距过大。

2.3 TextRNN

没找到论文,我就凭感觉实现了一下:

4979daaa7d2bf30f9022884e2c4cc3fcced2a84b

相比于其他人的做法,这里的不同点在于:

  • 使用了两层的双向LSTM。
  • 分类的时候不是只使用最后一个隐藏元的输出,而是把所有隐藏元的输出做K-MaxPooling再分类。

2.4 TextRCNN

参考原论文的实现,和RNN类似,也是两层双向LSTM,但是需要和Embedding层的输出Concat(类似于resnet的shortcut直连)。

7827ef4f8023fa079868d5e164a81d5f4df4dc8b

2.5 TextInception

这个是我自己提出来的,参照TextCNN的思想(多尺度卷积核),模仿Inception的结构设计出来的,一层的Inception结构如下图所示,比赛中用了两层的Inception结构,最深有4层卷积,比TextCNN更深。

db30f38b1fbf858203991a23887e2a7b0a2d6ebe

2.6 训练方法

要点:

  • 基于词和基于字的模型要分开训,然后融合,一起训的效果不好
  • 使用官方给的word-embedding.txt和char-embedding.txt初始化Embedding层的权重
  • 刚开始训练的时候Embedding层的学习率为0,其它层的学习率为1e-3,采用Adam优化器(一开始的时候卷积层都是随机初始化的,反向传播得到的Embedding层的梯度受到卷积层的影响,相当于噪声)
  • 训练1-2个epoch之后,Embedding层的学习率设为2e-4
  • 每个epoch或者半个epoch统计一次在验证集的分数
  • 如果分数上升,保存模型,并记下保存路径
  • 如果分数下降,加载上一个模型的保存路径,并降低学习率为一半(重新初始化优化器,清空动量信息,而不是只修改学习率----使用PyTorch的话新建一个新优化器即可)

2.7 各个模型分数计算

训练的时候,每个模型要么只训练基于词(word)的模型,要么只训练基于字(char)的模型。各个模型的分数都差不多,这里不再单独列出来了,只区分训练的模型的类型和数据增强与否。

1f9fc607fd3b6eddea7d35e21526837f4cab5a90

可以看出来:

  • 基于词的模型效果远远好于基于字的(说明中文分词很有必要);
  • 数据增强对基于词(word)的模型有一定的提升,但是对于基于字(char)的模型主要是起到副作用;
  • 各个模型之间的分数差距不大。

2.8 模型融合

像这种模型比较简单,数据量相对比较小的比赛,模型融合是比赛获胜的关键。

在这里,我只使用到了最简单的模型融合方法-----概率等权重融合。对于每个样本,单模型会给出一个1999维的向量,代表着这个模型属于1999个话题的概率。融合的方式就是把每一个模型输出的向量直接相加,然后选择概率最大的5个话题提交。结构如图所示:

156e3e9d9b1ad878ef854cfe1ef9f7b82799fa91

下面我们再来看看两个模型融合的分数:

e1b2d9a5e0b135bcd8a607b7c80e60de4aebfdb0

第一列的对比模型采用的是RNN(不采用数据增强,使用word作为训练数据),第二列是四个不同的模型(不同的结构,或者是不同的数据)。

我们可以得出以下几个结论:

  • 从第一行和第二行的对比之中我们可以看出,模型差异越大提升越多(RNN和RCNN比较相似,因为他们底层都采用了双向LSTM提取特征),虽然RCNN的分数比Inception要高,Inception对模型融合的提升更大。
  • 从第一行和第四行的对比之中我们可以看出,数据的差异越大,融合的提升越多,虽然基于字(char)训练的模型分数比较低,但是和基于词训练的模型进行融合,还是能有极大的提升。
  • 采用数据增强,有助于提升数据的差异性,对模型融合的提升帮助也很大。

总结: 差异性越大,模型融合效果越好。没有差异性,创造条件也要制造差异性。

另外模型融合还有个规律:越往上越难提升,有些模型在你分数较低的时候,对融合提升很明显,当你分数较高的时候就没什么帮助,甚至会有干扰

2.9 MultiModel

其实模型融合的方式,我们换一种角度考虑,其实就是一个很大的模型,每一个分支就像多通道的TextCNN一样。那么我们能不能训练一个超级大的模型?答案是可以的,但是效果往往很差。因为模型过于复杂,太难以训练。这里我尝试了两种改进的方法。

第一种方法,利用预训练好的单模型初始化复杂模型的某一部分参数,模型架构如图所示:

8fc9041a9e13342d67c5c650cb8bd9a1a08fdce0

但是这种做法会带来一个问题: 模型过拟合很严重,难以学习到新的东西。因为单模型在训练集上的分数都接近0.5,已经逼近理论上的极限分数,这时候很难接着学习到新的内容。这里采取的应对策略是采用较高的初始学习率,强行把模型从过拟合点拉出来,使得模型在训练集上的分数迅速降低到0.4左右,然后再降低学习率,缓慢学习,提升模型的分数。

第二种做法是修改预训练模型的embedding矩阵为官方给的embedding权重。这样共享embedding的做法,能够一定程度上抑制模型过拟合,减少参数量。虽然CNN/RNN等模型的参数过拟合,但是由于相对应的embedding没有过拟合,所以模型一开始分数就会下降许多,然后再缓慢提升。这种做法更优。在最后提交模型复现成绩的时候,我只提交了七个这种模型,里面包含着不同子模型的组合,一般包含3-4个子模型。这种方式生成的权重文件也比较小(600M-700M左右),上传到网盘相对来说更方便。


点击有惊喜



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

300万知乎多标签文本分类任务经验分享(附源码) 的相关文章

  • python计算圆的面积

    提示 xff1a 笔记希望对你有帮助 文章目录 前言1 事先准备2 代码书写3 代码运行总结 前言 提示 xff1a 本次我们的代码的是通过pycharm实现的 下面让我们使用python对我们的圆的面积以及周长进行一个简单的计算 1 事先
  • Windows环境下edge浏览器点击下载没有反应

    项目场景 xff1a 系统 xff1a windows 11 家庭中文版 浏览器 xff1a Microsoft Edge版本 104 0 1293 54 正式版本 64 位 问题描述 edge浏览器点击下载没有反应 原因分析 xff1a
  • python怎么查看安装了哪些库

    这里写目录标题 前言方法1方法2 前言 有时候我们在使用python的时候 xff0c 想知道自己安装哪些了第三方库以及第三方库的版本 xff0c 下面来介绍一下方法 方法1 我们可以通过命令提示符输入相关的命令进行查看 xff0c 命令如
  • python 安装dmPython

    文章目录 前言下载达梦数据库安装dmPython模块引用模块解决方法 代码演示 前言 使用python连接我们的连接达梦数据库 下载达梦数据库 达梦数据库的官网链接 达梦数据库的下载链接 安装dmPython模块 找到达梦数据库的安装目录
  • python requests cookie的获取和使用

    文章目录 前言一 cookie是什么 xff1f 二 使用步骤开始代码实现会话是什么然后写入我们的账号信息 使用session访问登陆账号的url获取账号的书架上的数据 完整的代码补充比较暴力的获取方式 前言 我们在使用爬虫中会用到很多账号
  • pyspark报错 org.apache.spark.SparkException: Python worker failed to connect back.

    项目场景 xff1a 使用pycharm工具将spark分析完的数据存储到MySQL数据库中 问题描述 在程序执行过程中发生以下报错 xff1a org span class token punctuation span apache sp
  • python的tkinter(图形用户界面)

    目录标题 什么是图形用户界面 xff08 GUI xff09 Tinter函数和参数说明 xff08 常用 xff09 Lable 标签 xff1a 效果Button 按钮 效果 Entry 文本框 效果 Text xff08 多行文本框
  • K8s配置文档

    xff01 xff01 xff01 xff01 xff01 xff01 如果看不懂文档点击进入视频k8s配置视频 xff01 xff01 xff01 xff01 xff01 xff01 xff01 xff01 xff01 xff01 xff
  • 安装spark

    安装spark 上传安装包文件 spark 2 1 1 bin hadoop2 7 解压安装包 span class token function tar span xvf spark 2 1 1 bin hadoop2 7 C opt m
  • 人大金仓数据库的简单巡查

    人大金仓的简单巡查 查询人大金仓的版本 sys ctl V sys ctl version span class token comment 在ksql命令行工具中查询数据库版本 span span class token keyword
  • 人大金仓数据库的单表查询

    人大金仓数据库的单表查询 查看表的内容 span class token comment 查询数据库的创建语句 span d exam span class token punctuation span course span class
  • JWT和Security 登录权限判断和token访问和让token失效

    文章目录 Spring SecurityJWT无状态的单点登录流程用到的方法configure HttpSecurity http 登录 authenticationSuccessHandler loadUserByUsername 通过t
  • Flutter Container设置 width 无效

    文章目录 布局组件和容器组件BoxContraints机制布局组件 Row Column解决办法参考 布局组件和容器组件 容器类Widget和布局类Widget都作用于其子Widget xff0c 不同的是 xff1a 布局类Widget一

随机推荐

  • Flutter 滚动距离来设置TabBar的位置,点击TabBar滚动的到指定的位置

    文章目录 效果gif定义属性每个组件设置Key获取控件的距离顶部的位置设置监听设置TabBar 点击getY源码 感觉有用的话 xff0c star一下如果想一起学习进步 QQ群766903559 效果gif 定义属性 ScrollCont
  • solidity create2 学习

    文章目录 saltcreatecreate2address this clone factoryshr shl使用 两个值生成唯一的值 xff0c 通过唯一值获取对应的两个值 salt nonce 也可以自己生成 create addres
  • Flutter和Native 通信 pigeon

    文章目录 1 pigeon2 定义接口3 定义sh文件 pigeon sh xff08 lib同级目录创建 xff09 4 运行sh文件 pigeon sh 会生成一下文件5 配置6 使用7 IOS xxx plugin h8 XxxPlu
  • flutter调用go

    文章目录 命令引入greeting aar和使用android中使用Flutter2gopluginPlugin kt参考文档 命令 mkdir demo cd demo go mod init demo 编写greeting go go
  • solidity 学习2.批量转账,存入eth。读取数据。

    pragma solidity 0 4 17 import 39 zeppelin solidity contracts token ERC20 StandardToken sol 39 contract BLEOS is Standard
  • 根据图片获取图片中最多的颜色

    根据网络图片获取背景色 xff0c 用Palette 获取出来的颜色总是不对 Palette p 61 Palette from resource generate int defaultColor 61 ContextCompat get
  • flutter-border

    文章目录 Border继承构造方法BorderStyle和BorderSideBorderStyleBorderSide构造方法 BoxShadow构造方法 BoxShape是Code BorderRadius继承CodeRadius xf
  • ubuntu20.04中安装Flatpak,切换数据源

    安装 Flatpak xff1a sudo apt install flatpak 接着 xff0c 使用以下命令添加 Flatpak 数据源 xff1a sudo flatpak remote span class token opera
  • centeros8 图形化界面设置

    基于性能及通用性等因素的考虑 xff0c 阿里云官方提供的公共Linux系统镜像 xff0c 默认不安装图形化桌面组件 通过管理终端连接Linux实例 执行以下命令 xff0c 安装图形桌面的软件包 yum groupinstall 34
  • 定时器周期计算

    对定时器周期公式的总结 xff1a 1 T 61 xff08 arr 43 1 xff09 PSC 43 1 Tck 其中TCK为时钟频率 xff0c PSC为时钟预分频系数 xff0c arr为自动重装载值 f 61 Tck psc 43
  • [已解决 2020年]你的支付授权失败。请核对你的信息并重试,或尝试其他支付方式。请联系你的银行了解更多信息

    博主更多实战教程 xff1a NET WebApi实战教程 微信小程序实战教程 因为苹果政策的调整 xff0c 目前进行开发者计划加入时 xff0c 有两个模式 如果账号本身是在apple developer app中申请的 xff0c 那
  • LPC1768 IIC通信示——PCF8563

    PCF8563与AT24C02一样 xff0c 是典型的IIC通信器件 xff0c 这里就以它为例 xff0c 编写基于LPC1768硬件IIC的通信代码 xff1a 上图是PCF8563各个寄存器地址 xff0c PCF8563的IIC地
  • 程序员笔试题----字符串的操作

    在程序员面试的过程当中 xff0c 很多时候都会问到对字符串的操作 xff0c 其中包括 xff1a 字符串的逆序 xff0c 字符串的最大字串 xff0c 字符串按单词逆序 xff0c 两个字符串的最大公共子串 xff0c 记录字符串中某
  • 如何选择离线数据集成方案 - 全量&增量

    1 前言 我在上一篇中介绍了实时集成与离线集成该怎么选择 xff0c 接着介绍一下离线集成中的增量与全量的选择问题 要设计方案 xff0c 我们先分析一下数据产生的方式 我们把音视频流这种非结构化的数据集成从这里排除出去 xff0c 因为这
  • 使用阿里云PCDN降低内容分发成本

    点击打开链接 阿里云PCDN xff08 P 2P CDN 的 简称 xff09 是基于P2P技术的内容分发 网络 产品 xff0c 相比CDN而言 xff0c PCDN单价较低 xff0c 更适 用 于大流量内容分发 PCDN产品是与传统
  • 机器学习--线性代数基础

    原文地址 数学是计算机技术的基础 xff0c 线性代数是机器学习和深度学习的基础 xff0c 了解数据知识最好的方法我觉得是理解概念 xff0c 数学不只是上学时用来考试的 xff0c 也是工作中必不可少的基础知识 xff0c 实际上有很多
  • Dockerfile小案例(systemctl)

    Dockerfile小案例 xff08 systemctl xff09 文章目录 Dockerfile小案例 xff08 systemctl xff09 Dockerfile制作 xff08 systemctl xff09 镜像 Docke
  • 怎么打造属于自己的天猫精灵

    原文地址 看了天猫精灵的介绍 xff0c 是不是觉得很神奇 xff0c 实际每个程序要都可以打造属于自己的智能家居 可以实现的功能 点歌 最基础的功能了 xff0c 可以将自己喜欢的歌曲下载下来 xff0c 随时点歌定时提醒 提醒自己吃饭
  • 聊一聊数据仓库中的元数据管理系统

    原文地址 一 元数据的定义 按照传统的定义 xff0c 元数据 xff08 Metadata xff09 是关于数据的数据 在数据仓库系统中 xff0c 元数据可以帮助数据仓库管理员和数据仓库的开发人员非常方便地找到他们所关心的数据 xff
  • 300万知乎多标签文本分类任务经验分享(附源码)

    点击有惊喜 七月 xff0c 酷暑难耐 xff0c 认识的几位同学参加知乎看山杯 xff0c 均取得不错的排名 当时天池AI医疗大赛初赛结束 xff0c 官方正在为复赛进行平台调试 xff0c 复赛时间一拖再拖 看着几位同学在比赛中排名都还