当前位置: 首页 > news >正文

【自然语言处理】正向最大匹配算法(FMM),反向最大匹配算法(BMM)和双向最大匹配算法(BM)原理及实现

目录

一,正向最大匹配算法(FMM)

 二,反向最大匹配算法(RMM)


一,正向最大匹配算法(FMM)

        正向最大匹配分词(Forward maximum matching segmentation)通常简称为FMM法。其基本思想为:假定分词词典中的最长词有i个汉字字符,则用被处理文档的当前字串中的前i个字作为匹配字段,查找字典。若字典中存在这样的一个字词,则匹配成功,匹配字段被作为一个词切分出来。如果词典中找不到这样的一个字词,则匹配失败,将匹配字段中的最后一个字去掉,对剩下的字串重新进行匹配处理。如此进行下去,直到匹配成功,即切分出一个词或剩余字串的长度为零为止。这样就完成了一轮匹配,然后取下一个i字字串进行匹配处理,直到文档被扫描完为止。

例子:

设变量dt为字典,s为待切字符串,result为被切后的词

令dt = ['abc', 'bcd'] ,s = ['abcd'],则 result = ['abc', 'd']

原理:字典中最大字符长度为‘abc’和‘bcd’,正向选取‘abc’,则拿‘abc’去匹配,s中匹配到‘abc’后切出,之后字典中最长的是‘d’,匹配到s的‘d’后切出,得到切片后的result = ['abc', 'd']

代码实现: 

def FMM(dt, s):  # 正向最大匹配算法result = []   max_len = max([len(i) for i in dt])    # 选取字典里长度最大的字符串start = 0while start != len(s):    # 判断列表不为空,建立循环                index = start + max_len    # 从0开始正向索引最大长度的字符串if index > len(s):         # 判断是否溢出列表index = len(s)for _ in range(max_len):    t = s[start:index]       # t是切片if t in dt or len(t) == 1:result.append(t)start = indexbreakindex -= 1 # 为了保证算法能够扫描到所有字符return result

 二,反向最大匹配算法(RMM)

        逆向最大匹配算法(Reserve maximum matching segmentation)的基本原理与正向最大匹配法相同,不同的是分词切分的方向与FMM法相反。逆向最大匹配法从被处理文档的末端开始匹配扫描,每次取最末端的i个字符(为词典中最长词数)作为匹配字段,若匹配失败,则去掉匹配字段最前面的一个字,继续匹配。相应地,它使用的分词词典是逆序词典,其中的每个词条都将按逆序方式存放。在实际处理时,先将文档进行倒排处理,生成逆序文档。然后,根据逆序词典,对逆序文档用正向最大匹配法处理即可。

例子:

设变量dt为字典,s为待切字符串,result为被切后的词

令dt = ['abc', 'bcd'] ,s = ['abcd'],则 result = ['a', 'bcd']

原理:字典中最大长度为'abc',‘bcd’,反向选取‘bcd’,则拿‘bcd’去匹配,s中匹配到‘bcd’后切出,之后字典中最长的是‘a’,匹配到s的‘a’后切出,得到切片后的result = ['a', 'bcd']

代码实现:

def RMM(dt, s): # 反向最大匹配算法result = []max_len = max([len(i) for i in dt]) # 选取字典里长度最大的字符串start = len(s)while start != 0:    #判断列表不为空,建立循环index = start - max_len    # 从列表最后开始索引最大长度的字符串if index < 0:        # 判断是否溢出列表index = 0for _ in range(max_len):t = s[index:start]    # t是切片if t in dt or len(t) == 1:result.insert(0, t)    # 在最前面插入start = indexbreakindex += 1return result

三,双向匹配算法(BM)

        双向最大匹配算法的原理就是将正向最大匹配算法和逆向最大匹配算法进行比较,从而选择正确的分词方式。

        比较原则/步骤:

        1.比较两种匹配算法的结果

        2.如果分词数量结果不同:选择数量较少的那个

        3.如果分词数量结果相同

​                 1.分词结果相同,返回任意一个

​                 2.分词结果不同,返回单字数较少的一个

​                 3.若单字数也相同,任意返回一个

例子:

设变量dt为字典,s为待切字符串,result_1为被正向切后的词,result_2为被反向切后的词

令dt = ['abc', 'deab'] ,s = ['abcdeabc'],则 result_1 = ["abc", "deab", "c"],result_2=["c", "deab"]

原理:字典中最大长度为'deab',则拿‘deab’去匹配,s中匹配到‘deab’后切出,之后字典中最长的是‘abc’,匹配到s的‘abc’后切出,得到切片后的result_1 = ["abc", "deab", "c"],同理result_2=["c", "deab"],其中正向的切词有三个,逆向有两个,数量不相等选择分词数量 少的,则输出逆向切词result_2=["c", "deab"]

def BM(dt, s): # 双向最大切词r1 = FMM(dt, s)r2 = RMM(dt, s)if len(r1) == len(r2):if r1 == r2:return r1else:r1_cnt = len([i for i in r1 if len(i)==1])r2_cnt = len([i for i in r2 if len(i)==1])return r1 if r1_cnt < r2_cnt else r2else:return r1 if len(r1) < len(r2) else r2
http://www.lryc.cn/news/245802.html

相关文章:

  • 数据结构 | 堆排序
  • 编程语言发展史:Go语言的设计和特点
  • FinGPT:金融垂类大模型架构
  • 24. 深度学习进阶 - 矩阵运算的维度和激活函数
  • 杰发科技AC7801——keil工程移植到IAR
  • Word怎么看字数?简单教程分享!
  • 万字解析设计模式之观察者模式、中介者模式、访问者模式
  • 【MySQL | TCP】宝塔面板结合内网穿透实现公网远程访问
  • Python break用法详解
  • 【C++初阶】STL详解(五)List的介绍与使用
  • MySQL特点和基本语句
  • Gin 学习笔记03-参数绑定
  • 【100天精通Python】Day73:python机器学习入门算法详解与代码示例
  • Node.js入门指南(四)
  • Java LeetCode篇-深入了解关于数组的经典解法
  • LeeCode前端算法基础100题(4)- 无重复字符的最长子串
  • Axios简单使用与配置安装-Vue
  • 【初始前后端交互+原生Ajax+Fetch+axios+同源策略+解决跨域】
  • C语言--每日选择题--Day24
  • 记一次简单的PHP反序列化字符串溢出
  • 找工作面试技巧
  • Jackson无缝替换Fastjson
  • JVM 内存分析工具 MAT及实践
  • jupyter notebook 不知道密码,怎么登录解决办法
  • 软著项目推荐 深度学习中文汉字识别
  • WEB渗透—反序列化(七)
  • 牛客网刷题笔记四 链表节点k个一组翻转
  • 【数据结构】图<简单认识图>
  • Git介绍和基础命令解析
  • 力扣hot100 和为 K 的子数组 前缀和