提供分词与词频统计并行化的Python实现,提速效果明显。

小数据集情况

NLP任务往往需要词频统计,如果涉及到中文词信息,往往还需要分词。在小数据集的情况下,使用串行的方法能解决大部分的问题,一般如下操作获得词频表,

1
2
3
4
5
import itertools
import collections
X = [text1, text2, ..., textn]
words = collections.Counter(itertools.chain(*X))
print(words.most_common(20))

但是当数据集非常大,如十个GB的文本数据,一边分词一边词频统计,以上代码显得非常无力。

并行词频统计

为此,这里提供在大数集中并行统计字词频率表的方法,

1
2
3
4
5
6
7
8
9
10
11
12
13
import jieba

path = "THUCNews/**/*.txt"
tokens = count_in_parrallel(
tokenize=jieba.lcut,
batch_generator=load_batch_texts(path, limit=10000),
processes=6,
maxsize=300,
preprocess=lambda x: x.lower()
)
print(len(tokens))
print(tokens.most_common(200))
print(tokens.most_common(-200))

并行分词

并行分词例子,分词结果按原句子顺序返回,这样有利于Tokenizer处理和模型训练等相关操作,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import itertools
import jieba
from tokenize_in_parallel import *

file = "THUCNews-title-label.txt"

def gen(file):
with open(file, encoding="utf-8") as fp:
text = fp.read()
lines = text.split("\n")[:-1]
for line in lines:
yield line

# 分词结果按原顺序返回
tokens = tokenize_in_parallel(
tokenize=jieba.lcut,
generator=gen(file),
processes=7,
maxsize=300,
preprocess=lambda x: x.lower()
)

print(len(tokens))
for i in range(10):
print(tokens[i])

实现与效果

开源地址:count-in-parallel,里面包括并行分词和词频统计的实现和例子。

以THUCNews文件集作为测试,jieba作tokenize下测试:

CPUs 文件数 时间
6CPUS 10000 8s
4CPUS 10000 11s
2CPUs 10000 16s
1CPUs 10000 32s
1CPUs 800000 近40分钟
6CPUS 800000 350s

可以看到,并行效果还是不错的。

转载请包括本文地址:https://allenwind.github.io/blog/13136
更多文章请参考:https://allenwind.github.io/blog/archives/