博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jieba 分词源代码研读(1)
阅读量:4709 次
发布时间:2019-06-10

本文共 1912 字,大约阅读时间需要 6 分钟。

从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,详见:

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森林。

转载于:https://www.cnblogs.com/rav009/p/5131119.html

你可能感兴趣的文章
maven使用阿里镜像配置文件
查看>>
Copy code from eclipse to word, save syntax.
查看>>
arguments.callee的作用及替换方案
查看>>
Centos 6.5下的OPENJDK卸载和SUN的JDK安装、环境变量配置
查看>>
【.Net基础03】HttpWebRequest模拟浏览器登陆
查看>>
zTree async 动态参数处理
查看>>
Oracle学习之常见错误整理
查看>>
数据库插入数据乱码问题
查看>>
【转】IT名企面试:微软笔试题(1)
查看>>
IO流入门-第十章-DataInputStream_DataOutputStream
查看>>
DRF的分页
查看>>
Mysql 模糊匹配(字符串str中是否包含子字符串substr)
查看>>
python:open/文件操作
查看>>
流程控制 Day06
查看>>
Linux下安装Tomcat
查看>>
windows live writer 2012 0x80070643
查看>>
tomcat 和MySQL的安装
查看>>
git常用操作
查看>>
京东SSO单点登陆实现分析
查看>>
u-boot启动第一阶段
查看>>