[Day2] 断词介绍

一. 为何需要断词
最主要的原因就是中文的最小一个单位就是一个词,通常不能直接喂一个句子给你的语言模型处理,这样模型连词跟词的关系都不知道,所以我们需要先利用断词,让电脑了解这个词与哪些词会很长相连,那些词又是无关的,例如: '很'是个副词麻,他後面基本上只会接形成词或动词对吧,像是'漂亮'、'帅气'这类的词。但在不同语言上都会有不同的断词方法,像是中文与英文,英文也是需要断词,但他们的词语词之间就是用空白相隔,与中文比较起来,英文算是比较好断开的,那中文就需要用一些统计的方法来处理拉。

二. 断词的演算法
目前断词的演算法大致如下:

  • 基於词典的分词法:照一定的策略将待匹配的字符串和一个已建立好的词典中的词进行匹配,通常会采用双向匹配的方法,但这方法的能力有限,例如像是新发明的词就无法进行匹配,但这方法在最一开始做中文断词是真的满有用的,比起顺向匹配、逆向匹配,双向匹配的准确度是满高的
  • 统计的机器学习算法:如HMM,CRF (Conditional Random Field),这类方法应该算是目前的大宗吧,Jieba(一个断词的套件)对於不存在於字典的字词就是用统计的方法来处理的
  • 深度学习的算法:LSTM,深度学习的方法应该算是比较新的,但其实就是处理LSTM多对多的模型,之前有看过有人利用双向LSTM+CRF实做断词,有兴趣的可以去找找

我等等下面会以Jieba断词为主,故这边稍微提及一下Jieba的断词方法,他会分成2种部份:

  • 针对存在於字典的字词:
    • step1. 根据字典产生Trie树 (字典树)
    • step2. 根据 Trie 树建立给定输入句的 DAG(有向无环图)
    • step3. 使用Dynamic Programming 来找出最大机率路径,此路径及为基於词频最大的分词结果
  • 针对不存在於字典的字词:
    • 使用隐马可夫模型(HMM) 与维特比演算法(Viterbi) 来进行分词辨识,找出最合适的组合

三. Jieba
Jieba其实算是中文满常用的断词套件,但他对简体效果比较好,繁体效果有些差,如果想要针对繁中断词的话,满推荐CKIP的,但我记得断词速度是满慢的,而且因为他是client-server的架构,还满常发生断线的问题,本人之前硕论再用CKIP断词时很常发生过QQ,最後还是改用jieba了,其他的断词套件如Hanlp最近还满常听到的,听说断词的准确度还不错,但本文为以Jieba为主。

  1. 安装
    总之呢要先安装套件,对python熟的人,应该都知道就是这样安装:
    pip install jieba,然後在自己的python档引入 import jieba 就可以开始用罗

  2. 载入繁体中文的辞典~这个的位置在Jieba的github有提供,这里附上网址

    # 载入繁体辞典
    jieba.set_dictionary('dict.txt.big')
    
  3. Jieba的四种断词模式:

    • 精确模式: Jieba基础的断词模式,也就是基本款
    text_after_jieba = jieba.cut("我爱自然语言处理", cut_all=False) # 精确模式
    print("精确模式: " + "/ ".join(text_after_jieba))
    # output: 精确模式: 我/ 爱/ 自然语言/ 处理
    
    • 全模式: 将cut_all设为true,这个模式下会将可以断的词再继续断开,列出所有可能的词~
    text_after_jieba = jieba.cut("我爱自然语言处理", cut_all=True) # 全模式
    print("全模式: " + "/ ".join(text_after_jieba))
    # output: 全模式: 我/ 爱/ 自然/ 自然语言/ 语言/ 处理
    
    • paddle模式: Jieba导入一个深度学习框架PaddlePaddle来进行分词,据说是利用GRU,必须要先利用jieba.enable_paddle()来启动~
    # 启用paddle模式
    jieba.enable_paddle()
    seg_list = jieba.cut("我爱自然语言处理", use_paddle=True)  # 使用paddle
    print("paddle: " + "/ ".join(seg_list))
    # output: paddle: 我/ 爱/ 自然/ 语言/ 处理
    
    • 搜寻引擎模式: 这个模式跟全模式很像,都可以将词再更切分
    text_after_jieba = jieba.cut_for_search("我爱自然语言处理")  # 搜寻引擎模式
    print("搜寻引擎: " + "/ ".join(text_after_jieba))
    
    # output: 搜寻引擎: 我/ 爱/ 自然/ 语言/ 处理
    

    以上是Jieba提供的四种断词模式,但其实用在简体效果会较好

  4. 辨识新字词:

    • 像上述说的,若Jieba遇到新词,可以透过HMM来预测,如下,这边容我直接用官网例子QQ,没试到好的繁中例子:
    words = jieba.cut("他来到了网易杭研大厦", HMM=True) #HMM 设为 True
    words_list = []
    for word in words:
        words_list.append(word)
    
    print(f'HMM output:{words_list}')
    
    # output: HMM output:['他', '来到', '了', '网易', '杭研', '大厦']
    

    这个例子是辨识了'杭研'这个词,有兴趣的可以试一下

  5. 载入自定义辞典:

    • Jieba也提供载入自订义辞典,例如我建立一个了一个txt,如下:
    韩国瑜
    年终奖金
    
    • 来比较一下载入自定义与没有自定义的差异,载入自定义的方式用jieba.load_userdict('./dict_define.txt')来载入:
    text = '韩国瑜今天颁发年终奖金'
    words = jieba.cut(text)
    words_list = []
    for word in words:
        words_list.append(word)
    
    print(f'output:{words_list}')
    
    jieba.load_userdict('./dict_define.txt')
    
    words = jieba.cut(text)
    words_list = []
    for word in words:
        words_list.append(word)
    
    print(f'output:{words_list}')
    
    # output:['韩国', '瑜', '今天', '颁发', '年终奖金']
    # output:['韩国瑜', '今天', '颁发', '年终奖金']
    

    jieba也支持透过add_word的function来动态增加辞典唷~

  6. Jieba也支持pos tagging,如下范例:

    import jieba.posseg as pseg
    
    words = jieba.posseg.cut('我爱自然语言处理')
    for word, flag in words:
        print(f'{word} {flag}')
    
    # 我 r
    # 爱 v
    # 自然语言 l
    # 处理 v
    

    在繁体上有些POS感觉不是很适合,如果想知道对应的词性,可参考这个网站

    其实Jieba还有满多功能我没介绍的,有兴趣的可以去他们的github看唷~~


这次的篇幅好像不小心拉太长了QQ,明天会说明比较简单的stemming与lemmatization


<<:  html字体的变化

>>:  【Day2】声音的一些基本介绍

[第三十只羊] 迷雾森林终章 决斗,抽牌

天亮了 昨晚是平安夜 关於迷雾森林故事 金色山脉 海马的自爆攻击 让整座迷雾森林火势开始蔓延开来 就...

【Side Project】 寻找日常生活中的问题

正当愁这次Side Project题目要找甚麽来做时,刚好运气不错碰到了一个随机事件。 让我决定了这...

Day 09: 机器学习你知多少?

人工智慧? 机器学习? 深度学习? 刚踏入机器学习的学生自然会对这些专有名词感到相当模糊,我们就先来...

IT 铁人赛 k8s 入门30天 -- day30 Share Process Namespace between Containers in a Pod

参考文件 https://kubernetes.io/docs/tasks/configure-po...

28/AWS SSA面试经验分享(上)

虽然现在欧洲还在work from home的期间,AWS ML Specialist Soluti...