自然语言处理-01中文分词技术

版权声明:转载请注明出处 https://blog.csdn.net/zhouchen1998/article/details/88871149

中文分词技术

  • 简介
    • 自然语言处理的一项核心技术。在语言理解中,词是最小的能够独立活动的有意义的语言成分。将词确定下来是理解自然语言的第一步,只有跨越这一步,中文才能像英文那样过渡到短语划分、概念抽取以及主题分析,已至自然语言理解,最终达到智能计算的最高境界。因此,每个NLP研究者应该掌握最基本的分词技术。
    • “词”这个概念一直是汉语语言学界纠缠不清而又绕不开的问题。“词是什么”(词的抽象定义)和“什么是词”(词的具体界定),这两个问题迄今为止也没有权威、明确的表述,更不可能拿出令人认可的词表来。主要的难点在于汉语结构与英语等语种差异很大,对词的构成边界方面很难界定。
    • 在英语中,单词本身就是“词”的表达,一篇英文文章就是“单词”加分隔符(空格或者逗号和句号)来表示的,而在汉语中,词以字为基本单位的,但是一篇文章的语义表达确实 以词来划分的。因此,在处理中文文本时,需要进行分词处理,将句子转化为词的表示。这个切词处理过程就是中文分词,它通过计算机自动识别出句子的词,在词间加入边界标记符,分隔出各个词汇。整个过程看似简单,然而实践起来确实无比复杂的,主要就是因为中文歧义。
    • 很多句子人来判定都有问题,更不用说机器了。此外,像未登录词、分词粒度粗细等都是影响分词效果的重要因素。
    • 从中文分词提出以来,历经30多年的探索,提出来很多方法,归纳为**规则分词、统计分词和混合分词(规则+统计)**这三个主要流派。
      • 规则分词是最早兴起的办法,主要是通过人工设立词库,按照一定的方式进行匹配切分,其实现简单高效,但对新词很难进行处理。
      • 统计分词是随着机器学习的技术兴起,应用到了分词任务上而产生的,它能够较好应对新词发现等特殊场景。然而,实践中统计分词太过依赖语料的质量。
      • 混合分词是基于前两者的结合,如今大多采用这种方式。
  • 规则分词
    • 基于规则的分词是一种机械分词方法,主要是通过维护词典,在切分语句时将语句的每个字符串与词表中的词逐一匹配,找到则切分,否则不予切分。
    • 按照匹配切分的方式,主要有正向最大匹配法、逆向最大匹配法以及双向匹配法三种。这三种方法每一个都是对前者的优化。
    • 基于规则的分词,一般简单高效,但是词典的维护是一个庞大的工程。在网络发达的今天,新词层出不穷,很难通过词典覆盖所有词。
  • 统计分词
    • 随着大规模语料的建立,统计机器学习方法的研究和发展,基于统计的中文分词算法渐渐成为主流。
    • 其主要思想是把每个词看做是由词的最小单位的各个字组成的,如果相连的字在不同的文本中出现的次数越多,就证明这相连的字很可能就是一个词。因此我们就可以利用字与字相邻出现的频率来反映成词的可靠度,统计语料中相邻出现的各个字的组合的频度,当组合频度高于某一个临界值时,我们便认为此字组可能会构成一个词语。
    • 基于统计的分词一般做如下两个步骤。
      • 建立统计语言模型。
      • 对句子进行单词划分,然后对划分结果进行概率计算,获得概率最大的分词方式。这里就用到了统计学习算法,如隐含马尔可夫(HMM)、条件随机场(CRF)等。
    • 主要的有HMM模型、CRF模型、神经网络分词算法(常采用CNN、LSTM等深度学习网络自动发现一些模式和特征,然后结合CRF、softmax等分类算法进行分词预测。)
    • 对比机械分词法,统计分词方法不需要耗费人力维护词典,能较好地处理歧义和未登录词,是目前分词的主流方法。但是,其分词的效果很依赖训练语料的质量,且计算量很大。
  • 混合分词
    • 事实上,目前不管是基于规则的算法、还是基于HMM、CRF或者深度学习的方法,其分词效果在具体任务中,其实差距并没有多明显。在实际工程应用中,多是基于一种分词方法,然后用其他分词算法加以辅助。如此,能在保证词典分词准确率的基础上,对未登录词和歧义词有较好的识别,jieba就是如此实现的。
  • 中文分词工具Jieba
    • 简介
      • 北大之前开源的pkuseg在我之前的博客有过介绍。
      • 近年来,NLP技术的日益成熟,开源实现的分词工具越来越多,如Ansj、盘古分词等。
      • 相对而言,jieba有着如下优势。
        • 社区活跃。
          • GitHub近10000的star,社区反馈快。
        • 功能丰富
          • 并不只是分词,其实是一个开源框架,提供了很多分词之上的算法,如关键词提取、词性标注等。
        • 多语言实现
          • 官方提供Python、Java、C++、Go、R、iOS等多平台多语言支持,不仅如此,还提供了很多热门社区项目的扩展插件,如ElasticSearch、solr、lucene等。
        • 使用简单
          • API不多,配置不复杂,方便上手。
      • jieba结合了基于规则和统计两种方法。首先,基于前缀字典的词图扫描;然后,对于未登录词,使用基于汉字成词的HMM模型,采用了Viterbi算法进行推导。
    • 安装
      • Python下使用pip安装
        • pip install jieba
    • 三种分词模式(见JiebaDemo)
      • 精确模式(默认)
        • 试图将句子最精确切开,适合文本分析。
      • 全模式
        • 把句子中可以成词的词语都扫描出来,速度很快,但是不能解决歧义。
      • 搜索引擎模式
        • 在精确模式的基础上,对长词再次划分,提高召回率,适合用于搜索引擎分词。
      • 代码
        •   # -*-coding:utf-8-*-
            import jieba
            sentence = "中文分词是文本处理不可或缺的一步!"
            
            seg_list = jieba.cut(sentence, cut_all=True)
            print('全模式', '/'.join(seg_list))
            
            seg_list = jieba.cut(sentence, cut_all=False)
            print('精确模式', '/'.join(seg_list))
            
            seg_list = jieba.cut(sentence)
            print('默认精确模式', '/'.join(seg_list))
            
            seg_list = jieba.cut_for_search(sentence)
            print('搜索引擎模式', '/'.join(sentence))
            
          
      • 运行结果
    • 自定义字典
      • jieba有默认的一套字典,然而很多情况下,不同的应用场合需要不同的字典,jieba支持用户自定义字典,只要分词之前加载即可。
        • jieba.load_userdict('./data/user_dict.utf8')
      • 用户字典格式
        • 每行
          • 词语 词频(可以省略) 词性(可以省略)
        • 需为utf8编码
  • 实战
    • 高频词提取
    • 数据集为搜狗实验室新闻数据
    • 高频词一般指文档中出现频率较高且非无用的词语,其一定程度上代表了文档的焦点所在。针对单篇文档,可以作为关键词看待。对于新闻这样的多篇文档,可以作为热词,发现舆论焦点。
    • 高频词提取其实就是NLP中的TF策略。(后面具体介绍)主要有标点符号和停用词(“的”“了”等无意义词)两个干扰项。
    • 这个项目是使用jieba,针对搜狗实验室新闻数据,进行高频词提取。
    • 代码
      •   # -*-coding:utf-8-*-
          
          
          def get_content(path):
              """
              获取文件内容
              :param path:
              :return:
              """
              with open(path, 'r', encoding='gbk', errors='ignore') as f:
                  content = ''
                  for l in f:
                      l = l.strip()
                      content += l
                  return content
          
          
          def get_TF(words, topK=10):
              """
              计算TF值
              :param words:
              :param topK:
              :return:
              """
              tf_dic = {}
              for w in words:
                  tf_dic[w] = tf_dic.get(w, 0) + 1
              return sorted(tf_dic.items(), key=lambda x: x[1], reverse=True)[:topK]
          
          
          def stop_words(path):
              """
              获取停用词
              :param path:
              :return:
              """
              with open(path, encoding='utf-8') as f:
                  return [l.strip() for l in f]
          
          
          stop_words('./data/stop_words.utf8')
          
          
          def main():
              """
              主模块
              :return:
              """
              # 文件操作模块,允许通配符等
              import glob
              import jieba
              import random
          
              files = glob.glob('./data/news/C000013/*.txt')
              corpus = [get_content(x) for x in files]
              # 随机文字进行高频词提取
              sample_inx = random.randint(0, len(files))
              split_words = [x for x in jieba.cut(corpus[sample_inx]) if x not in stop_words('./data/stop_words.utf8')]
              print('样本之一:' + corpus[sample_inx])
              print('样本分词效果:' + '/ '.join(split_words))
              print('样本的topK(10)词:' + str(get_TF(split_words)))
          
          
          if __name__ == '__main__':
              main()
        
          
        
    • 结果
  • 补充说明
    • 参考书为《Python自然语言处理实战》
    • 具体数据集代码可以查看我的GitHub,欢迎star或者fork

猜你喜欢

转载自blog.csdn.net/zhouchen1998/article/details/88871149