自然语言处理基础——jieba分词的原理与使用方法

Posted 小哈里

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自然语言处理基础——jieba分词的原理与使用方法相关的知识,希望对你有一定的参考价值。

文章目录

1 什么是jieba

  • 自然语言处理,特别是中文处理中,最好用的分词组件。
    python原项目开源地址:https://github.com/fxsjy/jieba

  • 支持四种分词模式:
    精确模式,试图将句子最精确地切开,适合文本分析;
    全模式,把句子所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义;
    搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。
    paddle模式,利用PaddlePaddle深度学习框架,训练序列标注(双向GRU)网络模型实现分词。同时支持词性标注。paddle模式使用需安装paddlepaddle-tiny,pip install paddlepaddle-tiny==1.6.1。目前paddle模式支持jieba v0.40及以上版本。jieba v0.40以下版本,请升级jieba,pip install jieba --upgrade 。

  • jieba分词的特点
    支持繁体分词
    支持自定义词典

  • jieba分词能分英文吗?
    对于英文文本,句子中的词汇可以通过空格很容易得进行划分,并不需要分词,谢谢。
    英文可以使用NLTK 进行分词和分句。
    jieba也可以把像All work and no play makes jack a dull boy, all work and no play这样的句子给分出来,不过在统计词频的时候效果似乎不是特别好。

  • jieba分词拥有多语言版本
    Java:https://github.com/huaban/jieba-analysis
    C++:https://github.com/yanyiwu/cppjieba
    GO:https://github.com/wangbin/jiebago,https://github.com/yanyiwu/gojieba
    NODE:https://github.com/yanyiwu/nodejieba
    android:https://github.com/452896915/jieba-android
    ios:https://github.com/yanyiwu/iosjieba
    php:https://github.com/fukuball/jieba-php
    C#:https://github.com/anderscui/jieba.NET/

2 jieba分词的使用

  • 安装说明:
    py3环境下直接通过pip3 install jieba安装
    官网下载源代码,解压后运行 python setup.py install安装
    将 jieba 目录放置于当前目录或者 site-packages 目录来安装
    通过 import jieba 来引用

  • 分词

    官方示例代码:

    # encoding=utf-8
    import jieba
    
    jieba.enable_paddle()# 启动paddle模式。 0.40版之后开始支持,早期版本不支持
    strs=["我来到北京清华大学","乒乓球拍卖完了","中国科学技术大学"]
    for str in strs:
        seg_list = jieba.cut(str,use_paddle=True) # 使用paddle模式
        print("Paddle Mode: " + '/'.join(list(seg_list)))
    
    seg_list = jieba.cut("我来到北京清华大学", cut_all=True)
    print("Full Mode: " + "/ ".join(seg_list))  # 全模式
    
    seg_list = jieba.cut("我来到北京清华大学", cut_all=False)
    print("Default Mode: " + "/ ".join(seg_list))  # 精确模式
    
    seg_list = jieba.cut("他来到了网易杭研大厦")  # 默认是精确模式
    print(", ".join(seg_list))
    
    seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造")  # 搜索引擎模式
    print(", ".join(seg_list))
    
    
    【全模式】:/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学
    
    【精确模式】:/ 来到/ 北京/ 清华大学
    
    【新词识别】:他, 来到,, 网易, 杭研, 大厦    (此处,“杭研”并没有在词典中,但是也被Viterbi算法识别出来了)
    
    【搜索引擎模式】: 小明, 硕士, 毕业,, 中国, 科学, 学院, 科学院, 中国科学院, 计算, 计算所,,, 日本, 京都, 大学, 日本京都大学, 深造
    
  • 词典操作


    官方示例代码:

    >>> print('/'.join(jieba.cut('如果放到post中将出错。', HMM=False)))
    如果/放到/post/中将/出错/>>> jieba.suggest_freq(('中', '将'), True)
    494
    >>> print('/'.join(jieba.cut('如果放到post中将出错。', HMM=False)))
    如果/放到/post///出错/>>> print('/'.join(jieba.cut('「台中」正确应该不会被切开', HMM=False)))////正确/应该/不会//切开
    >>> jieba.suggest_freq('台中', True)
    69
    >>> print('/'.join(jieba.cut('「台中」正确应该不会被切开', HMM=False)))/台中//正确/应该/不会//切开
    
  • 基于 TF-IDF 算法的关键词抽取

    官方示例代码:

    import sys
    sys.path.append('../')
    
    import jieba
    import jieba.analyse
    from optparse import OptionParser
    
    USAGE = "usage:    python extract_tags.py [file name] -k [top k]"
    
    parser = OptionParser(USAGE)
    parser.add_option("-k", dest="topK")
    opt, args = parser.parse_args()
    
    
    if len(args) < 1:
        print(USAGE)
        sys.exit(1)
    
    file_name = args[0]
    
    if opt.topK is None:
        topK = 10
    else:
        topK = int(opt.topK)
    
    content = open(file_name, 'rb').read()
    
    tags = jieba.analyse.extract_tags(content, topK=topK)
    
    print(",".join(tags))
    

