借助kaggle比赛 https://www.kaggle.com/c/jigsaw-unintended-bias-in-toxicity-classification/overview 做些文本分类的总结
此次介绍文本分类领域经典模型textCNN,因为结构简单,效果好,提供keras和tensorflow代码供学习
相关论文:https://arxiv.org/abs/1408.5882
相关细节
1. 数据预处理部分:比赛是多分类问题,需要判断文本中的评论是否是有毒评论(即带有脏话、歧视性的字词),主要步骤如下
-- 分词:对于英文文本分类也需要分词,去掉一些停用词,大写转小写,去掉无意义的符号,去掉一些高频低频词,中文也如此
-- 建立词典以及单词索引:建立词典就是统计文本中出现多少了单词,然后为每个单词编码一个唯一的索引号,便于查找。如果对以上词典建立单词索引,结果如下图示意:
-- 将训练文本用单词索引好表示,对于不同长度的文本,一般都是通过观察文本长度分布来设置合适的最大长度,例如本赛题设置为250,不足的要补全,多余的要剔除,只保留最高频的词索引。keras中相关的接口函数为Tokenizer、pad_sequences等
2. TextCNN结构
TextCNN的结构比较简单,输入数据首先通过一个embedding layer,得到输入语句的embedding表示,然后通过一个convolution layer,提取语句的特征,最后通过一个fully connected layer得到最终的输出,整个模型的结构如下图:
注意上图,传统图像处理中的卷积核一般都是正方形的,比如(3,3),然后在整张image上沿宽和高进行卷积操作。但是nlp中的"image"是词矩阵,比如n个words,每个word用200维的vector表示的话,这个”image”就是n*200的矩阵,卷积核只在高度上已经滑动,在宽度上和word vector的维度一致(=200),也就是说每次窗口滑动过的位置都是完整的单词,不会将几个单词的一部分“vector”进行卷积,这也保证了word作为语言中最小粒度的合理性。
由于卷积核和word embedding的宽度一致,一个卷积核对于一个sentence,卷积后得到的结果是一个vector, shape=(sentence_len - filter_window + 1, 1),那么,在max-pooling后得到的就是一个Scalar。所以,这点也是和图像卷积的不同之处,需要注意一下
正是由于max-pooling后只是得到一个scalar,在nlp中,会实施多个filter_window_size(比如3,4,5个words的宽度分别作为卷积的窗口大小),每个window_size又有num_filters个(比如64个)卷积核。一个卷积核得到的只是一个scalar太孤单了,智慧的人们就将相同window_size卷积出来的num_filter个scalar组合在一起,组成这个window_size下的feature_vector。
最后再将所有window_size下的feature_vector也组合成一个single vector,作为最后一层softmax的输入。
(重要的事情说三遍:一个卷积核对于一个句子,convolution后得到的是一个vector;max-pooling后,得到的是一个scalar。)
3. 模型参数:
a. 构建模型的基本参数:
filter windows:[3,4,5]
filter maps:100 for each filter window
dropout rate:0.5
l2 constraint:3
randomly select:10% of training data as dev set(early stopping)
word2vec(google news) as initial input, dim = 300
sentence of length: n, padding where necessary
number of target classes
dataset size
vocabulary size
b. 训练模型参数设置
batch size: 50
shuffuled mini batch
optimizer:Adam、SGD、Adadelta and so on...
Test method: standard train/test split ot CV
c. Dropout注意事项:正则是解决过拟合的问题,在最后一层softmax的时候是full-connected layer,因此容易产生过拟合。
策略就是在:
在训练阶段,对max-pooling layer的输出实行一些dropout,以概率p激活,激活的部分传递给softmax层。
在测试阶段,w已经学好了,但是不能直接用于unseen sentences,要乘以p之后再用,这个阶段没有dropout了全部输出给softmax层。
d. Embedding Layer
# Embedding layer
with tf.device('/cpu:0'),tf.name_scope("embedding"):
w = tf.Variable(
tf.random_uniform([vocab_size,embedding_size],-1.0,1.0),name='w')
self.embedded_chars = tf.nn.embedding_lookup(w,self.input_x)
self.embedded_chars_expanded = tf.expand_dims(self.embedded_chars, -1)
其他模型细节可以参考本文末尾的链接
参考链接:
1. textCNN细节解释:https://blog.csdn.net/accumulate_zhang/article/details/78504637
2. textCNN训练预测版本:https://blog.csdn.net/u012762419/article/details/79561441
3. github tensorflow base版本:https://github.com/dennybritz/cnn-text-classification-tf/blob/master/text_cnn.py
4. 完整tensorflow 版本:https://github.com/brightmart/text_classification/tree/master/a02_TextCNN