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

本文主要是介绍【自然语言处理】正向最大匹配算法(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

这篇关于【自然语言处理】正向最大匹配算法(FMM),反向最大匹配算法(BMM)和双向最大匹配算法(BM)原理及实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/419710

相关文章

redis中使用lua脚本的原理与基本使用详解

《redis中使用lua脚本的原理与基本使用详解》在Redis中使用Lua脚本可以实现原子性操作、减少网络开销以及提高执行效率,下面小编就来和大家详细介绍一下在redis中使用lua脚本的原理... 目录Redis 执行 Lua 脚本的原理基本使用方法使用EVAL命令执行 Lua 脚本使用EVALSHA命令

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依