当前位置:   article > 正文

自然语言处理之词性标注_pseg.cut

pseg.cut

        词性标注作为NLP领域的一项基本任务,其与分词任务同等重要,是很多任务的基础,比如句法分析,命名实体识别等。命名实体识别在一定程度上也属于标注任务,不过,难度相比一般的词性标注而言,上升了不少。对于词性标注而言,不论是中文还是英文,其难点在于对于不同的语境,词性的多变化;另一方面,随着社会的发展,很多词都会潜移默化的产生额外的词性。相信这些现象,大家都有所感触,也经常遇到这些情况,就不再举例了。从技术来说,词性标注也依赖于分词,不同的分词,对于结果的标注也会不同,比如“读书”,如果分词结果为“/读/书/”,那显然是“动词+名词”的序列结构;如果是“/读书/”,则是“名词”的单个词性。因此在进行词性标注任务时,一般都需要先将句子进行分词,然后基于分词的结果再进行词性标注。

        目前,词性标注的方法也比较多,在AI领域,有很多词性标注器,这些方法都已经嵌入到成型的自然语言处理工具包中,比如jieba软件,HanLP,NLTK等。然而,从自然语言的层面上来看待词性标注问题,不同的语言,词性标注的难度截然不同,比如英文和中文。对于英文而言,分词不仅相比中文要简单,而且词性标注也相比中文要简单,即使单独通过词的形态学来处理也可以获得很高的标注准确率,这里的词的形态学指的是词的结构,包括前缀,后缀,时态等等,英文的时态丰富,前缀、后缀具有明显的区分标志,甚至不用考虑上下文,就可以获得很好的标注效果。而中文缺少形态变化,不能从词的形态来识别词性;另外一个难点在于,对于不同的词性标注器,其拥有属于自己的一套标注符号集,也就是说,使用不同的标注器,标注的词性可能相同,但是,符号不同,不统一,因为,词类的划分粒度和标记符号不同,目前还没有一个统一的标准,比如LDC标注语料中,将中文词性划分为33类,而北大语料库则分为26类。词类划分标准和标记符号的不统一,以及分词规范的含糊,都给词性标注带来了很大的困难。还有很多问题还未解决,因此,看似这些已经基本解决的NLP基础问题,其实还需要投入很大的研究精力来挖掘潜在的价值。

        词性标注算法从目前的使用情况来看,主要分为两类,一种是基于规则的方法,主要指的是基于字符串匹配的词典查找算法;另外一种是基于数据驱动的方法,比如机器学习方法。首先,基于字符串匹配的词典查找算法,主要过程为:先对句子进行分词,然后从词典中查找每个词语的词性,对其进行标注即可。这种方法非常简单,但是无法解决一词多词性问题。而采用机器学习方法的词性标注算法,比如HMM,CRF等方法具有非常好的效果。对于HMM,其包括3个量,初始状态概率向量、状态转移概率矩阵、观测概率矩阵。在具体的词性标注问题上,观测序列为分词后的句子,状态序列(或者标记序列、隐状态序列都一个意思)为经过标注后的词性标注序列。而模型的3个量可以通过大量的语料计算得到。这样,对于标注问题,很容易计算得到HMM模型参数,再结合分词后的原句子序列,便将问题转换为模型的预测问题,即已知模型和观测序列,来预测标记序列(或者说状态序列)。这是HMM的经典应用场景。

        在工业界,比较常用的中文处理软件包括jieba,hanLP等,在这里,以jieba软件为例,并对其原理进行剖析。jieba的词性标注的结果,对于每个词的词性,采用和ICTCLAS兼容的标记法。使用方法如下:

  1. # -*- coding:utf-8 -*-
  2. import jieba.posseg as pseg
  3. words = pseg.cut("我喜欢研究算法")
  4. for word, flag in words:
  5. print("%s %s" % (word, flag))

运行后,结果如下:

下面对pseg.cut()的原理进行一波分析:

1.准备工作:首先检查词典是否初始化好,如果没有则先初始化词典,比如上面的“红色字体”显示。将句子的编码解码为unicode编码格式。根据正则表达式进行匹配,将输入文本切分成一个个的句子。

2.遍历句子组成的列表,对每一个句子进行单独分词和词性标注。

3.如果句子中含有未登录词,使用HMM进行处理。

jieba分词的主程序源码如下:

  1. def cut(self, sentence, cut_all=False, HMM=True):
  2. '''
  3. 本函数的主要作用是将句子切分成词
  4. 参数:
  5. - sentence: 要被切分的句子,必须是unicode编码,如果是其他编码,必须要解码为unicode
  6. - cut_all: 选择的切分方法,是采用全模式还是精确模式。对于全模式,是为了把句子中所有的可能
  7. 成词的词语都切分出来,速度快,但是不能解决歧义。而精确模式,试图将句子进行
  8. 最精确的切分,一般是我们最想要的结果,适合文本分析。
  9. - HMM: 是否使用HMM,一般对于含有未登录词的句子的分词,采用HMM会获得更好的分词效果
  10. '''
  11. sentence = strdecode(sentence) # 将句子解码为unicode编码
  12. # 模式选择,对于不同的模式,选择不同的正则表达式对象
  13. if cut_all:
  14. re_han = re_han_cut_all
  15. re_skip = re_skip_cut_all
  16. else:
  17. re_han = re_han_default
  18. re_skip = re_skip_default
  19. # 设置不同模式下的cut_block的分词方法
  20. if cut_all:
  21. cut_block = self.__cut_all
  22. elif HMM:
  23. cut_block = self.__cut_DAG
  24. else:
  25. cut_block = self.__cut_DAG_NO_HMM
  26. blocks = re_han.split(sentence)
  27. # 先采用正则表达式进行粗切分,通过yield返回词语生成器,生成器的好处是可以节约内存
  28. for blk in blocks:
  29. if not blk:
  30. continue
  31. if re_han.match(blk):
  32. for word in cut_block(blk):
  33. yield word
  34. else:
  35. tmp = re_skip.split(blk)
  36. for x in tmp:
  37. if re_skip.match(x):
  38. yield x
  39. elif not cut_all:
  40. for xx in x:
  41. yield xx
  42. else:
  43. yield x

分词之后,便可以进行词性标注了,这里主要介绍如何使用HMM来对未登录词进行处理。通过大规模的语料计算,可以计算得到HMM的参数,然后结合模型的预测算法,将观测序列(分词之后的句子)转换为标注序列(状态序列)。这样便完成了未登录词的词性标注。

        最后,做个总结。jieba作为一个高效的NLP软件包,它可以在分词的同时完成词性标注,因此标注的速度是非常快的。而且,在整个过程中,通过字典查询的方法识别词的词性,通过HMM模型来完成对未登录词的词性标注,从而达到对整个句子的分词和词性标注。但是,字典查询的方式无法解决一词多词性的问题,因此,在精度上还是有所欠缺的。关于jieba软件的更多细节,请参见官方源码https://github.com/fxsjy/jieba。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/588734
推荐阅读
相关标签
  

闽ICP备14008679号