Sentencepiece是google开源的文本Tokenzier工具,其主要原理是利用统计算法,在语料库中生成一个类似分词器的工具,外加可以将词token化的功能;对比开源的分词器,它会将频繁出现的字符串作为词,然后形成词库进行切分,所以它会切分的粒度会更大些。

例如“机器学习领域“这个文本,按jieba会分“机器/学习/领域”,但你想要粒度更大的切分效果,如“机器学习/领域”或者不切分,这样更有利于模型捕捉更多N-gram特征。为实现这个,你可能想到把对应的大粒度词加到词表中就可以解决,但是添加这类词是很消耗人力。然而对于该问题,利用sentencepiece可以得到一定程度解决,甚至能完美解决你的需求。

基于上述的场景,本项目主要探究利用sentencepiece进行文本分类,对比开源的分词器,会有怎样的效果。在实验中,选择的是中文新闻文本数据集,对比的开源分词器选择的是jieba。若想对sentencepiece有更多的了解,可以查看sentencepiece原理与实践。

1 环境

python3
tensorflow2.0
jieba
sentencepiece
numpy

2 数据集及前期处理

本实验同样是使用THUCNews的一个子集进行训练与测试,数据集请自行到THUCTC:一个高效的中文文本分类工具包下载,请遵循数据提供方的开源协议;

文本类别涉及10个类别:categories = [‘体育’, ‘财经’, ‘房产’, ‘家居’, ‘教育’, ‘科技’, ‘时尚’, ‘时政’, ‘游戏’, ‘娱乐’],每个分类6500条数据;

cnews.train.txt: 训练集(500010)
cnews.val.txt: 验证集(500
10)
cnews.test.txt: 测试集(1000*10)

训练所用的数据,可以下载:链接: https://pan.baidu.com/s/1DOgxlY42roBpOKAMKPPKWA, 密码: up9d

其实,本项目是基于词级别的CNN for text classification, 只是这个词一个从jieba切分过来的,一个是sentencepiece训练的模型识别出来的。在预处理过程中,本项目中只是简单的过滤标点符号,数字类型的词,具体code体现在loader.py 文中的 re_han=re.compile(u"([\u4E00-\u9FD5a-zA-Z]+)")。

3 超参数说明

class TextConfig():embedding_size=100    #dimension of word embeddingvocab_size=8000     #number of vocabularyseq_length=600        #max length of sentencenum_filters=128       #number of convolution kernelfilter_sizes=[2,3,4]num_classes=10hidden_unit=128drop_prob=0.5          #droppoutlr= 1e-3               #learning ratenum_epochs=10          #epochsbatch_size=64          #batch_sizespm=True               #use sentencepiecetrain_dir='./data/cnews.train.txt'val_dir='./data/cnews.val.txt'test_dir='./data/cnews.test.txt'vocab_dir='./data/vocab.txt'

在与jieba对比的时, 默认设定的vocab_size=8000, spm参数控制是否use sentencepiece,其他参数都是一致的;./data/vocab.txt是用jieba切分后前8000的高频词;

4 实验对比

(1) 训练和验证准确率对比

模型 train_accuracy val_accuracy test_accuracy
jieba+word2vec+cnn 1.000 0.971 0.9723
jieba+cnn 0.9988 0.9686 0.9706
spm+cnn 0.9972 0.9704 0.9667

