jieba分词源码解读一
来源:互联网 发布:用什么软件做内帐 编辑:程序博客网 时间:2024/05/21 20:22
从github上下载源代码后,打开 文件夹 jieba,找到__init__.py,结巴分词最主要的函数 cut 就定义在这个文件中。
这个函数的前半部分主要是根据用户指定的模式 用 正则表达式 将输入的文本 分块(block)。然后针对每一块进行分词,默认情况(精确模式)下使用的 块的分词函数叫 __cut_DAG 。
__cut_DAG 函数调用了 get_DAG(sentence),这是用来生成每一块(sentence)的有向无环图DAG。要生成DAG就必须有语料库的辅助了,所以在 同样在 文件夹 jieba 下,可以找到一个文件:dict.txt。语料库的有3列,第一列是词,第二列是词频,第三列是词性。在程序中初始化语料库的动作在函数 initialize(DICTIONARY) 中,它通过一个包装器 require_initialized 在 get_DAG 函数被调用的时候才执行。代码如下:
- def require_initialized(fn):
- @wraps(fn) #wraps的作用是保留被包装函数的一些属性,比如__doc__
- def wrapped(*args, **kwargs):
- global initialized
- if initialized:
- return fn(*args, **kwargs)
- else:
- initialize(DICTIONARY)
- return fn(*args, **kwargs)
- return wrapped
语料库加载后是要保存在 trie 树中的,让我们来看看作者是怎么实现中文的 trie 树的。
在 initialize 函数的最开头可以看到作者用with关键词优雅的获取了当前线程的RLock,with 的用法有点类似C#里的关键词using,详见:http://blog.csdn.net/largetalk/article/details/6910277
jieba 分词为了加快语料库的加载使用了缓存技术,它会将生成好的语料库数据结构用 marshal 序列化,然后存放在系统的临时目录(用到了 tempfile 库)下。如果找不到 缓存的 .cache 文件,调用 gen_trie 函数来生成 trie 树。该函数的代码如下:
- def gen_trie(f_name):
- lfreq = {}
- trie = {}
- ltotal = 0.0
- with open(f_name, 'rb') as f:
- lineno = 0
- for line in f.read().rstrip().decode('utf-8').split('\n'):
- lineno += 1
- try:
- word,freq,_ = line.split(' ')
- freq = float(freq)
- lfreq[word] = freq
- ltotal+=freq
- p = trie
- for c in word:
- if c not in p:
- p[c] ={}
- p = p[c]
- p['']='' #ending flag
- except ValueError, e:
- logger.debug('%s at line %s %s' % (f_name, lineno, line))
- raise ValueError, e
- return trie, lfreq,ltotal
这段代码就是 trie 树的具体实现,发现 trie 树其实就是一个嵌套的 dict,根据我的测试,使用默认的 dict.txt 生成的 trie 树在第一层的节点数高达:11772,这是一个值得改进的地方。如果使用自己的语料库而且又非常庞大的话,可以使用trie森林这样的手段,以词语的首字为根节点得到一颗trie树,形成一个trie森林。
- jieba分词源码解读一
- jieba分词源码解读二
- jieba分词源码解读三
- jieba分词源码解读四
- jieba中文分词源码分析(一)
- jieba分词源码阅读
- jieba分词算法源码解析
- 结巴分词源码解读(一)
- jieba中文分词源码分析(二)
- jieba中文分词源码分析(三)
- jieba中文分词源码分析(四)
- jieba分词的一些源码解析网站
- 浅谈中文分词与jieba源码
- jieba分词学习笔记(一)
- jieba分词
- jieba分词
- jieba分词
- jieba分词
- 完整java开发中JDBC连接数据库代码和步骤
- Java基础:参数传递(三)
- 跑步节奏音乐匹配Android项目开发和调试经验
- linux 多线程聊天服务器
- 【android】:android错误之Unparsed appt errors
- jieba分词源码解读一
- 学习心得
- 字典序法全排列
- ios 获取UIImage图片的像素尺寸
- Android正向传值和回调传值
- 别人的心得
- ubuntu14.4系统下载编译Android5.1.1源码
- Swift中的懒加载
- jieba分词源码解读二