基于词表的中文分词算法

基于词表的中文分词算法

正向最大匹配法

对于输入的一段文本从左至右,以贪心的方式切分出当前位置上长度最大的词.正向最大匹配法是基于词典的分词方法,其分词原理是:单词的颗粒度越大,所能表示的含义越确切.

该算法主要分两个步骤:

  1. 一般从一个字符串的开始位置,选择一个最大长度的词长的片段,如果序列不足最大词长,则选择全部序列.
  2. 首先看该片段是否在词典中,如果是,则算为一个分出来的词,如果不是,则从右边开始,减少一个字符,然后看短一点的这个片段是否在词典中,依次循环,直到只剩下一个.
  3. 序列变为第2步骤截取分词后剩下的部分序列.

示例:

0123456789
posremain charactersstart charactersmax matching
0我毕业于湖北科技学院
1毕业于湖北科技学院毕业
3于湖北科技学院
4湖北科技学院湖北科技学院湖北科技学院

代码实现:

 words_dic = []

def init():
    """
    读取词典文件
    载入词典
    :return:
    """
    with open('dic/dic.txt','r',encoding='utf8') as dic_inp:
        for word in dic_inp:
            words_dic.append(word.strip())

#实现正向匹配算法中的切词方法
def cut_words(raw_sentence,word_dic):
    #统计词典中最长的词
    max_length  = max(len(word) for word in words_dic)
    sentence = raw_sentence.strip()
    #统计序列长度
    words_length = len(sentence)
    #存储切分好的词语
    cut_word_list = []
    while words_length > 0:
        max_cut_length = min(max_length,words_length)
        subSentence = sentence[0 : max_cut_length]
        while max_cut_length > 0:
            if subSentence in words_dic:
                cut_word_list.append(subSentence)
                break
            elif max_cut_length == 1:
                cut_word_list.append(subSentence)
                break
            else:
                max_cut_length = max_cut_length - 1
                subSentence = subSentence[0:max_cut_length]
        sentence = sentence[max_cut_length:]
        words_length = words_length - max_cut_length
    words = "/".join(cut_word_list)
    return words

def main():
    init()
    while True:
        print("请输入您要分词的序列")
        input_str = input()
        if not input_str:
            break
        result = cut_words(input_str,words_dic)
        print("分词结果")
        print(result)

if __name__ == "__main__":
    main()

测试结果:

 请输入您要分词的序列
我毕业于湖北科技学院,就职于华为
分词结果
我/毕业/于/湖北科技学院/,/就职于/华为

逆向最大匹配法

反向最大匹配法的基本原理与正向最大匹配法类似,只是分词顺序变为从左至右

示例

0123456789
posremain charactersstart charactersmax matching
4我毕业于湖北科技学院湖北科技学院
3我毕业于
1我毕业毕业
0

代码实现:

words_dic = []

def init():
    with open('dic/dic.txt','r',encoding="utf8") as dic_input:
        for word in dic_input:
            words_dic.append(word.strip())

#实现逆向最大匹配算法的切词算法
def cut_words(raw_sentence,words_dic):
    max_length = max(len(word) for word in words_dic)
    sentence = raw_sentence.strip()
    words_length = len(sentence)
    cut_word_list = []
    while words_length>0:
        max_cut_length = min(max_length,words_length)
        subSentence = sentence[-max_cut_length:]
        while max_cut_length > 0:
            if subSentence in words_dic :
                cut_word_list.append(subSentence)
                break
            elif max_cut_length == 1 :
                cut_word_list.append(subSentence)
                break
            else:
                max_cut_length = max_cut_length - 1
                subSentence = subSentence[-max_cut_length:]
        sentence = sentence[0:-max_cut_length]
        words_length = words_length - max_cut_length
    cut_word_list.reverse()
    words = "/".join(cut_word_list)
    return words

def main():
    init()
    while True:
        print("请输入您要分词的序列")
        input_str = input()
        if not input_str:
            break
        result = cut_words(input_str,words_dic)
        print("分词结果")
        print(result)
if __name__ == '__main__':
    main()

测试结果:

 请输入您要分词的序列
我毕业于湖北科技学院
分词结果
我/毕业/于/湖北科技学院

双向最大匹配算法

双向最大匹配算法是将正向最大匹配算法得到的分词结果和逆向最大匹配法得到的结果进行比较,从而决定正确的分词方法.

启发式规则

  1. 如果正反向分词结果词数不同,则取分词数量较少的那一个.
  2. 如果分词结果次数相同
    a. 分词结果相同,就说明没有歧义,可返回任意一个.
    b. 分词结果不同,返回单字较少的那个
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值