【jieba】 jieba 库中 cut_for_search 方法的实现详解

jieba 是一个非常流行的中文分词工具,它支持三种分词模式:精确模式全模式搜索引擎模式。其中,cut_for_search()jieba 提供的用于搜索引擎模式的分词方法,适合用在构建搜索索引或进行文本检索时。

jieba.cut_for_search() 详解

功能:

cut_for_search() 主要用于搜索引擎分词,会对文本进行较细的切分,特别是对较长的词语进行更多的分割。这使得它更适合搜索场景,因为搜索引擎通常需要更细粒度的分词来提高匹配的可能性,特别是支持短语检索和子词匹配。

使用方法:
import jieba

text = "我来到北京清华大学"
result = jieba.lcut_for_search(text)
print(result)

输出:

['我', '来到', '北京', '清华', '华大', '大学', '清华大学']
特点:
  1. 子词拆分lcut_for_search() 不仅会分出完整的词,还会将长词进一步细分。例如,“清华大学”会被分为“清华”、“华大”、“大学”。
  2. 适合搜索引擎:对长词的进一步拆分非常适合构建倒排索引(inverted index),因为它能够提高子词的匹配率,进而提高检索的召回率。
  3. 返回列表lcut_for_search() 会返回一个分词后的词语列表,而不是迭代器,方便处理。
具体应用场景:
  • 倒排索引构建:在搜索引擎中,常常需要对文本进行分词,以便为每个词建立倒排索引。cut_for_search() 会切分出更多细粒度的词,有助于提高搜索结果的相关性。
  • 用户查询处理:当用户输入长词或短语时,细粒度的分词可以确保用户查询中的各个部分都能参与匹配,提高检索的灵活性。
注意事项:
  • 细粒度分词可能增加计算开销:由于对长词进行了更多的拆分,可能会生成比精确模式更多的词,因此在处理和匹配时可能会稍微增加一些计算负担。
  • 适用场景cut_for_search() 在需要更高检索召回率的场景(如搜索引擎)非常合适,但在不涉及子词匹配的其他任务中,可能不如精确模式高效。

对比其他分词模式:

  • 精确模式 (cut())jieba.cut() 切分出来的词通常更少,只保留了精确的词语边界,适合统计或语义分析等任务。
  • 全模式 (cut_all())cut_all() 会把可能的词都分出来,通常会生成非常多的词,适合搜索引擎的粗分词场景,但输出结果冗余度较高,不建议直接用于检索任务。

通过使用 cut_for_search(),可以有效地提高搜索系统的召回能力,同时保持较高的搜索精度。

    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

这段代码是 jieba 库中 cut_for_search 方法的实现,它用于进行搜索引擎的细粒度分词。让我们详细分析这段代码的逻辑,解释其工作原理:

1. 函数定义

def cut_for_search(self, sentence, HMM=True):
    """
    Finer segmentation for search engines.
    """
  • 该函数的作用是对输入的 sentence 进行更细致的分词,主要用于搜索引擎。
  • HMM=True 是用于控制是否使用**隐马尔可夫模型(HMM)**来处理未登录词(即词典中没有的词)。

2. 调用 self.cut() 进行基础分词

words = self.cut(sentence, HMM=HMM)
  • self.cut()jieba 中的标准分词方法,它会根据设定的模式(是否启用 HMM)对 sentence 进行初步分词。
  • 返回的 words 是初步分词结果,这个结果可以包含单个词语或者多个词。

3. 遍历分词结果

for w in words:
  • cut_for_search() 会对 self.cut() 分词后的每个词 w 进行进一步处理。

4. 生成 2-gram

if len(w) > 2:
    for i in xrange(len(w) - 1):
        gram2 = w[i:i + 2]
        if self.FREQ.get(gram2):
            yield gram2
  • 对于长度大于 2 的词,程序会生成该词的所有 2-gram 子词。
    • 2-gram 是由相邻两个字符组成的子词。例如,“清华大学” 会被分成 “清华”、“华大”。
  • 在生成 2-gram 之后,程序会检查这些子词是否出现在词典 (self.FREQ) 中。
    • 如果子词存在于词典中,程序会 yield 出这个子词,意味着该子词将作为一个有效的分词结果。

5. 生成 3-gram

if len(w) > 3:
    for i in xrange(len(w) - 2):
        gram3 = w[i:i + 3]
        if self.FREQ.get(gram3):
            yield gram3
  • 对于长度大于 3 的词,程序会生成 3-gram 子词。
    • 3-gram 是由三个相邻字符组成的子词。例如,“清华大学” 可以被分成 “清华大”、“华大学”。
  • 同样,程序会检查这些 3-gram 是否在词典中存在,若存在,则 yield 出该子词。

6. 保留原词

yield w
  • 无论该词是否生成了 2-gram 或 3-gram,原始词语都会作为一个分词结果被保留。

总结:

  • cut_for_search() 在标准分词结果的基础上,对长度较大的词进一步生成 2-gram 和 3-gram 子词,并检查这些子词是否存在于词典中。存在的话,就将这些子词作为额外的分词结果输出。
  • 这种处理方式可以在搜索引擎中提高短词和子词的匹配率,进而提高召回率。这也是搜索引擎分词通常比普通分词更细致的原因。

例如:

sentence = "清华大学"
result = list(jieba.cut_for_search(sentence))
print(result)

输出:

['清华', '华大', '大学', '清华大学']

这展示了 2-gram 的生成过程以及原词的保留。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值