七、Contextualized Word Representations:
优点:
动态的单词表示
缺点:
- 存储开销大
- 显著提高下游性能但是计算开销大
- 需要额外的word embedding
- 受词表限制
- 仅能服务于句子和文章级别
3、模型介绍
在做文本分类的过程中,模型的设计其实包括上述介绍的词向量的获得,尽可能希望得到如下的信息
- 词向量可以充分表征文本原来的意思
- 词向量可以表征语义信息
- 模型可以提取样本级别的整体特征表示,然后+Softmax便可以实现分类
3.1 基于静态词向量的网络
为啥使用静态词向量+LSTM前后文无法充分表征语义信息?个人揣测,使用静态词向量的网络通常是在小数据上基于给定任务训练,难以捕捉比较好的语义信息。
3.1.1 FastText
本质上应该属于Word2Vec+单层的网络+H-softmax。
3.1.2 TextCNN
本质上使用Word2Vec+CNN
TextCNN详细过程:
- Embedding:第一层是图中最左边的7乘5的句子矩阵,每行是词向量,维度=5,这个可以类比为图像中的原始像素点。
- Convolution:然后经过 kernel_sizes=(2,3,4) 的一维卷积层,每个kernel_size 有两个输出 channel。
- MaxPolling:第三层是一个1-max pooling层,这样不同长度句子经过pooling层之后都能变成定长的表示。
- FullConnection and Softmax:最后接一层全连接的softmax层,输出每个类别的概率。
3.1.3 TextRNN
3.2 基于动态词向量的网络
为什么使用动态此向量?
word级别到数值向量的映射不足以完全表征上下文的信息,我们希望基于上下文训练对应的词向量表示,即我们希望在句子级别或者更高的级别对文本进行编码。
就好比,我仅使用mlp对图像进行学习不如CNN可以提取空间信息更加有效的意思?
主要的模型有:
GPT、Bert、XLNet等,这部分的技术原理仍旧需要时间来仔细分析,但是我们最终的目的是如何在项目中有效使用,所以做一下简要的介绍。
3.2.1 Bert
BERT是一种预训练语言表示的方法,他将NLP模型的建立分为了两个阶段:Pre-training和fine-tuning。Pre-training是为了在大量文本语料(维基百科)上训练了一个通用的“语言理解”模型,然后用这个模型去执行想做的NLP任务。Fine-training则是在具体的NLP任务上进行相应的微调学习。
Bert模型结构主要是采用了transformer的编码结构,其主要创新点在于其训练方式采用了1)它在训练双向语言模型时以减小的概率把少量的词替成了Mask或者另一个随机的词。感觉其目的在于使模型被迫增加对上下文的记忆。2)增加了一个预测下一句的loss,迫使模型学习到句子之间的关系。
输入表示:
论文的输入表示(input representation)能够在一个token序列中明确地表示单个文本句子或一对文本句子(例如, [Question, Answer])。对于给定token,其输入表示通过对相应的token、segment和position embeddings进行求和来构造。图2是输入表示的直观表示:
关键创新:预训练任务
任务1: Masked LM
为了训练一个深度双向表示(deep bidirectional representation),研究团队采用了一种简单的方法,即随机屏蔽(masking)部分输入token,然后只预测那些被屏蔽的token。
数据生成器将执行以下操作,而不是始终用[MASK]替换所选单词:
- 80%的时间:用[MASK]标记替换单词,例如,my dog is hairy → my dog is [MASK]
- 10%的时间:用一个随机的单词替换该单词,例如,my dog is hairy → my dog is apple
- 10%的时间:保持单词不变,例如,my dog is hairy → my dog is hairy. 这样做的目的是将表示偏向于实际观察到的单词。
任务2:下一句预测
在为了训练一个理解句子的模型关系,预先训练一个二进制化的下一句测任务,这一任务可以从任何单语语料库中生成。具体地说,当选择句子A和B作为预训练样本时,B有50%的可能是A的下一个句子,也有50%的可能是来自语料库的随机句子。
通过采用以上两种预训练方式,使得模型能够具有语义表征性质,在fine-tuning阶段就可以搭连一个NN结构完成文本分类任务。
4、评估指标
- ACC
>>> import numpy as np >>> from sklearn.metrics import accuracy_score >>> y_pred = [0, 2, 1, 3] >>> y_true = [0, 1, 2, 3] >>> accuracy_score(y_true, y_pred) 0.5 >>> accuracy_score(y_true, y_pred, normalize=False)
- Top-K ACC
>>> import numpy as np >>> from sklearn.metrics import top_k_accuracy_score >>> y_true = np.array([0, 1, 2, 2]) >>> y_score = np.array([[0.5, 0.2, 0.2], ... [0.3, 0.4, 0.2], ... [0.2, 0.4, 0.3], ... [0.7, 0.2, 0.1]]) >>> top_k_accuracy_score(y_true, y_score, k=2) 0.75 >>> # Not normalizing gives the number of "correctly" classified samples >>> top_k_accuracy_score(y_true, y_score, k=2, normalize=False)
- F1
>>> from sklearn import metrics >>> y_pred = [0, 1, 0, 0] >>> y_true = [0, 1, 0, 1] >>> metrics.precision_score(y_true, y_pred) 1.0 >>> metrics.recall_score(y_true, y_pred) 0.5 >>> metrics.f1_score(y_true, y_pred) 0.66...
- AUC
ROC曲线,是一个图解,它说明了二值分类器系统在其判别阈值变化时的性能。它是通过在不同的阈值设置下绘制阳性中的真阳性部分(TPR=真阳性率)与阴性中的假阳性部分(FPR=假阳性率)来创建的。TPR也称为敏感性,FPR是1减去特异性或真阴性率。
AUC是ROC曲线下的面积。
from sklearn.metrics import roc_auc_score