(2) 训练中损失变化对比
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NRPZ0yY2-1606111442274)(https://github.com/cjymz886/sentencepiece-text-classification/blob/main/imgs/img_loss.png)]

从训练结果来看,二者相差并不大,利用spm+cnn在验证集上有一定的提升,但在测试集jieba+cnn表现好一些。通过这些微小数据对比,个人觉得利用sentencepiece相对jieba这类正规分词器来说,更容易过拟合些,换个角度来说,它捕捉的特征更多些,但也带来更多噪声特征的影响。

(3) 载入数据集的消耗时间

模型 cost_time(seconds)
jieba+cnn 475
spm+cnn 80

对比jieba分词器,sentencepiece切分效率是它的近6倍,基于这个优势,是可以看出sentencepiece的使用价值的,尤其当处理文档级文本的时候。

(4) 是不是词表越大越好
在与jieba对比中,设定的是8000个高频词,可能有疑问:是不是词表越大效果会越好?对此,本实验在spm+cnn模型下,对比了词表8000,20000,320000(sentencepiece能训练的最大词表),效果如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-62hx3hTi-1606111442275)(https://github.com/cjymz886/sentencepiece-text-classification/blob/main/imgs/img_acc.png)]

可以看出,随着词表增大,在训练集上更早的达到“潜在的最好效果”,而在验证集上的表现越来越差。理论上不是词表越大越好吗,它毕竟降低了未登录词出现的概率。其实,我想是这样的,该新闻数据集的各个label区分度是很高的,也就是说影响每个label的特征都是很明显的,而且这些影响特征都是可用高频词汇组合出来的。如果加大词表,就相当于training过程中,让model学到很多label的噪声特征,导致在验证集上效果降低

还有一个原因:该数据集不论基于字,词,或者加上word2vec词向量,它的train_accuracy都很高;如果一个数据集的train_accuracy较低,增加词表应该会有正向的提升。

(4) spm不同词表下切分效果对比

在训练sentencepiece,可以设定输出词表的大小。本实验训练了8000,20000,320000三个级别的spm model,对比jieba,看看它们切分文本的效果,如下:

模型 text
no_segement 新浪体育讯北京时间4月27日,NBA季后赛首轮洛杉矶湖人主场迎战新奥尔良黄蜂
jieba 新浪\体育讯\北京\时间\4\月\27\日\,\NBA\季后赛\首轮\洛杉矶\湖人\主场\迎战\新奥尔良\黄蜂
spm_8000 \新浪体育讯北京时间\4\月\27\日,\NBA\季后赛\首\轮\洛杉矶\湖人\主场\迎\战\新\奥\尔\良\黄蜂
spm_20000 \新浪体育讯北京时间\4\月\27\日,\NBA\季后赛\首轮\洛杉矶湖人\主场迎战\新\奥尔良\黄蜂
spm_320000 新浪体育讯北京时间\4\月\27\日,\NBA\季后赛首轮\洛杉矶湖人主场迎战新奥尔良黄蜂

对比显示:随着词表增大,spm切分的粒度越来越大;三个spm模型都将“新浪体育讯北京时间”当一个词块,说明语料库中该词块出现的频率很高;在spm_320000模型下,将“洛杉矶湖人主场迎战新奥尔良黄蜂”切在一起,粒度是相当的大,直接是将一句话当成一个词块。

此外,可以看出spm_8000下粒度太细了,很多单字情况,这种情况明显是没有jieba效果好,也就影响了模型的训练,试想:如果在训练spm模型的时候,是不是可以限定下词的长度,只要长度2以上的高频词汇,是不是再去词token化效果会好些。

我之前也尝试:让jieba先切分下,形成词列表,然后再用sentencepiece去训练,这样二者就有种互补的效果,一来减少jieba因为词库的原因导致很多高频词组切开的影响,二来可利用sentencepiece的切分效率。但在实际操作中,并没有实现,不知道是对开源的sentencepiece工具没搞清楚,还是它本事就有这个问题。之前也有朋友遇到同样的问题,也与他探讨过,当目前还是没解决…

5 结语

利用sentencpiece代替分词器进行下游任务,是完全可行的,一来它与正规分词器对比效果是相当的,二来它的切分效率很高,可降低模型在token化消耗的时间,这对在工业上应用是合适的。只是在使用过程中,可调式下词表大小,不宜过高,但也要具体场景具体对比看下,是否有必要把词表加大。此外,如果在领域性很强的任务时,或者在做multi-label任务时,我想sentencpiece带来的效果应该更明显。当然,上述提到的问题,若能解决,会让sentencpiece在中文处理上更有价值。对此感兴趣的朋友,若有啥问题,可与我私下交流~

6 参考

  1. Text classification with CNN and Word2vec
  2. sentencepiece原理与实践
  3. SentencePiece

更多文章可关注笔者公众号:自然语言处理算法与实践

使用Sentencepiece +CNN进行文本分类相关推荐

  1. 使用CNN做文本分类——将图像2维卷积换成1维

    使用CNN做文本分类from __future__ importdivision, print_function, absolute_importimporttensorflow as tfimpor ...

  2. CNN在文本分类的应用(内有代码实现) 论文Convolutional Neural Networks for Sentence Classification

    一.CNN文本分类简介 文本分类是NLP领域的一个重要子任务,文本分类的目标是自动的将文本打上已经定义好的标签,常见的文本分类任务有: 用户评论的情感识别 垃圾邮件过滤 用户查询意图识别 新闻分类 由 ...

  3. 文本分类(下) | 卷积神经网络(CNN)在文本分类上的应用

    正文共3758张图,4张图,预计阅读时间18分钟. 1.简介 原先写过两篇文章,分别介绍了传统机器学习方法在文本分类上的应用以及CNN原理,然后本篇文章结合两篇论文展开,主要讲述下CNN在文本分类上的 ...

  4. 论文复现:用 CNN 进行文本分类

    前一篇文章中我们学习了 CNN 的基础结构,并且知道了它是计算机视觉领域的基础模型,其实 CNN 不仅仅可以用于计算机视觉,还可以用于处理自然语言处理问题,今天就来看看如何用 CNN 处理文本分类任务 ...

  5. linux tf2 中文,tf2+cnn+中文文本分类优化系列(2)

    1 前言 接着上次的tf2+cnn+中文文本分类优化系列(1),本次进行优化:使用多个卷积核进行特征抽取.之前是使用filter_size=2进行2-gram特征的识别,本次使用filter_size ...

  6. 基于CNN中文文本分类实战

    一.前言 之前写过一篇基于循环神经网络(RNN)的情感分类文章,这次我们换种思路,采用卷积神经网络(CNN)来进行文本分类任务.倘若对CNN如何在文本上进行卷积的可以移步博主的快速入门CNN在NLP中 ...

  7. [Python人工智能] 二十一.Word2Vec+CNN中文文本分类详解及与机器学习(RF\DTC\SVM\KNN\NB\LR)分类对比

    从本专栏开始,作者正式研究Python深度学习.神经网络及人工智能相关知识.前一篇文章分享了Keras实现RNN和LSTM的文本分类算法,并与传统的机器学习分类算法进行对比实验.这篇文章我们将继续巩固 ...

  8. 【论文复现】使用CNN进行文本分类

    今天要写的是关于NLP领域的一个关键问题:文本分类. 相对应的论文是:Convolutional Neural Networks for Sentence Classification 参考的博客为: ...

  9. 基于python文本挖掘实战_python实现CNN中文文本分类

    [实例简介] CNN 中文文本挖掘 文本分类 python 深度学习 机器学习 [实例截图] [核心代码] zh_cnn_text_classify-master └── zh_cnn_text_cl ...

  10. 深度学习原理与框架-CNN在文本分类的应用 1.tf.nn.embedding_lookup(根据索引数据从数据中取出数据) 2.saver.restore(加载sess参数)...

    1. tf.nn.embedding_lookup(W, X) W的维度为[len(vocabulary_list), 128], X的维度为[?, 8],组合后的维度为[?, 8, 128] 代码说 ...

最新文章

  1. C# 在用户控件中添加自定义事件
  2. Bokeh中图形与组件的布局简介 | Bokeh 小册子
  3. Android的数据存储
  4. python用pip安装_使用pip安装python库的几种常用方法
  5. Vue入门到TodoList练手
  6. 使用try_catch_finally处理流中的异常
  7. 【Virtual DOM】虚拟 DOM 和 Snabbdom 库
  8. NHibernate从入门到精通系列(5)——持久对象的生命周期(下)
  9. uni-app开发规范
  10. 调用 WebService 请求因 HTTP 状态 407 失败
  11. 【C++】内存4区---代码区、全局区、栈区、堆区
  12. 固有模态函数IMF与经验模态分解EMD
  13. 【Unity2D】制作游戏主菜单MainMenu
  14. 【NUC980开发板DIY项目大挑战】串口服务器
  15. 用Python计算北京地铁的两站间最短换乘路线
  16. MySQL千万级别表数据中提高RAND随机查询的实验
  17. js+css3的卡牌抽奖特效动画
  18. uniapp 获取定位以及经纬度转换为城市名
  19. Get和Post提交
  20. 序列比对(27)BWT算法

热门文章

  1. 模块划分-1 功能划分
  2. C300 OLT自动下发WAN连接指导配置
  3. Asp 解析 XML并分页显示
  4. 复合隐写/图片混合/图片格式头修改-西伯利亚大尾巴狼
  5. 开源漫画翻译神器! AI 自动清除、填补漫画文字!
  6. ps一点等于多少厘米_请问PS中“像素”和“厘米”是肿么换算的?
  7. 地质地貌卫星影像集锦(一 典型地貌篇)
  8. 冬季皮肤暗黄,教你一招变白
  9. BottomNavigationView取消水波纹动画
  10. 利用python爬取飞猪信息_python+selenium爬取飞猪酒店详情信息