jieba源碼研讀筆記(十四) - 詞性標注函數入口

jieba源碼研讀筆記(十四) - 詞性標注函數入口

前言

在前面兩篇中介紹了__cut_DAG_NO_HMM__cut_DAG函數。

本篇介紹的__cut_internal函數是__cut_DAG__cut_DAG_NO_HMM這兩個函數的入口,它的參數HMM可以選擇要使用哪一個。

本篇還會介紹_lcut_internal_lcut_internal_no_hmmcutlcut,它們是__cut_internal的wrapper,讓它變得更易用。

__cut_internal函數

以下代碼中用到的正則表達式,包括:re_han_internalre_skip_internalre_numre_eng已於jieba源碼研讀筆記(四) - 正則表達式中介紹。

在以下代碼中,先依HMM這個參數來決定要使用__cut_DAG__cut_DAG_NO_HMM,然後改以cut_blk來稱呼它。

一開始用re_han_internal來將句子分割成可處理的及不可處理的部份。可處理的部份直接呼叫cut_blk,不可處理的部份則利用正則表達式匹配的方式來做詞性標注。

class POSTokenizer(object):
    # ...
    def __cut_internal(self, sentence, HMM=True):
        self.makesure_userdict_loaded()
        sentence = strdecode(sentence)
        #re_han_internal:一個或多個中文或英數字或+#&._
        #能與re_han_internal匹配代表可以被__cut_DAG或__cut_DAG_NO_HMM處理
        blocks = re_han_internal.split(sentence)
        #決定要使用__cut_DAG或__cut_DAG_NO_HMM中的一個
        if HMM:
            cut_blk = self.__cut_DAG
        else:
            cut_blk = self.__cut_DAG_NO_HMM

        for blk in blocks:
            #如果與re_han_internal相匹配,代表可被__cut_DAG及__cut_DAG_NO_HMM所處理
            if re_han_internal.match(blk):
                for word in cut_blk(blk):
                    yield word
            else:
                #無法與re_han_internal匹配的blk
                #re_skip_internal:換行字元及空白字元
                tmp = re_skip_internal.split(blk)
                for x in tmp:
                    if re_skip_internal.match(x):
                        #換行字元及空白字元的詞性為'x'(未知)
                        yield pair(x, 'x')
                    else:
                        #非空白字元,檢查它是否為數字或英文
                        for xx in x:
                            if re_num.match(xx):
                                yield pair(xx, 'm')
                            elif re_eng.match(x):
                                yield pair(xx, 'eng')
                            else:
                                yield pair(xx, 'x')

__cut_internal的wrapper

POSTokenizercut函數是__cut_internal函數的wrapper,接受的參數與__cut_internal一樣是sentenceHMM。它會依據HMM來決定要調用__cut_DAG_NO_HMM__cut_DAG中的一個。

_lcut_internal_lcut_internal_no_hmmlcut分別是__cut_internal(sentence)__cut_internal(sentence, False)cut三個函數的wrapper,將它們的輸出由generator型別轉為list型別。

class POSTokenizer(object):
    # ...
    def cut(self, sentence, HMM=True):
        for w in self.__cut_internal(sentence, HMM=HMM):
            yield w
            
    def _lcut_internal(self, sentence):
        return list(self.__cut_internal(sentence))

    def _lcut_internal_no_hmm(self, sentence):
        return list(self.__cut_internal(sentence, False))

    def lcut(self, *args, **kwargs):
        return list(self.cut(*args, **kwargs))

參考連結

jieba源碼研讀筆記(四) - 正則表達式

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
结巴分词早期版本。 * 结巴分词(java版) jieba-analysis 首先感谢jieba分词原作者[[https://github.com/fxsjy][fxsjy]],没有他的无私贡献,我们也不会结识到结巴 分词,更不会有现在的java版本。 结巴分词的原始版本为python编写,目前该项目在github上的关注量为170, 打星727次(最新的数据以原仓库为准),Fork238次,可以说已经有一定的用户群。 结巴分词(java版)只保留的原项目针对搜索引擎分词的功能(cut_for_index、cut_for_search),词性标注,关键词提取没有实现(今后如用到,可以考虑实现)。 * 简介 ** 支持分词模式 - Search模式,用于对用户查询词分词 - Index模式,用于对索引文档分词 ** 特性 - 支持多种分词模式 - 全角统一转成半角 - 用户词典功能 - conf 目录有整理的搜狗细胞词库 - 支持词性标注(感谢 [[https://github.com/linkerlin][@linkerlin]] 的贡献) * 如何获取 - 当前稳定版本 #+BEGIN_SRC xml com.huaban jieba-analysis 0.0.2 #+END_SRC - 当前快照版本 - 支持词性标注 [[https://github.com/huaban/jieba-analysis/pull/4][#4]] - 修复以'-'连接词分词错误问题 [[https://github.com/huaban/jieba-analysis/issues/3][#3]] #+BEGIN_SRC xml com.huaban jieba-analysis 1.0.0-SNAPSHOT #+END_SRC * 如何使用 - Demo #+BEGIN_SRC java @Test public void testDemo() { JiebaSegmenter segmenter = new JiebaSegmenter(); String[] sentences = new String[] {"这是一个伸手不见五指的黑夜。我叫孙悟空,我爱北京,我爱Python和C++。", "我不喜欢日本和服。", "雷猴回归人间。", "工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作", "结果婚的和尚未结过婚的"}; for (String sentence : sentences) { System.out.println(segmenter.process(sentence, SegMode.INDEX).toString()); } } #+END_SRC * 算法(wiki补充...) - [ ] 基于 =trie= 树结构实现高效词图扫描 - [ ] 生成所有切词可能的有向无环图 =DAG= - [ ] 采用动态规划算法计算最佳切词组合 - [ ] 基于 =HMM= 模型,采用 =Viterbi= (维特比)算法实现未登录词识别 * 性能评估 - 测试机配置 #+BEGIN_SRC screen Processor 2 Intel(R) Pentium(R) CPU G620 @ 2.60GHz Memory:8GB 分词测试时机器开了许多应用(eclipse、emacs、chrome...),可能 会影响到测试速度 #+END_SRC - [[src/test/resources/test.txt][测试文本]] - 测试结果(单线程,对测试文本逐行分词,并循环调用上万次) #+BEGIN_SRC screen 循环调用一万次 第一次测试结果: time elapsed:12373, rate:2486.986533kb/s, words:917319.94/s 第二次测试结果: time elapsed:12284, rate:2505.005241kb/s, words:923966.10/s 第三次测试结果: time elapsed:12336, rate:2494.445880kb/s, words:920071.30/s 循环调用2万次 第一次测试结果: time elapsed:22237, rate:2767.593144kb/s, words:1020821.12/s 第二次测试结果: time elapsed:22435, rate:2743.167762kb/s, words:1011811.87/s 第三次测试结果: time elapsed:22102, rate:2784.497726kb/s, words:1027056.34/s 统计结果:词典加载时间1.8s左右,分词效率每秒2Mb多,近100万词。 2 Processor Intel(R) Core(TM) i3-2100 CPU @ 3.10GHz 12G 测试效果 time elapsed:19597, rate:3140.428063kb/s, words:1158340.52/s time elapsed:20122, rate:3058.491639kb/s, words:1128118.44/s #+END_SRC
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值