基于词典的中文分词-前向/后向最大匹配(Python)

说明

当前自然语言处理的理论都是基于西方语言学,而这些语言学结论大部分是从英语等语言中归纳出来的。那么问题来了:
对汉语适用吗?
不知道有没有人想过想过这个问题,反正多少年了搞中文信息处理的人都是这么用的,我们很自然地接受了语法、词、句法等概念,于是,中文信息处理的第一步便是所谓的“分词”。但我这里保留自己的观点:我认为汉语有没有“词”“句法”等概念还待研究。
这也是我为什么打算不做自然语言处理方向的原因。
话虽这么说,但是课程大作业还是要做的……之前倔强地想用c语言实现中文分词,被同学劝退了。于是入门Python,以下程序是本人人生第一个Python程序。小白一个,瞎写着玩的。
环境:pycharm

算法描述

基于词典的前向最大匹配算法是最粗糙地、最简单的实现中文分词功能的手段。给我一个词典,找出词典中最长词的字数(m),再给我段落,从头开始,先看前m个字,是否在词典里,不在的话看m-1个字符串是不是在词典里,以此类推,找到一个词就输出判断剩余文本。
后向和前向的差别就是它不是从头开始,而是从最后开始,看倒数第m个字符串是不是。

代码

为了方便,代码是这么运行的:先将要分词的文本写成str.txt文本文档放在一样的目录里;词典文件名dictionary.txt也放在同一目录下;结果会保存在data.txt文件中。
先放前向的代码(我觉得我的注释还是很详细的……):

#子函数:判断输入的str是否在词典里
def search(str):
    lens=len(str)
    j=0
    for i in range(lendict):
        temp=dict[i:i+lens]
        if(str==temp):
            j=1 #存在的话返回1
            break
    return j

#主函数
dic=open("dictionary.txt", "r", encoding="utf-8")
dict=dic.read()
lendict=len(dict) #字典总长度
#词典中最长词的长度
m=5

str=open("str.txt","r",encoding="utf-8")
sentence=str.read()
n=len(sentence) #待切分句子总长度

j=0
p=0
word='F '
while(p<n):
    if(n<=m):
        print(sentence)
        break

    elif(n>m):
        e=p+m
        i=0
        while(j!=1):
            if(p>n):
                p=n
            #如果只有一个字直接输出
            if(len(sentence[p:e-i])==1):
                word=word+sentence[p:e-i]+' '
                p=p+1
                e=p+(m-1)
                break
            #调用子函数判断
            j=search(sentence[p:e-i])
            if(j==1):
                word=word+sentence[p:e-i]+' '
                p=p+len(sentence[p:e-i])
                e=p+(m-1)
                j=0
                i=0
                break

            i=i+1

with open('data.txt','a+',encoding='utf-8') as f:
    f.write(word+'\n')
print(word[2:len(word)])

dic.close()
str.close()

缺点很明显:暴力搜索,没有技巧可言。
再放后向的:

#子函数:判断输入的str是否在词典里
def search(str):
    lens=len(str)
    j=0
    for i in range(lendict):
        temp=dict[i:i+lens]
        if(str==temp):
            j=1 #存在的话返回1
            break
    return j

#主函数
dic=open("dictionary.txt", "r", encoding="utf-8")
dict=dic.read()
lendict=len(dict) #字典总长度
#词典中最长词的长度
m=5

str=open("str.txt","r",encoding="utf-8")
sentence=str.read()
n=len(sentence) #待切分句子总长度

j=0
p=n
word=' B'
while(p>0):
    if(n<=m):
        print(sentence)
        break

    elif(n>m):
        b=p-m
        i=0
        while(j!=1):
            if(p<m):
                b=0
            #如果只有一个字直接输出
            if(len(sentence[b+i:p])==1):
                word=sentence[b+i:p]+' '+word
                p=p-1
                b=p-m
                break
            #调用子函数判断
            j=search(sentence[b+i:p])
            if(j==1):
                word=sentence[b+i:p]+' '+word
                p=p-len(sentence[b+i:p])
                b=p-m
                j=0
                i=0
                break

            i=i+1

with open('data.txt','a+',encoding='utf-8') as f:
    f.write('B '+word[0:len(word)-2]+'\n')
print(word[0:len(word)-2])

dic.close()
str.close()

结果

最后放一张结果图:依次运行前向、后向后的结果:
基于词典的中文分词-前向/后向最大匹配(Python)_第1张图片

你可能感兴趣的:(基于词典的中文分词-前向/后向最大匹配(Python))