在上一篇文章中,我们获取了分词的向量表达,接下来要考虑怎么样构建模型。在这一部分,我将分别按普通的机器学习分类器和稍复杂的神经网络TextCNN模型两个部分来进行功能的实现。关于上一篇文章的详细内容请查看下面的链接。
不忘初心:最全NLP中文文本分类实践(上)——中文分词获取和Word2Vec模型构建zhuanlan.zhihu.com1 SVM实现
我们确实拥有了词的向量表达,可是,每个文章都包含不同数量的单词,我们怎么样用训练出来的词向量表示不同的文章呢?在这里,我用的是计算平均词向量来表示文档的方法。这其实挺好理解的,就是文章内包含的所有词的向量相加再取平均,这样,我们就可以得到一个和词向量维度相同的指示文章信息的向量。
import
计算平均向量的函数已经写好了,下面我们就把他应用到我们预先保存好以文章形式保存的分词列表上。
w2v_model
接下来,利用GridSearchCV来找到设置条件下f1_macro最高的模型。
from
在我的测试中,我得到的模型效果最好的参数是{'C': 10, 'gamma': 1}。将这些参数重新设置训练并保存模型。
from
最终,这个SVM模型我得到了89.48%的accuracy和87.42%的macro f1。我们把confusion matrix绘制一下。
import
2 TextCNN实现
除了简单的SVM等机器学习分类器,我们当然要尝试构建一下神经网络。虽然CNN被广泛应用于图像处理之中,但是在文本处理里也有其用武之地。下面我们将构建TextCNN模型实现分类任务。 首先,我们先要对word2vec模型进行预处理。TextCNN中的Embedding层需要我们把分词转化成index,因此我们把模型中的词转化成一个字典以[word : index]保存起来,方便日后的处理。
#导入word2vec模型并进行预处理
同样地,我们依然面临着与构建SVM时相同的问题:怎么处理文章长度的不同。在此,我们考虑截断的解决方法,即预先规定一个长度,不足则在后面补零,超出则舍去后面全部内容,以此来达到长度一致的目的。
from
接下来,我们读取文件,将文章的分词转化成index的形式。训练集每个文章长度,即所包含单词的数量分布如下图所示。
在本次实践过程中,我们将截断长度设置为1000。
from
数据已经加载并处理完毕,下面我们可以开始构建TextCNN模型了。
from
模型构建完毕,下面继续运行该模型进行训练
def
此时模型也已经训练完了,我们用它来验证测试集,看看其表现如何。
import
最终,我们的TextCNN只达到了80%左右的macro f1。这相比SVM可以说差的很多。
3 小结
本文利用SVM和TextCNN模型对中文文本分类任务进行实践。通过比较,我们发现相较于结构更加复杂训练更“深”的TextCNN,SVM分类器的表现反而更好。在TextCNN上,模型呈现出过拟合的趋势,即使经过多次调参,验证集在最多在达到百分之九十左右时就基本上没有提升了,但是训练集甚至可以达到99%之多。此外,History类别在两个分类器下的表现都是较差,这在TextCNN上尤为明显。
针对于这样的现象,我认为其中一个原因可能是数据的规模还没有这么大,利用SVM已经可以呈现出不错的效果,并不需要对它来说过于复杂的神经网络进行训练。还有一个原因,恐怕是特征工程做的不够,即词向量的模型还不够完善。之前看到一个分析说,特征工程决定了之后模型表现的上限,而模型的选择调参等决定了你能多大程度逼近这个上限。因此,特征工程不足也是模型表现如此的一个合理推测。
下一节,我将利用模型融合,尝试去提升模型的表现和各项指标。感谢支持,希望多多关注!