您的位置:首页 > 编程语言 > Python开发

python 实现机械分词(1)-正向最大匹配算法

2017-07-20 09:43 1171 查看
        词语是自然语言处理中重要的知识载体和基本操作单元, 但是中文里词与词之间没有很明显的标记,它们都是连续的字符串,所以文本处理的第一步是怎样进行中文分词。分词是添加合适的显性的词语边界标志使得所形成的词串反映句子的本意的过程。分词主要有基于字符串匹配的方法、基于规则的方法和基于统计的方法,本文主要通过python实现基于字符串匹配的方法也称为机械分词中的两类方法:正向最大匹配算法和逆向最大匹配算法,有实验表明逆向最大匹配算法比正向最大匹配算法更有效。

       基于字符串匹配的分词法是一种的机械分词方法,根据分词词典和一个基本的切分规则,最常用的规则为最长匹配原则。最长匹配方法的思想简单:一个正确的分词结果应该由合法的词组成,而这些词是根据所选词典中的词比较分出。按照所扫描方向的不同,分词的匹配方法分为正向匹配和逆向匹配;按照长度不同优先匹配的情况,分为最长匹配和最短匹配;按照是否与词性标注的过程相结合又可分为分词与标注相结合的一体化和单纯的分词方法。

       1、正向最大匹配算法

      正向最大匹配算法(MM)的思想是假设自动分词中最长词条所含汉字的个数为n, 则截取需要分词文本中当前字符串序列中的前n个字符作为匹配字段,查找分词词典,若词典中有这样一个n字词那么就匹配成功,匹配字段作为一个词被切分出来;若词典中找不到这样的一个n字词那么匹配失败, 匹配字段去掉最后一个汉字, 剩下的字符作为新的匹配字段再进行匹配,如此进行下去,直到匹配成功为止。因为停用词对后续文本处理可能会造成干扰,所以在用正向最大匹配算法分词的过程中直接去除了停用词。具体步骤如下:

      S1、导入分词词典words.txt,存储为字典形式dic、导入停用词词典stoplis.txt ,存储为字典形式stoplis、需要分词的文本文件 test.txt,存储为字符串chars

      S2、遍历分词词典,找出最长的词,其长度为此算法中的最大分词长度max_chars 

      S3、创建空列表words存储分词结果

      S4、初始化字符串chars的分词起点n=0

      S5、判断分词点n是否在字符串chars内,即n < len(chars)  如果成立,则进入下一步骤,否则进入S9

      S6、根据分词长度i(初始值为max_chars)截取相应的需分词文本chars的字符串s 

      S7、判断s是否存在于分词词典中,若存在,则分两种情况讨论,一是s是停用词,那么直接删除,分词起点n后移i位,转到步骤5;二是s不是停用词,那么直接添加到分词结果words中,分词起点n后移i位,转到步骤5;若不存在,则分两种情况讨论,一是s是停用词,那么直接删除,分词起点后移i位,转到步骤5;二是s不是停用词,分词长度i>1时,分词长度i减少1,转到步骤6 ,若是此时s是单字,则转入步骤8;

      S8、将s添加到分词结果words中,分词起点n后移1位,转到步骤5

      S9、将需分词文本chars的分词结果words输出到文本文件result.txt中

       具体实现代码如下:

import codecs

#获得分词字典,存储为字典形式
f1=codecs.open('words.txt','r',encoding='gbk')
dic={}
while 1:
line=f1.readline()
if len(line)==0:
break
term=line.strip().replace('\r\n','')#去除字符串两侧的换行符,避免取最大分词长度时出差错
dic[term]=1
f1.close

#获得需要分词的文本,为字符串形式
f2=codecs.open('test.txt','r',encoding='gbk')
chars=f2.read().strip().replace('\r\n','') #去除字符串两侧的换行符,避免截词时出差错
f2.close

#获得停用词典,存储为字典形式
f3=codecs.open('stoplis.txt','r',encoding='gbk')
stoplis={}
while 1:
line=f3.readline()
if len(line)==0:
break
term=line.strip()
stoplis[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
for i in xrange(max_chars,0,-1):
s=chars[n:n+i]
#判断所截取字符串是否在分词词典和停用词典内
if s in dic:
if s in stoplis:
matched=1
n=n+i
break
else:
words.append(s.encode('gbk'))
matched=1
n=n+i
break
if s in stoplis:
matched=1
n=n+i
break
if not matched:
words.append(chars
.encode('gbk'))
n=n+1

#将分词的结果存入新的文本文件中
f3=open('result.txt','w')
f3.write("\t".join(words))
f3.close


        
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: