理论:NLP学习路径(三):NLP中文分词技术

1、中文分词简介
难点:分词歧义
方法:
1)规则分词:人工建立词库,按一定方式匹配切分。缺点:对新词很难进行处理。
2)统计分词:利用机器学习技术。缺点:过于依赖语料的质量。
3)混合分词:上述两种方法的结合。(用得较多)

2、规则分词
主要是通过维护词典,在切分语句时,将语句的每个字符串与词表中的词进行逐一匹配,找到则切分,否则不予切分。
主要方法有:正向最大匹配法;逆向最大匹配法;双向最大匹配法。
(1)正向最大匹配法
算法描述:
1)从左向右取待切分汉语句的m个字符串作为匹配字段,m为机器词典中最长词条的字符数。
2)查找机器词典并进行匹配。若成功,则将这个匹配字段作为一个词切分出来。若不成功,则将这个匹配字段的最后一个词去掉,剩下的字符串作为新的匹配字段,进行再次匹配,重复以上过程,直到切分出所有词。
例子:

# -*- coding: utf-8 -*

class MM(object):
    def __init__(self):
        self.window_size = 3


    def cut(self, text):
        result = []
        index = 0
        text_length = len(text)
        dic = ['研究', '研究生', '生命', '命', '的', '起源']
        while text_length > index:
            for size in range(self.window_size+index, index, -1):  # 3,0,1
                piece = text[index:size]
                if piece in dic:
                    index = size-1
                    break  # 打破最小封闭的for或者while循环
            index += 1
            result.append(piece+'---')
        print(result)


if __name__ == '__main__':
    text = '研究生命的起源'
    tokenizer = MM()
    print(tokenizer.cut(text))


输出:(效果不好)

(2)逆向最大匹配法(RMM)
算法描述:
从被处理文档的末端开始匹配扫描,每次取最末端的i个字符(i为词典中最长词数)作为匹配字段,若匹配失败,则去掉匹配字段最前面的一个字,继续匹配。在实际中,先将文档进行倒排处理,生成逆序文档,最后根据逆序词典,对逆序文档用RMM算法。
例子

# -*- coding: utf-8 -*

class RMM(object):
    def __init__(self):
        self.window_size = 3


    def cut(self, text):
        result = []
        index = len(text)
        text_length = len(text)
        dic = ['研究', '研究生', '生命', '命', '的', '起源']
        while index > 0:
            for size in range(index-self.window_size, index):
                piece = text[size:index]
                if piece in dic:
                    index = size+1
                    break  # 打破最小封闭的for或者while循环
            index -= 1
            result.append(piece+'---')
        result.reverse()
        print(result)


if __name__ == '__main__':
    text = '研究生命的起源'
    tokenizer = RMM()
    print(tokenizer.cut(text))


输出:

(3)双向最大匹配法
算法描述:将正向最大匹配法得到的分词结果和逆向最大匹配法得到的结果进行比较,然后按照最大匹配原则,选取词数切分最少的作为结果。
规则:
1)如果正反向分词结果词数不同,则取分词数量较少的那个
2)如果分词数量相同
①分词结果相同,可以返回任意一个
②分词结果不同,返回其中单个字较少的那个
例子
正向和逆向代码同上

if __name__ == '__main__':
    text = '研究生命的起源'
    tokenizer1 = MM()
    tokenizer2 = RMM()
    result_MM = tokenizer1.cut(text)
    result_RMM = tokenizer2.cut(text)
    len_MM = len(result_MM)
    len_RMM = len(result_RMM)
    if len_MM != len_RMM:  # 正反向词数不同
        if len_MM < len_RMM:
            result = result_MM
        else:
            result = result_RMM
    else:  # 分词结果数相同
        if operator.eq(result_MM, result_RMM):  # 两个分词结果相同
            result = result_MM  # 返回任意一个
        else:  # 分词结果不同,返回单个字数较少的那个
            min_MM = (x for x in result_MM if len(x) == 4)  # 返回MM中的单个字
            min_RMM = (x for x in result_RMM if len(x) == 4)  # 返回RMM中的单个字
            min_len_MM = len(list(min_MM))
            min_len_RMM = len(list(min_RMM))
            if min_len_MM > min_len_RMM:
                result = result_RMM
            else:
                result = result_MM
    print(result)


