【自然语言处理】正向最大匹配算法(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

相关文章

SpringBoot结合Docker进行容器化处理指南

《SpringBoot结合Docker进行容器化处理指南》在当今快速发展的软件工程领域,SpringBoot和Docker已经成为现代Java开发者的必备工具,本文将深入讲解如何将一个SpringBo... 目录前言一、为什么选择 Spring Bootjavascript + docker1. 快速部署与

Linux下删除乱码文件和目录的实现方式

《Linux下删除乱码文件和目录的实现方式》:本文主要介绍Linux下删除乱码文件和目录的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下删除乱码文件和目录方法1方法2总结Linux下删除乱码文件和目录方法1使用ls -i命令找到文件或目录

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

mybatis执行insert返回id实现详解

《mybatis执行insert返回id实现详解》MyBatis插入操作默认返回受影响行数,需通过useGeneratedKeys+keyProperty或selectKey获取主键ID,确保主键为自... 目录 两种方式获取自增 ID:1. ​​useGeneratedKeys+keyProperty(推

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被

Qt使用QSqlDatabase连接MySQL实现增删改查功能

《Qt使用QSqlDatabase连接MySQL实现增删改查功能》这篇文章主要为大家详细介绍了Qt如何使用QSqlDatabase连接MySQL实现增删改查功能,文中的示例代码讲解详细,感兴趣的小伙伴... 目录一、创建数据表二、连接mysql数据库三、封装成一个完整的轻量级 ORM 风格类3.1 表结构

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过

Python中将嵌套列表扁平化的多种实现方法

《Python中将嵌套列表扁平化的多种实现方法》在Python编程中,我们常常会遇到需要将嵌套列表(即列表中包含列表)转换为一个一维的扁平列表的需求,本文将给大家介绍了多种实现这一目标的方法,需要的朋... 目录python中将嵌套列表扁平化的方法技术背景实现步骤1. 使用嵌套列表推导式2. 使用itert