0.写在前面
0.1本文配套github:
https://github.com/willinseu/kaggle-Jigsaw-Unintended-Bias-in-Toxicity-Classification-solution
如果你觉得本文对你有帮助,或者有提高,请点一个star以表支持,感谢~
同时与上一篇博文的github项目是对接的:
https://github.com/willinseu/kesci-urdu-sentiment-analysis
0.2 数据集
数据:
https://www.kaggle.com/c/jigsaw-unintended-bias-in-toxicity-classification/data
0.3一些说明
本文要求你具有神经网络,pandas,keras的基础知识。
如果你是一个nlp基础较为薄弱的人,建议先看本文的兄弟篇:
用lstm实现nlp情感分析(roman urdu小语种为例)代码+原理详解,再看本篇(提高篇)
不然会对tokenizer等用法很陌生,而且对整体的nlp思路也会不清晰。
如果你基础扎实,对于各种nlp手法都很熟悉,建议直接去kaggle比赛页阅读相关内容,本文仅是为了帮助一些初学者。
0.4文章截图说明
文中会出现多处jupyter代码截图。截图均来自我的github。如需要请前往文中开头的链接。
0.5 关于原代码
代码大部分来自:https://www.kaggle.com/thousandvoices/simple-lstm?scriptVersionId=12556909
但是其实对于初学者而言,原代码很难看懂,所以这就是我写这篇博客的目的。
并且github中用notebook写了下注释。
1.赛题分析
比赛呢,简单说来还是一个情感分析的二分类问题。但说复杂点了,就是一个多输出的二分类问题。
我们先看一眼这个数据集,再做讨论。
我们这里默认target>0.5的为1,<0.5的为0,这样问题就是一个二分类问题了。
我们在上一篇博文中见到的只有图中的红框。意思很简单,给你一句话,那你就要给我它的输出是0还是1,经典的情感分析问题。
当然了,对于本数据集,你也完全可以忽略掉全部,只看红框,然后搭建网络做判别,我在我的github上也实现了这种初级解法,auc可以达到0.9左右。
1.1只关注红框与关注红+蓝的区别到底是什么?
这其实是一个很重要的问题!!!但是经常有人会说:这不显而易见吗?你用到的数据多了,模型肯定好。feature越多越好木问题的~
请思考的更深入一些。Think Deep.
下面开始我们的分析:
我们可以很明显的发现,你只关注红框,那么数据集你没有完全利用到,蓝框的数据你都没用到。说专业点,你的网络只关注到了1或者0,或者说你只告诉了它是不是toxic,那他的表现自然不能太好。但是如果你告诉网络,这句话的toxic程度为0.8,insult(辱骂)程度为0.7,…那么这句话就真正被网络fit进去了。
或者换句话说,一句话toxic程度是0.6,另一句是0.9,而我们都认为是1。那么其中的差异性就被我们丢失了,所以关于在这一个二分类问题中关注这些连续型变量就是这个目的。所以我们需要把float形式的target加进去。剩下的feature加进去也是一个道理。
所以我们的问题是一个多输出问题,训练集的构造也应该是这样:
x_train = preprocess(train['comment_text'])
y_train = np.where(train['target'] >= 0.5, 1, 0)
y_aux_train = train[['target', 'severe_toxicity', 'obscene', 'identity_attack', 'insult', 'threat']]
x_test = preprocess(test['comment_text'])
1.2代码思路说明
一、预处理阶段
- 文本预处理,去除特殊符号等
- 利用glove/fasttext 进行数据的编码,生成权重矩阵
二、模型构建以及训练
2.文本预处理
在本代码中,我们只进行了简单的处理:
def preprocess(data):
'''
Credit goes to https://www.kaggle.com/gpreda/jigsaw-fast-compact-solution
'''
punct = "/-'?!.,#$%\'()*+-/:;<=>@[\\]^_`{|}~`" + '""“”’' + '∞θ÷α•à−β∅³π‘₹´°£€\×™√²—–&'
def clean_special_chars(text, punct):
for p in