输出:


3、统计分词
(1)主要算法思想:
1)建立统计语言模型
2)对句子进行单词划分,然后对划分结果进行概率计算,获得概率最大的分词方式。会涉及到统计学习算法:隐含马尔可夫,条件随机场等
(2)语言模型
1)描述:为长度为m的字符串确定其概率分布,其中w1到wm依次表示文本中的各个词语。一般采用链式法则计算其概率值

当文本过长时,每一项计算难度都很大。可以使用n元模型降低计算难度。一般使用频率计数的比例计算n元条件概率。

  表示词语在语料库中出现的总次数。
当n越大时,模型包含的词序信息越丰富,计算量随之变大。同时,长度越长的文本序列出现的次数也会减少,所以会出现分子分母为零的情况,因此在n元模型中需要配合平滑算法解决,比如拉普拉斯平滑算法等。
 

(3)HMM(隐马尔可夫)模型
算法思想:
每个字在构造一个特定的词语时都占据着一个确定的构词位置(词位),现规定每个字最多只有四个构词位置:B(词首)、M(词中)、E(词尾)、S(单独成词),就可以形成逐字标注的形式。比如:
①中文/分词/是/文本处理/不可或缺/的/一步!
②中/B文/E分/B词/E是/S文/B本/M处/M理/E不/B可/M或/M缺/E的/S一/B步/E!/S
用数学抽象表示如下:用λ=λ1λ2…λn代表输入的句子,n为句子长度,λi表示字(包括标点等非中文字符),o=o1o2…on代表输出的标签,理想的输出为:max = maxP(o1o2…on|λ1λ2…λn)。但无法进行精确地计算P,需要引入观测独立性假设,即每个字的输出仅仅与当前字有关。但会出现类似BBB、BEM等不合理的输出。
HMM就是用来解决该问题的一个方法,通过贝叶斯公式可以得到:
P(o|λ)=P(λ|o)P(o)/P(λ)
最大化P(o|λ)等价于最大化P(λ|o)P(o),常用方法是Veterbi算法(动态规划方法)。算法思想:如果最终的最优路径经过某个oi,那么从初始节点到oi-1点的路径必然也是一个最优路径——因为每一个节点oi只会影响前后两个P(oi-1|oi)和P(oi|oi+1)。
(4)其他统计分词方法
条件随机场方法:区别于隐马尔可夫算法(每个状态只与它前面的状态有关),条件随机场使得每个状态不仅与它前面的状态有关,还与它后面的状态有关。
神经网络分词算法:采用CNN,LSTM等深度学习网络自动发现一些特征和模式,然后结合CRF和softmax等分类算法进行分词预测。
对比机械分词法:能较好处理歧义和未登录词。但分词效果很依赖语料质量,计算量比机械分词大很多。

HMM算法实现的Github地址

4、混合分词
先基于词典的方式进行分词,然后再用统计分词的方法进行辅助。能保证词典分词准确率的基础上,对未登录词和歧义词有较好的识别。


5、中文分词工具——Jieba
Jieba分词结合了基于规则和基于统计这两类方法。首先基于前缀词典进行词图扫描,前缀词典是指词典中的词按照前缀包含得到顺序排列,从而形成一种层级包含结构。基于前缀词典可以快速构建包含全部可能分词结果的有向无环图,这个图包含多条分词路径。基于标注语料,使用动态规则的方法可以找出最大概率路径,并将其作为最终的分词结果。
使用 pip install Jieba 安装
(1)三种分词方式
1)精确模式:将句子最精确地分开,适合文本分析。
2)全模式:把句子中所有可以成词的词语都扫描出来,但是不能解决歧义。
3)搜索引擎模式:在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。
例子:
(2)实战:高频词提取
高频词提取方法及实现

参考:《python自然语言处理实战 核心技术与算法》
 

你可能感兴趣的:(NLP,中文分词,规则分词,统计分词)