【NLP CODE】基于词典的中文分词算法1:最大匹配法

REF:https://zhuanlan.zhihu.com/p/103392455

# 正向最大匹配法(FMM,Forward Maximum Matching)
# 反向最大匹配法(BMM, Backward Maximum Matching)
# 双向最大匹配法 首先看两种方法结果的分词数,分词数越少越好;分词数相同的情况下,看单个词的数量,越少越好
 
FMM.py
def FMM_func(user_dict, sentence):
    """
    正向最大匹配(FMM)
    :param user_dict: 词典
    :param sentence: 句子
    """
    # 词典中最长词长度
    max_len = max([len(item) for item in user_dict])
    start = 0
    while start != len(sentence):
        index = start + max_len
        if index>len(sentence):
            index = len(sentence)
        for i in range(max_len):
            if (sentence[start:index] in user_dict) or (len(sentence[start:index])==1):
                print(sentence[start:index], end='/')
                start = index
                break
            index += -1

 

BMM.py

def BMM_func(user_dict, sentence):
    """
    反向最大匹配(BMM)
    :param user_dict:词典
    :param sentence:句子
    """
    
    max_len = max([len(item) for item in user_dict]) # 词典中最长词长度
    result = []
    start = len(sentence)
    #print("start:"+str(start))
    #print("max_len:"+str(max_len))
    while start != 0:
        index = start - max_len
        #print("start:"+str(start))
        #print("max_len:"+str(max_len))
        #print("index:"+str(index))
        if index < 0: # 如果最大词出了界线,从边界开始算
            index = 0
            #break
        for i in range(max_len):
            if (sentence[index:start] in user_dict) or (len(sentence[start:index])==1):
                result.append(sentence[index:start])
                start = index
                break
            index += 1

    for i in result[::-1]:
        print(i, end='/')

TestMaxWords1.py

# https://zhuanlan.zhihu.com/p/103392455
# 正向最大匹配法(FMM,Forward Maximum Matching)
# 反向最大匹配法(BMM, Backward Maximum Matching)
# 双向最大匹配法 首先看两种方法结果的分词数,分词数越少越好;分词数相同的情况下,看单个词的数量,越少越好

from FMM import FMM_func
from BMM import BMM_func

sentence = '我们在野生动物园玩'
user_dict = ['我们', '', '在野', '生动', '野生', '动物园', '野生动物园', '','']

FMM_func(user_dict, sentence)
print()
BMM_func(user_dict, sentence)

# 如:“我们在野生动物园玩”
# 正向最大匹配法,最终切分结果为:“我们/在野/生动/物/园/玩”,其中,两字词3个,单字字典词为2,非词典词为1('物'不在词典)。
# 逆向最大匹配法,最终切分结果为:“我们/在/野生动物园/玩”,其中,五字词1个,两字词1个,单字字典词为2,非词典词为0。
# 非字典词:正向(1)>逆向(0)(越少越好)
# 单字字典词:正向(2)=逆向(2)(越少越好)
# 总词数:正向(6)>逆向(4)(越少越好)
# 因此最终输出为:逆向结果。逆向结果是正确的。

TestMaxWords2.py

# https://www.cnblogs.com/dahuang123/p/11990651.html


from FMM import FMM_func
from BMM import BMM_func

sentence = '他是研究生物化学的'
user_dict = ['','','研究','研究生','生物','物化','化学','生物化学','','']

FMM_func(user_dict, sentence)
print()
BMM_func(user_dict, sentence)

# 他/是/研究生/物化/学/的/
# 他/是/研究/生物化学/的/
# 非字典词:正向(0)=逆向(0)(越少越好)
# 单字字典词:正向(4)>逆向(3)(越少越好)
# 总词数:正向(6)>逆向(5)(越少越好)
# 因此最终输出为:逆向结果。逆向结果是正确的。

TestMaxWords3.py

from FMM import FMM_func
from BMM import BMM_func

sentence = '商品和服务'
user_dict = ['商品','','和服','服务']

FMM_func(user_dict, sentence)
print()
BMM_func(user_dict, sentence)

# 商品/和服/务/
# 商品/和/服务/
# 非字典词:正向(0)=逆向(0)(越少越好)
# 单字字典词:正向(1)=逆向(1)(越少越好)
# 总词数:正向(3)>逆向(3)(越少越好)
# 因此最终输出为:不确定。逆向结果是正确的。

 TestMaxWords4.py

from FMM import FMM_func
from BMM import BMM_func

sentence = '南京市长江大桥'
user_dict = ['南京','南京市','','市长','长江','大桥','江大桥']

FMM_func(user_dict, sentence)
print()
BMM_func(user_dict, sentence)

# 南京市/长江/大桥/
# 南京/市长/江大桥/
# 非字典词:正向(0)=逆向(0)(越少越好)
# 单字字典词:正向(0)=逆向(0)(越少越好)
# 总词数:正向(3)=逆向(3)(越少越好)
# 因此最终输出为:不确定。正向结果是正确的。

 TestMaxWords5.py

from FMM import FMM_func
from BMM import BMM_func

sentence = '下雨天留客天留我不留'
user_dict = ['','','下雨','雨天','','留客','','','不留','']

FMM_func(user_dict, sentence)
print()
BMM_func(user_dict, sentence)

输出:

下雨/天/留客/天/留/我/不留//雨天/留客/天/留/我/不留/
原文地址:https://www.cnblogs.com/hbuwyg/p/13236459.html