java中文分词工具_对Pandas百万级文本进行中文分词加速,看这一篇就足够了

f37a40e2568d7a4cdaee23feaaba2698.png

一、摘要

很多NLP相关的任务都需要分词,而当文本语料比较多时,用python处理分词任务的过程会比较消耗时间。本文测试了对pandas百万级中文语料分词的多种实现方案和相应的执行时间,希望读者可以根据本次实验的结果选择适合自己的实现方式,节约分词任务带来的时间损耗。尤其是在没有集群环境下,需要在单机上处理大量文本分词任务时,可以有所参考。我们测试的多种方案中,最好的方案比最差的方案速度提升了318倍,最好的方案对百万级中文语料分词的总耗时仅有27.9秒!

二、python中文分词工具

用python进行中文分词任务,最常见的分词工具是jieba,当然可以用Jython调用一些java的分词工具,例如HanLP、Ansj等。本文主要讨论jieba分词工具。在python中使用jieba分词工具,简单、轻便,但是速度上不够快,所以有了用Cpython重新实现了jieba的核心函数的分词工具jieba_fast。jieba_fast分词工具在保证了与jieba分词工具一致性的基础上,分词速率大大提升。接下来,我们测试一下jieba和jieba_fast工具的分词速率。

我们网上找来1000条文本,句子长度平均在20个字,首先导入两个分词工具:

af5c33d019e1d6879f8fb26ef202e4f8.png

我们写一个计算函数执行时间的函数,如下:

206ce55b03ebfc63018127f0d8e899ce.png

定义两个分词函数进行分词,如下:

6bc38b8a67e8a4bf04c4f64c23a60612.png

测试这两个分词函数的执行时间,如下:

a04be9f5b4af0fee48afe7957fa11ac8.png

我们可以看到,对1000条文本进行分词,jieba工具需要1.737秒,而jieba_fast工具只需要0.157秒,jieba_fast速度提升了近11倍,当文本数量更大时,节约的时间更加明显。所以,在用python对中文文本进行分词时,我们推荐使用jieba_fast分词工具。

三、对Pandas逐行运算的加速

本次测试,我们用pandas读取网络上的公开中文文本进行分词。共有137万+的中文文本,单个文本字数平均为20个字,最小的字数为11,最大的字数为1170个字。

33438ebef53af89897ff574b45150a25.png

下面将用这份中文数据,测试多种对pandas dataframe逐行分词运算的加速方案。

分词函数定义如下:

363671a0c4465a15f4021f4c2b99b7f5.png

3.1、普通的逐行遍历dataframe

652cf416dd98dd6e23c2fb3de46df1aa.png

运行上述函数,查看执行时间:

519718ca3e56abf4e6c275ddcea072f6.png

可以看到用普通的逐行遍历的方式,来对137万的中文语料进行分词,总耗时是229.7秒。

3.2、使用iterrows()函数遍历dataframe

7e4699cb1febf10bbcf809db6fde3034.png

运行上述函数,查看执行时间:

166a512d743084087a77736411b431ef.png

可以看到用iterrows()函数遍历的方式,来对137万的中文语料进行分词,总耗时488.3秒。

3.3、使用apply()函数进行遍历dataframe

8029f0757905ed8c97eeb2d4e057aaa6.png

运行上述函数,查看执行时间:

9a3bfa0e954c7a2ebea054353a38b748.png

可以看到用apply()函数遍历的方式,来对137万的中文语料进行分词,总耗时227.9秒。

3.4、启用joblib多进程+apply()函数进行遍历

9275f2504da3c5676e1b21ddc75435fc.png

执行上述代码,我们在后台查看,是否启用了多个进程来处理:

a70cf5a8ef60edaa0e637e11a34c4d2b.png

后台看到确实启用了多个进程来并行的跑job。我们再来看看执行时间:

cc2d14f17c4a2fff6b0a9b8f83ecf6f1.png

采用joblib起多个进程来跑这个分词任务时,我们震惊地发现执行时间竟然高达8895.7秒(2.5h)!

原因可能是多个进程之间频繁的数据复制和传输,再加上多个数据之间的pd.concat 效率并不高。真是”一顿操作猛如虎,定睛一看原地杵“……

3.5、dataframe转成numpy array之后再遍历

6be03e670054d7789ca39d0ad6d03db9.png

运行上述函数,查看执行时间:

eab5480287fad3c6c01a73278db98be5.png

可以看到将dataframe转化成numpy array之后再遍历的方式,来对137万的中文语料进行分词,总耗时138.5秒。我们发现转化成numpy array之后再遍历比直接对dataframe遍历要高效,速度大约提升1倍左右。

3.6、使用modin给pandas加速

8d79e9b2bae1e54476fbb0eda169bb66.png

运行上述函数,查看执行时间:

288c61c6b679172ad75d1015b85cd530.png

可以看到用modin给dataframe加速的方式,来对137万的中文语料进行分词,总耗时54.9秒。另外从输出日志中也可以看出来,modin也启用了多个进程并行处理,只是多个进程之间不会将原始数据多次复制,所以处理速度大大提升了(modin启用了redis)。

3.7、使用swifter对dataframe加速

86c4549383538db71f9ef3f9e714865a.png

运行上述函数,查看执行时间:

0fb2b2bfb287ae038d00af29c900fa73.png

可以看到用swifter给dataframe加速的方式,来对137万的中文语料进行分词,总耗时278.2秒。另外,swifter处理过程会显示进度条,显示已经处理的数据条数、已经处理时间和预估剩余时间等。

3.8、使用dask对dataframe加速

b174f7cac24633034fcf00350cbf669b.png

运行上述函数,查看执行时间:

9f3d5e6879400101a535846c60d3f7e8.png

可以看到用dask给dataframe加速的方式,来对137万的中文语料进行分词,总耗时仅需要27.9秒!非常迅速。我们在后台可以看到启用的多个进程的资源使用非常平衡。

557634b5bb371e1b518e25b3962c5cfe.png

四、总结一下

1、用Python对中文分词,建议使用jieba_fast工具包代替jieba工具包。

2、各种对Pandas DataFrame的逐行迭代运算方案及其相应耗时如下:

28bdcc859c5f580279d2dd658f817f0d.png

对Pandas DataFrame遍历加速,除了本文测试的之外,还有一种方式,就是使用Mars对pandas加速。至于Mars给pandas的提速可以达到多少,留给感兴趣的读者自行尝试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值