jieba库:Tokenizer()类详解:(六)cut,cut_for_search

2021SC@SDUSC


cut

def cut(sentence,cut_all=False,HMM=True):  
	#整个分词的主函数,
	#输入sentence是需要分词的句子;
	#cut_all是分词模式,默认是精准模式;
	#HMM是隐马尔可夫链,默认开启。
    '''The main function that segments an entire sentence that contains 
    Chinese characters into seperated words. 
    Parameter:
        - sentence: The String to be segmented
        - cut_all: Model. True means full pattern, false means accurate pattern.   
        - HMM: Whether use Hidden Markov Model.
    '''
    if not isinstance(sentence, unicode):  #如果输入的句子不是统一编码形式的unicode,那么使用Python中的decode,将其解码称为unicode
		#注:unicode、gbk等都是中文编码的方式
        try:
            sentence = sentence.decode('utf-8')
        except UnicodeDecodeError:  #如果在decode的过程中出现了错误,那么就解码成gbk形式的。
            sentence = sentence.decode('gbk','ignore')
    '''
        \u4E00-\u9FA5a-zA-Z0-9+#&\._ : All non-space characters. Will be handled with re_han
        \r\n|\s : whitespace characters. Will not be Handled. 
    ''' 
	#下面使用到了Python中正则表达式模块re,正则表达式是用于处理字符串的强大工具,
	#拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大。
	#其最擅长的、最被大家使用的就是字符串匹配功能
	#正则表达式的大致匹配过程是:依次拿出表达式和文本中的字符比较,如果每一个字符都能匹配,则匹配成功;
	#一旦有匹配不成功的字符则匹配失败。如果表达式中有量词或边界,这个过程会稍微有一些不同
 
	#re.compile 可以把正则表达式编译成一个正则表达式对象。
	#可以把那些经常使用的正则表达式编译成正则表达式对象,这样可以提高一定的效率
	#关于正则表达式指南:http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html
	#关于正则表达式常用的处理函数:http://www.cnblogs.com/sevenyuan/archive/2010/12/06/1898075.html
 
    re_han, re_skip = re.compile(ur"([\u4E00-\u9FA5a-zA-Z0-9+#&\._]+)", re.U), re.compile(ur"(\r\n|\s)", re.U)
	#将以下正则表达式编译成re_han对象:
	#\u4E00-\u9FA5是所有汉字的编码,a-zA-Z是所有大小写字母的编码,0-9是所有阿拉伯数字的编码,+#&\._其余字符
	#将以下正则表达式编译成re_skip对象:
	#\r是回车,\n是换行,|或, \s是空白字符(\r\n\t\f\v)
	#re.U是使得compile的结果取决于unicode定义的字符属性
    if cut_all:
        re_han, re_skip = re.compile(ur"([\u4E00-\u9FA5]+)", re.U), re.compile(ur"[^a-zA-Z0-9+#\n]", re.U)
		#全模式下,只handle中文字符部分[\u4E00-\u9FA5],其余的字母、数字等等都要跳过。
    blocks = re_han.split(sentence)
	#这个split的作用和Python自带的split作用差不多,按照能够匹配的子串,即刚才compile进去的哪些字符,将sentence分割
	#而且是把sentence分成几个blocks,然后针对每一块进行分词
	'''
	例子:
	p = re.compile(r'\d+')
	print p.split('one1two2three3four4')
 
	### output ###
	# ['one', 'two', 'three', 'four', '']  #按照compile的表达式,把一个string分成几个blocks
	'''
    if HMM:  #默认情况使用__cut_DAG作为分词函数,为每个block分词
        cut_block = __cut_DAG
    else:
        cut_block = __cut_DAG_NO_HMM
    if cut_all:
        cut_block = __cut_all
 
    for blk in blocks:  #针对每一块进行分词
        if len(blk)==0:  #当blk为空时,继续下一个blk的分词
            continue
        if re_han.match(blk):  #如果re_han.match(blk)为true,说明当前blk是re_han范围内的文本
            for word in cut_block(blk):  #__cut_DAG作为分词函数为每个block分词,返回分词后word列表
                yield word  #yield作用也是返回,但是其不会消除local variables。
				#yield statement is what makes a function a generator function.
				#具体的yield和return在Python中的区别:http://blog.csdn.net/jiyanfeng1/article/details/8148561
        else:
            tmp = re_skip.split(blk)  #按照re_skip中的正则表达式,把blk划分成几块
            for x in tmp:
                if re_skip.match(x):
                    yield x  #返回匹配划分的每一部分
                elif not cut_all:  #如果是精准模式,则返回x中的每一项,即试图将句子最精确地切开
                    for xx in x:
                        yield xx
                else:  #如果是全模式,把句子中所有的可以成词的词语都扫描出来
                    yield x

cut_for_search()


    # 搜索引擎模式,首先调用cut()方法,得到切分后的结果,
    # 然后对length大于二和大于三的子结果进行遍历,检测是否有二字成词(对于长度大于二的结果)和三字成词(对于长度大于三的结果),
    # 如果有,先于结果加入迭代器返回。
    def cut_for_search(self, sentence, HMM=True):
        """
        Finer segmentation for search engines.
        """
        words = self.cut(sentence, HMM=HMM)
        for w in words:
            if len(w) > 2:
                for i in xrange(len(w) - 1):
                    gram2 = w[i:i + 2]
                    if self.FREQ.get(gram2):
                        yield gram2
            if len(w) > 3:
                for i in xrange(len(w) - 2):
                    gram3 = w[i:i + 3]
                    if self.FREQ.get(gram3):
                        yield gram3
            yield w

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值