1 Star 0 Fork 0

liuyaox / text_classification

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

Text Classification

基于Keras的15种模型:TextCNN, TextRNN, TextDPCNN, TextRCNN, TextHAN, TextBert等及其变种

支持5类特征及其组合:word-level, char-level, 结构化特征(TFIDF, LSA), Context特征(word-left, word-right, char-left, char-right), sentence-level

支持4种分类任务:单标签二分类,单标签多分类,多标签二分类,多标签多分类

Task & Data

任务描述:给定一个关于手机的用户提问,判断用户关注的是手机哪些Labels。

Labels: System, Function, Battery, Appearance, Network, Photo, Accessory, Purchase, Quality, Hardware, Contrast

已标注数据集共有30,000,以下为示例:

1573355016134

所以,任务类型:多标签二分类(Multi-label Binary Classification)任务,共有11个Labels,每个Label有2种取值(关注,不关注)。

虽然数据集是关于多标签二分类任务的,但本项目代码适用于4种分类任务中的任何1种,只取简单修改Config.py文件即可,基模型定义文件BasicModel.py会自动处理。

附录1:Config.py和BasicModel.py中关于任务类型的配置和处理代码

# Config.py
self.task = 'multilabel'
self.token_level = 'word'       # word: word粒度  char: char粒度  both: word+char粒度
self.N_CLASSES = 11             # 标签/类别数量

# BasicModel.py
# 任务类型决定了类别数量、激活函数、损失函数和评估指标
if config.task == 'binary':                # 单标签二分类
    self.n_classes =  1
    self.activation = 'sigmoid'
    self.loss = 'binary_crossentropy'
    self.metrics = ['accuracy']
elif config.task == 'categorical':         # 单标签多分类
    self.n_classes = config.N_CLASSES
    self.activation = 'softmax'
    self.loss = 'categorical_crossentropy'
    self.metrics = ['accuracy']
elif config.task == 'multilabel':          # 多标签二分类(多标签多分类需转化为多标签二分类)
    self.n_classes = config.N_CLASSES
    self.activation = 'sigmoid'
    self.loss = 'binary_crossentropy'
    self.metrics = ['accuracy']

附录2:4种分类任务及其处理方法

  • a. 单标签二分类

    输出为Dense(1, activation='sigmoid'),应用时1个概率值判断其与阈值大小

  • b. 单标签N分类

    输出为Dense(N, activation='softmax'),应用时N个概率值取Top1

  • c. M标签二分类

    • c.1 一个输出:输出为Dense(M, activation=‘sigmoid’),应用时M个概率值取TopK或与阈值判断大小
    • c.2 一个输出:问题转化为M分类,类似于b,模型输出结构同b,应用时方法同c.1
  • d. M标签N分类

    • d.1 一个输出:问题转化为MN标签二分类,同c.1
    • d.2 一个输出:问题转化为MN分类,同c.2
    • d.3 M个输出:每个输出都是b,模型输出结构、应用时方法都同b 待尝试

备注:本项目使用的处理方法是c.1

Requirement

Python 3.6.5

Keras 2.2.4

Numpy 1.16.3

Pandas 0.23.0

SciPy 1.1.0

Sklearn 0.21.3

Data Preprocessing

数据预处理环节流程步骤如下图所示:

1573364046216

数据清洗和准备

文件:DataPreprocessing.py

内容:简单而通用的功能,如标注数据处理,分词,分字,分句子,过滤停用词,处理原始Labels

Embedding相关

文件:Embedding.py

内容:自己训练Word Embedding,读取公开训练的Word Embedding,支持word+char两种粒度

Vocabulary相关

文件:Vocabulary.py

内容:

生成词汇表,支持低频高频词过滤

基于Embedding生成<word, idx, vector>三者之间的映射字典

生成Embedding Layer初始化权重

基于映射字典的向量化编码工具(支持截断、补零、including和excluding)

以上功能支持word+char两种粒度

结构化特征

文件:FeatureStructured.py

内容:生成TFIDF特征和LSA特征,支持word+char两种粒度,后续会增加支持LSI, LDA等其他特征

特征选择

文件:TokenSelection.py

内容:基于卡方统计值等过滤词和字,项目暂未使用

数据编码

文件 :ModelTrain.py

内容:使用向量化编码工具和MultiLabelBinarizer对特征和Label进行编码

数据增强

文件 :DataAugmentation.py

内容:通过Shuffle和Random Drop进行数据增强,项目暂未使用

Model

使用了多个Model,各Model结构关系如下图所示:

1573366328001

使用类继承方式实现三层类定义

  • BasicModel: 所有模型基类

    实现3种Metrics

  • BasicDeepModel: 深度学习模型基类

    通用Layers创建

    绘制Loss和Metrics

    Embedding冻结和解冻

    模型训练和评估(支持CV)

    学习率Schedular

  • BasicStatModel: 传统模型基类

    暂未实现

