jieba源代码分析 | 您所在的位置:网站首页 › 比亚迪水陆两栖汽车叫什么名字 › jieba源代码分析 |
2021SC@SDUSC 2021SC@SDUSC 在之前的TextRank算法的源代码解析中,我们所做的流程的第一步就是进行分词,使用到了cut函数(默认使用精确模式),但其实cut函数共有四种模式——精确模式、搜索引擎模式、全模式、paddle模式。 2021SC@SDUSC 2021SC@SDUSC python分词主要是基于动态规划和其构成的前缀词典。 虽然同样都是分词,但四种模式在分词的精细度方面有所差异,比如看下面的例子: import jieba #默认精确模式 instance=jieba.cut("黄包车师傅总是吆喝两声接活,街边的糖炒栗子香气像雪在落") print("精确模式:\t" + '/'.join(list(instance))) #搜索引擎模式 instance=jieba.cut_for_search("黄包车师傅总是吆喝两声接活,街边的糖炒栗子香气像雪在落") print("搜索引擎模式:\t" + '/'.join(list(instance))) #全模式 instance=jieba.cut("黄包车师傅总是吆喝两声接活,街边的糖炒栗子香气像雪在落",cut_all=True) print("全模式:\t" + '/'.join(list(instance))) #paddle模式 instance=jieba.cut("黄包车师傅总是吆喝两声接活,街边的糖炒栗子香气像雪在落",use_paddle=True) print("paddle模式:\t" + '/'.join(list(instance)))同样的句子,使用四种不同的模式,输出如下: jieba分词基于前缀词典实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图 (DAG);采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合;对于未登录词,采用了基于汉字成词能力的 HMM 模型,使用了 Viterbi 算法。 关于cut函数的代码存放在jieba/_init_中,从这篇博客开始,我们会对这个文件中的代码逐行分析。 首先看第一部分代码如下: 出现了re.compile,是有关分词的正则表达式的判定,例如出现TF-IDF,jieba将其分为两个词TF和IDF,还是看作一个词,便与此相关。 在此处,re_han_default是基于正则表达式进行汉字判断,符合此表达式,则被判定为是汉字。 #正则表达式,判断是否是汉字 re_han_default = re.compile("([\u4E00-\u9FD5a-zA-Z0-9+#&\._%\-]+)", re.U) #正则表达式,符号匹配问题相关 re_skip_default = re.compile("(\r\n|\s)", re.U)然后便是jieba库非常有用的一个类Tokenizer,四种不同的分词模式的函数均在此类中定义。 那么在分词前第一步,便是构建分词需要的前缀词典, 前缀词典中会保存每个词以及其词频和词性。 代码如下: def gen_pfdict(self, f):# f 为词典文件 lfreq = {} # 空字典 ltotal = 0 f_name = resolve_filename(f) # 返回f的文件名 for lineno, line in enumerate(f, 1):# lineno:序号,line:f的内容,逐行读取f的内容 try: line = line.strip().decode('utf-8') word, freq = line.split(' ')[:2] freq = int(freq) lfreq[word] = freq ltotal += freq # 词频总数 # 获取前缀,若在词典中则跳过,不在则加入词典,且置频数为0 for ch in xrange(len(word)): wfrag = word[:ch + 1] if wfrag not in lfreq: lfreq[wfrag] = 0 except ValueError: raise ValueError( 'invalid dictionary entry in %s at Line %s: %s' % (f_name, lineno, line)) f.close() #关闭文件f return lfreq, ltotal # 返回前缀词典,词汇总数代码具体分析解释可见旁注, # 从前缀字典中获得此的出现次数 def gen_word_freq(self, word): if word in self.FREQ: #在词典中,返回词 return self.FREQ[word] else: return 0我们分析代码可知其返回了一个字典lfreq,形式为{word:freq},其中不仅有原词典中的词和频数,还有原词典中词语的前缀,其频数为0,这就是前缀词典,根据此词典,我们就可以生成所有词语可能的有向无环图,有向无环图的代码详解见下一篇博客。 |
CopyRight 2018-2019 实验室设备网 版权所有 |