3 jieba分词的原理

分词步骤:

  1. 根据dict.txt词典生成trie树;
  2. 给定待分词的句子,使用正则获取连续的中文字符和英文字符,切分成短语列表,对每个短语使用DAG(查字典)和动态规划,得到最大概率路径。
  3. 对DAG中那些没有在字典中查到的字,组合成一个新的片段短语,使用HMM模型进行分词,也就是作者说的识别新词,即识别字典外的新词。

核心算法部分:

  • 基于前缀词典实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图 (DAG)
  • 采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合
  • 对于未登录词,采用了基于汉字成词能力的 HMM 模型,使用了 Viterbi 算法

1、基于前缀词典实现高效的词图扫描

  • 结巴分词自带了一个叫做dict.txt的词典,里面有349046条词,其每行包含了词条、词条出现的次数(这个次数是结巴作者自己基于人民日报语料等资源训练得出来的)和词性。
  • 把这34万多条词语,放到一个trie树的数据结构中,也就是说一个词语的前面几个字一样,就表示他们具有相同的前缀,就可以使用trie树来存储,具有查找速度快的优势。
  • 査询的过程对于查询词来说,从前往后一个字符一个字符的匹配。对于trie树来说,是从根节点往下匹配的过程

2、找出基于词频的最大切分组合

  • 生成句子中汉字所有可能成词情况所构成的有向无环图,给定一个待分词的句子,将它的所有词匹配出来,构成词图,即是一个有向无环图DAG。
  • 作者的代码中将字典在生成trie树的同时,也把每个词的出现次数转换为了频率。频率其实也是一个0~1之间的小数,是事件出现的次数/实验中的总次数。
  • 动态规划中,先查找待分词句子中已经切分好的词语,对该词语查找该词语出现的频率(次数/总数),如果没有该词(既然是基于词典查找,应该是有可能没有该词),就把词典中出现频率最小的那个词语的频率作为该词的频率

3、基于汉字成词能力的 HMM 模型

  • 一些人可能会想到把dict.txt中所有的词汇全部删掉,然后再试试结巴能不能分词。结果会发现,结巴依然能够分词,不过分出来的词,大部分的长度为2。
  • 作者采用了HMM模型,中文词汇按照BEMS四个状态来标记,B是开始begin位置,E是是结束end位置,M是中间middle位置,S是single,单独成词的位置。也就是说,他采用了状态为(B,E,M,S)这四种状态来标记中文词语。
  • 经过作者对大量语料的训练,得到了finalseg目录下的三个文件
    位置转换概率,即B(开头),M(中间),E(结尾),S(独立成词) 四种状态的转移概率,该表存放于prob_trans.py中
    位置到单字的发射概率
    词语以某种状态开头的概率,其实只有两种,要么是B,要么是S
  • 将一个给定的待分词的句子视为一个观察序列,对HMM(BEMS)四种状态的模型来说,就是为了找到一个最佳的BEMS隐状态序列,这个就需要使用Viterbi算法来得到这个最佳的隐藏状态序列。通过提前训练好的HMM转移概率、发射概率,使用基于动态规划的viterbi算法的方法,就可以找到一个使概率最大的BEMS序列。

以上是关于自然语言处理基础——jieba分词的原理与使用方法的主要内容,如果未能解决你的问题,请参考以下文章

自然语言处理课程:Jieba分词的原理及实例操作

自然语言处理之jieba分词

jieba分词(R vs. python)

自然语言处理之jieba分词

自然语言处理之中文分词器-jieba分词器详解及python实战

机器学习之自然语言处理——中文分词jieba库详解(代码+原理)