Python自然语言处理之切分算法详解


Posted in Python onApril 25, 2021

一、前言

我们需要分析某句话,就必须检测该条语句中的词语。

一般来说,一句话肯定包含多个词语,它们互相重叠,具体输出哪一个由自然语言的切分算法决定。常用的切分算法有完全切分、正向最长匹配、逆向最长匹配以及双向最长匹配。

本篇博文将一一介绍这些常用的切分算法。

二、完全切分

完全切分是指,找出一段文本中的所有单词。

不考虑效率的话,完全切分算法其实非常简单。只要遍历文本中的连续序列,查询该序列是否在词典中即可。上一篇我们获取了词典的所有词语dic,这里我们直接用代码遍历某段文本,完全切分出所有的词语。代码如下:

from pyhanlp import *


def load_dictionary():
    IOUtil = JClass('com.hankcs.hanlp.corpus.io.IOUtil')
    path = HanLP.Config.CoreDictionaryPath.replace('.txt', '.mini.txt')
    dic = IOUtil.loadDictionary([path])
    return set(dic.keySet())


def fully_segment(text, dic):
    list = []
    for i in range(len(text)):
        for j in range(i + 1, len(text) + 1):
            temp = text[i:j]
            if temp in dic:
                list.append(temp)
    return list


if __name__ == "__main__":
    dic = load_dictionary()
    print(fully_segment("在绝对实力面前,一切的说辞都是枉然", dic))

Python自然语言处理之切分算法详解

可以看到,完全切分算法输出了文本中所有的单字与词汇。
这里的算法原理是:开始遍历单个字,以该字为首,将后面每个字依次组合到单个字中,分析出这些组合字句是否在词典中。第二次,从第二个字开始,组合后面的字,以此类推。不懂的看下图就明白了。

Python自然语言处理之切分算法详解

三、正向最长匹配

虽然说完全切分能获取到所有出现在字典中的单词,单字,但是我们获取语句中单字一般来说没有任何意义,我们更希望获取的是中文分词,那种具有意义的词语序列。

比如,上面我们希望“绝对实力”成为一整个词,而不是“绝对”+“实力”之类的碎片。为了达到这个目的,我们需要完善一下我们的算法。考虑到越长的单词表达的意义更加的丰富,于是我们定义单词越长优先级越高。

具体来说,就是在某个下标为起点递增查词的过程中,优先输出更长的单词,这种规则被称为最长匹配算法。该下标的扫描顺序如果从前往后,则称为正向最长匹配,反之则为逆向最长匹配。

下面,我们来实现正向最长匹配,代码如下:

def forward_segment(text, dic):
    list = []
    i = 0
    while i < len(text):
        long_word = text[i]
        for j in range(i + 1, len(text) + 1):
            word = text[i:j]
            if word in dic:
                if len(word) > len(long_word):
                    long_word = word
        list.append(long_word)
        i += len(long_word)
    return list

算法的原理:首先通过while循环判断i是否超出了字符串的大小,如果没有,获取当前第一个字符串为第一个最长匹配结果,接着遍历第一个字符串的所有可能组合结尾,如果在字典中,判断当前词语是否大于前面的最长匹配结果,如果是替换掉最长。遍历完成之后,将最长的结果添加到列表中,然后再获取第二字符,遍历所有结尾组合,获取最长匹配。以此类推。

四、逆向最长匹配

既然了解了正向如何匹配,那么逆向算法应该也很好写。代码如下:

def backward_segment(text, dic):
    list = []
    i = len(text) - 1
    while i >= 0:
        long_word = text[i]
        for j in range(0, i):
            word = text[j:i + 1]
            if word in dic:
                if len(word) > len(long_word):
                    long_word = word
                    break
        list.append(long_word)
        i -= len(long_word)
    return list

算法的原理:就是上面的正向反过来,但是这里并不是倒推文字,文字还是按语句的顺序,但是长度是从最长到最短,也就是遇到第一个就可以返回了添加了。比正向最长匹配算法节约时间。

五、双向最长匹配

虽然逆向比正向节约时间,但本身有一个很大的漏洞。假如我现在的句子中有一段“项目的”字符串,那么正向会出现“项目”,“的”两个词汇,而逆向会出现:“项”,“目的”两个词汇。

为此,我们的算法工程师提出了新的匹配规则,双向最长匹配。这是一种融合两种匹配方法的复杂规则,流程如下:

同时执行正向和逆向最长匹配,若两者的词数不同,则返回词数更少的一个否则,返回两者中单字更少的那一个。当单字也相同时,优先返回逆向最长匹配结果

具体代码如下:

#统计单字个数
def count_single_char(list):
    return sum(1 for word in list if len(word) == 1)

