赞
踩
如何实现准确并且迅速的中文分词一直是自然语言处理领域研究中的基础。
这三类分词技术代表了当前中文分词的发展方向,它们有着各自的优缺点。
基于字符串匹配的分词是通过构建一个固定的词表,对照这个词表,对输入的问句进行字符串截取和字符串匹配。主要原理是将问句从头开始不断切割成若干个子字符串,当所有的子字符串都能够与词表中的某一个单词匹配时,分词即结束。这种分词方法不需要大规模的语料库进行训练,复杂性相对较小,分词速度较快,但该方法过于依赖性词表的质量,当词表足够大时,该方法的优势明显。相反,词表较小时,分词效果较差,且不能识别未登录词。目前,基于字符串匹配的分词法中有最大正向匹配法、最大逆向匹配法和最小切分法等。
首先假设词表中最长的词有 p 个字符,然后对输入的长度为 n 的字符串从头开始,截取其前 p 个字符作为待匹配的字段,若在词表中匹配成功,从剩下的 n-p 个字符中继续匹配。若匹配不成功,则去除前 p 字符中最后一个字符后,对 p-1 个字符进行匹配。如此进行下去,直至长度为 n 的字符串全部匹配成功。
因为停用词对后续文本处理可能会造成干扰,所以在用正向最大匹配算法分词的过程中直接去除了停用词。具体步骤如下:
S1、导入分词词典words.txt,存储为字典形式dic、导入停用词词典stop_list.txt ,存储为字典形式dir_stop、需要分词的文本文件txt_to_cut.txt,存储为字符串chars
S2、遍历分词词典,找出最长的词,其长度为此算法中的最大分词长度max_chars(也就是上面说到的p)
S3、创建空列表word_list存储分词结果
S4、初始化字符串chars的分词起点n=0
S5、判断分词点n是否在字符串chars内(即是否完成分词),即n < len(chars) 如果成立,则进入下一步骤,否则进入S9
S6、根据分词长度i(初始值为max_chars)截取相应的需分词文本chars的字符串s
S7、判断s是否存在于分词词典中
若存在,则分两种情况讨论:
(1)若s是停用词,那么直接删除,分词起点n后移i位,转到步骤S5;
(2)若s不是停用词,那么直接添加到分词结果words中,分词起点n后移i位,转到步骤S5;
若不存在,则分两种情况讨论:
(1)s是停用词,那么直接删除,分词起点后移i位,转到步骤S5;
(2)s不是停用词,分词长度i>1时,分词长度i减少1,转到步骤S6 ,若是此时s是单字,则转入步骤S8;
S8、将s添加到分词结果words中,分词起点n后移1位,转到步骤S5
S9、将需分词文本chars的分词结果words输出到文本文件result.txt中
""" 最大正向匹配算法实现1 codecs 模块 :codecs专门用作编码转换 """ import codecs # 获得分词字典,存储为字典形式 f1 = codecs.open('words.txt', 'r', encoding='utf8') dic = {} while 1: line = f1.readline() if len(line) == 0: break term = line.strip() # 去除字典两侧的换行符,避免最大分词长度出错 dic[term] = 1 f1.close() # 获得需要分词的文本,为字符串形式 f2 = codecs.open('txt_to_cut.txt', 'r', encoding='utf8') chars = f2.read().strip() f2.close() # 获得停用词典,存储为字典形式 f3 = codecs.open('stoplist.txt', 'r', encoding='utf8') stoplist = {} while 1: line = f3.readline() if len(line) == 0: break term = line.strip() stoplist[term] = 1 f3.close() # 正向匹配最大分词算法 # 遍历分词词典,获得最大分词长度 max_chars = 0 for key in dic: if len(key) > max_chars: max_chars = len(key) # 定义一个空列表来存储分词结果 words = [] n = 0 while n < len(chars): matched = 0 # range([start,] stop[, step]),根据start与stop指定的范围以及step设定的步长 step=-1表示去掉最后一位 for i in range(max_chars, 0, -1): # i等于max_chars到1 s = chars[n : n + i] # 截取文本字符串n到n+1位 # 判断所截取字符串是否在分词词典和停用词词典内 if s in dic: if s in stoplist: # 判断是否为停用词 words.append(s) matched = 1 n = n + i break else: words.append(s) matched = 1 n = n + i break if s in stoplist: words.append(s) matched = 1 n = n + i break if not matched: # 等于 if matched == 0 words.append(chars[n]) n = n + 1 # 分词结果写入文件 f3 = open('FMMResult.txt','w', encoding='utf8') f3.write(' '.join('%s' %id for id in words)) f3.close()
实现原理和最大正向匹配法相同,只是匹配的顺序是从字符串的末端开始向前匹配,适用的词表也是逆序的词表。
实现原理是对于输入字符串,枚举其所有分词情况,然后选择分词数量最小的情况。因此大多情况下,分词长度越长,结果会越准确。但此种方法只适用于输入字符串较长度 n 较小的情况下。
基于统计的分词算法的基本原理是利用统计的方法计算字符串在语料库中的出现频率,通过概率计算,判断字符串是否可以单独成词。这种方法不需要固定的词表,核心思想是当相邻的字符出现的次数越多时,这些字符组成一个词的可信度就越大,对未登录词识别展现了很好的优越性。但需要进行大量的文本训练,算法计算周期长,复杂度较高。
基于理解的分词方法是通过让计算机模拟人对句子的理解,达到识别词的效果。其基本思想就是在分词的同时进行句法、语义分析,利用句法信息和语义信息来处理歧义现象。它通常包括三个部分:分词子系统、句法语义子系统、总控部分。在总控部分的协调下,分词子系统可以获得词、句的句法和语义信息来对分词歧义进行判断,即它模拟了人对句子的理解过程[34]。对未登录词有较强的识别能力,不需要词表和大量语料的训练,但需要使用大量的语言知识和信息、完备的规则库。算法复杂,实现技术难度较大,处理速度较慢,目前还处于实验测试阶段。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。