实现6大类模型(绿色):共15个模型

  • TextCNN:标配和基础

  • TextRNN:同上,可玩的地方更多

  • TextRCNN:结合CNN和RNN的优点

  • TextDPCNN:受ResNet启发,结合RNN+CNN

  • TextHAN:使用了层次注意力机制

  • TextBert:在TextGRU基础上把输入改为Bert编码的向量

  • 此外,还有5大类待实现模型(灰色)

三层类模型+全局Config的便捷之处

  • 支持所有分类任务:二分类,多分类,多标签二分类,多标签多分类

  • 支持各种输入组合:

    [word, char, word-structure, char-structure]中任意的4选1,4选2,4选3,4选4

    另外对于一些特殊模型,支持特殊输入,如TextRCNN模型的Context特征(word-left, word-right, char-left, char-right),以及TextHAN模型的Sentence-level特征

  • 模型训练评估支持KFold,支持6种Finetuning方式

  • 绝大多数模型支持Attention,绝大多数模型支持丰富的参数配置

Train & Evaluation

Train

Step1: 运行DataPreprocessing.py,基于已标注数据生成训练数据并保存本地

Step2: 运行Embedding.py,自己训练Embedding,读取公开训练的Embedding,支持char+word两种粒度

Step3: 运行Vocabulary.py,生成词汇表,基于Embedding生成映射字典,生成Embedding Layer初始化权重矩阵等,支持char+word两种粒度

Step4: 运行FeatureStructured.py,生成TFIDF特征和LSA特征,支持word+char两种粒度

Step5: 运行ModelTrain.py,项目全流程,包括:数据准备、Token筛选、特征和Label编码、划分Train/Test、环境配置、模型生成、模型训练和评估、模型持久化,详见脚本注释。

运行脚本:python3 ModelTrain.py

在运行脚本之前,先修改脚本里的配置项,内容如下:

# 根据实际情况修改,也可直接在Config.py里修改,推荐前者
config.n_gpus = 1
config.token_level = 'word'		# 只使用word-level特征,不使用char-level
config.structured = 'none'		# 不使用结构化特征
config.bert_flag = False		# 不使用Bert编码的输入向量

Evaluation

15个模型的评估结果如下表所示:

1573368628525

备注:模型并未进行精细化调参,大多是默认配置和参数,效果仅供参考。

从评估结果中可得出以下结论:

同一模型内

  • word+char相比word,效果明显有提升

  • word+char+structured相比word+char,效果提升不明显,一些情况下反而会下降

不同模型间

  • TextCNN训练最快,Precision和F1值相对也较高,可作为一个强有力的Baseline

  • TextRNN训练很慢,效果不是特别好,可能是因为训练数据很多是短文本

  • 各模型之间效果差不多(全是默认参数,没时间做精细化调参)

  • 输入改为Bert编码向量后效果提升比较明显,简单的模型(TextGRU)就得到了最好的F1值,后续值得好好研究

  • TextHAN比较给力,取到了最高的Precision,后续值得好好研究

Conclusion

  1. 一个脚本只干一件事情,一件事情只在一个脚本里干,各脚本解耦,各功能独立,互相之间只通过持久化和Config共享信息

  2. 充分利用类和继承以及闭包,相同功能不要重复定义,也不要到处粘贴复制,相似的功能通过闭包来实现

  3. Vocabulary及相关映射字典、Embedding权重,封装整合为一个class,统一管理

  4. 调试便捷化+逻辑清晰化

    a. 训练和应用数据封装进字典,单输入和多输入使用无差别,字典key对应模型搭建时Input的参数name

    b. 动态搭建模型,使其无缝支持多种输入及其组合

    方法:通用方法位于父类BasicDeepModel,各子类模型分为模型主体和模型结尾2部分,模型核心的纯粹的结构位于模型主体,根据输入不同,进行配置和组装,然后接入模型结尾

    c. 不同类模型,先选择最简单的模型如TextCNN,深入研究经验和Tricks,然后复制到别的模型

    d. 同一类模型,先搭建并跑通最简单的模型,随后基于评估效果,逐渐加深加宽

  5. 模型组件

    a. CNN+RNN是标配,CNN提取关键词,RNN适合前几层,提取依赖信息,Attention和MaxPooling可突出关键特征

    b. Capsule可代替CNN,有时效果好于CNN

    c. 有条件就使用Bert

Reference

Code

Libray

  • kashgari : NLP框架,超级傻瓜,超级Cutting Edge

  • hyperas : Keras超参数优化工具

  • sk-multilearn : Sklearn生态下的多标签分类工具

Article

空文件

简介

Text Classification using 15 Deep Learning Models with both Multi-Label and Single-Label Task. 展开 收起
Python
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Python
1
https://gitee.com/liuyaox/text_classification.git
git@gitee.com:liuyaox/text_classification.git
liuyaox
text_classification
text_classification
master

搜索帮助