#双向匹配算法
def bidirectional_segment():
    f = forward_segment("在绝对实力面前,一切的说辞都是枉然", dic)
    b = backward_segment("在绝对实力面前,一切的说辞都是枉然", dic)
    if len(f) < len(b):
        return f
    elif len(f) > len(b):
        return b
    else:
        if count_single_char(f)<count_single_char(b):
            return f
        else:
            return b

到此这篇关于Python自然语言处理之切分算法详解的文章就介绍到这了,更多相关python切分算法内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
在Lighttpd服务器中运行Django应用的方法
Jul 22 Python
浅谈Python中列表生成式和生成器的区别
Aug 03 Python
用Python实现命令行闹钟脚本实例
Sep 05 Python
Anaconda下安装mysql-python的包实例
Jun 11 Python
python学生信息管理系统(完整版)
Apr 05 Python
Python3爬虫爬取百姓网列表并保存为json功能示例【基于request、lxml和json模块】
Dec 05 Python
python打印n位数“水仙花数”(实例代码)
Dec 25 Python
python实现音乐播放器 python实现花框音乐盒子
Feb 25 Python
python两种获取剪贴板内容的方法
Nov 06 Python
Python做图像处理及视频音频文件分离和合成功能
Nov 24 Python
python openssl模块安装及用法
Dec 06 Python
Github 使用python对copilot做些简单使用测试
Apr 14 Python
Python网络编程之ZeroMQ知识总结
Python 文本滚动播放器的实现代码
Apr 25 #Python
Python基于Opencv识别两张相似图片
matplotlib之pyplot模块实现添加子图subplot的使用
python实现简单区块链结构
python实现图片九宫格分割的示例
详解python中[-1]、[:-1]、[::-1]、[n::-1]使用方法
Apr 25 #Python
You might like
Firefox中beforeunload事件的实现缺陷浅析
2012/05/03 Javascript
js获取元素到文档区域document的(横向、纵向)坐标的两种方法
2013/05/17 Javascript
javascript中的原型链深入理解
2014/02/24 Javascript
兼容最新firefox、chrome和IE的javascript图片预览实现代码
2014/08/08 Javascript
HTML+CSS+JS实现完美兼容各大浏览器的TABLE固定列
2015/04/26 Javascript
jQuery插件制作之参数用法实例分析
2015/06/01 Javascript
CSS中position属性之fixed实现div居中
2015/12/14 Javascript
JavaScript控制浏览器全屏及各种浏览器全屏模式的方法、属性和事件
2015/12/20 Javascript
AngularJS监听路由变化的方法
2017/03/07 Javascript
vue实现全选和反选功能
2017/08/31 Javascript
微信小程序开发之IOS和Android兼容的问题
2017/09/26 Javascript
基于VuePress 轻量级静态网站生成器的实现方法
2018/04/17 Javascript
js实现鼠标单击Tab表单切换效果
2018/05/16 Javascript
对mac下nodejs 更新到最新版本的最新方法(推荐)
2018/05/17 NodeJs
jQuery创建及操作xml格式数据示例
2018/05/26 jQuery
jquery多级树形下拉菜单的实例代码
2019/07/09 jQuery
Vue替代marquee标签超出宽度文字横向滚动效果
2019/12/09 Javascript
vue 子组件watch监听不到prop的解决
2020/08/09 Javascript
javascript使用canvas实现饼状图效果
2020/09/08 Javascript
微信小程序实现左滑删除效果
2020/11/18 Javascript
[51:34]Ti4主赛事胜者组 DK vs EG 2
2014/07/19 DOTA
用Python生成器实现微线程编程的教程
2015/04/13 Python
Python给你的头像加上圣诞帽
2018/01/04 Python
Python通过for循环理解迭代器和生成器实例详解
2019/02/16 Python
日本运动品牌美津浓官方购物网站:MIZUNO SHOP
2016/08/21 全球购物
Priority Pass机场贵宾室会籍计划:全球超过1200间机场贵宾室
2018/08/26 全球购物
英国花园、DIY、电器和家居用品商店:Robert Dyas
2019/03/18 全球购物
新西兰第一的行李箱网站:luggage.co.nz
2019/07/22 全球购物
教师师德教育的自我评价
2013/10/31 职场文书
演讲比赛策划方案
2014/06/11 职场文书
2015年安全生产责任书
2015/01/30 职场文书
2015年秘书个人工作总结
2015/04/25 职场文书
庆祝教师节新闻稿
2015/07/17 职场文书
少儿励志名言(80句)
2019/08/14 职场文书
Python使用openpyxl批量处理数据
2021/06/23 Python
mysql数据库实现设置字段长度
2022/06/10 MySQL