Spark做词性标注遇到的问题及解决方法
来源:互联网 发布:沙特军事知乎 编辑:程序博客网 时间:2024/05/17 19:18
在用spark做中文分词、词性标注的时候遇到了一些问题,记录一下场景及解决方法。
场景是这样的,我希望用spark做词性标注,这可以用jieba分词的POSTokenizer,本来只要集群的每个节点上的pyspark包路径都安装jieba就可以了。但问题在于,我需要用自定义的词典创建Tokenizer,目的是想令Tokenizer只切出词典中有的词,其他的词都过滤。起初的方案是在client 模式的driver program代码里用本地词典路径初始化Tokenizer,然后把这个Tokenizer对象绑定到需要传递给rdd.map的函数中,代码大概是
from functools import partialfrom jieba import Tokenizerdef func(text, tokenizer): tokenizer.cut(text) ...tokenizer = Tokenizer(local_dict_path)func_bind_tokenizer = partial(func, tokenizer=tokenizer)rdd.map(func_bind_tokenizer)
不过这种方法是行不通的,原因是spark需要把func_bind_tokenizer
这个闭包分发给各个worker,因此需要把这个闭包包括的对象都序列化。pyspark中的序列化方式是通过cPickle,而tokenizer因为包含添加新词的功能,因此带有锁,所以无法序列化, 这个闭包也就没办法分发给各worker了。
解决方法
解决方法有两种,第一种是修改jieba的代码,去除锁机制,并且自己保证添加新词的时候不会出错。这种方法就不细说了, 说说第二种不需要改代码的方法。
不考虑spark的架构如何,最好能够把词典分发到每个worker,然后在每个worker初始化一个tokenizer,这样就不需要把tokenizer序列化了。但spark是把task分发给各executor执行,我们并不能直接与worker联系。所以只好退而求其次在task粒度初始化tokenizer。因为每个partition对应一个task,所以用mapPartitions
方法针对partition粒度执行函数,用SparkContext.addFile()
方法将本地词典提交到集群,让集群分发到各个节点。这样每个task都会初始化一个tokenizer,只要词典不是太大,task数不是太多,都不用担心资源消耗的问题。代码大概如下
from jieba import Tokenizerfrom jieba.posseg import POSTokenizerfrom functools import partialfrom pyspark import SparkFilesdef func_partition(iterator, dict_name): # 获取各节点上词典文件的绝对路径 dict_path = SparkFiles.get(dict_name) tokenizer = Tokenizer(dict_path) pseg = POSTokenizer(tokenizer) for text in iterator: tokens = pseg.cut(text, HMM=False) for token in tokens: yield token.word, token.flag# sc 是实例化的SparkContextdict = 'user_dict'# 将本地词典文件添加到集群sc.addFile(local_dict_path)partial_func_partition = partial(func_partition, dict_name=dict)# 执行mapPartitionrdd.mapPartitions(partial_func_partition)
- Spark做词性标注遇到的问题及解决方法
- spark学习过程中遇到的问题及解决方法
- Spark开发中遇到的问题及解决方法
- 十七、让机器做词性自动标注的具体方法
- 做网站中遇到的一些问题及解决方法
- 对英文单词的词性标注
- 用pyltp做分词、词性标注、ner
- 自动化对语料做词性标注
- 遇到的问题及解决方法
- 遇到的问题及解决方法
- 词性标注
- 词性标注
- 词性标注
- 词性标注
- 词性标注
- 中英文分词及词性标注工具
- nltk词性标注英文简称及分类
- 中英文分词及词性标注工具
- 加入键盘鼠标控制的代码
- BZOJ 4385 Wilcze doły
- Shell脚本编写及常见面试题(二)
- 链接队列(Link Queue)——队列的链接实现
- 2017北京网络赛hihocoder 1580 matrix(dp)
- Spark做词性标注遇到的问题及解决方法
- Shell脚本编写及常见面试题(三)
- 2015-09-20-mysql数据库备份(备份 data文件夹)
- java学习笔记——HashMap的泛型容器
- 谈谈为什么选择使用小程序及小程序的优缺点20171219
- HDU2276(矩阵快速幂)
- 什么是SVN(Subversion)? 为什么要用SVN?
- sublime python快捷键
- 判断两各字符串相等的部分并将其输出(文件输入输出)