【自然语言处理】正向、逆向、双向最长匹配算法的 切分效果与速度测评

本文涉及的产品
NLP自然语言处理_基础版,每接口每天50万次
NLP自然语言处理_高级版,每接口累计50万次
NLP 自学习平台,3个模型定制额度 1个月
简介: 【自然语言处理】正向、逆向、双向最长匹配算法的 切分效果与速度测评

本文摘要

· 理论来源:【统计自然语言处理】第七章 自动分词;【自然语言处理入门】第二章 词典分词;

· 代码目的:手写三种算法:正向最长匹配、逆向最长匹配、双向最长匹配,比较它们的单词切分效果与速度

· 电脑配置:联想拯救者Y7000,Intel(R) Core(TM) i5-8300H CPU @ 2.30GHz 2.30 GHz

作者:CSDN 征途黯然.

一、关于测试用的语料库


  采用了2个预料库,一个是第二届国际分词的PKU测试集语料库(55303词),一个是网上随便找的(248303词)。它们的形式都如下:

中校 31
需要 353
圣彼得大 3
张德彝 2
周文德 2
……

 值得注意的是,语料库越大,代码搜索花费越大,会显著影响我们的算法速度测评环节。但是由于我们是比较三个算法的性能,不同系统配置、语料库不会影响三种算法的相对性能。

  获取本数据集或者代码工程,可以关注公众号‘三黄工作室’回复‘中文分词’。

二、正向最长匹配算法


  代码非常简单,见代码注释。

# 正向最长匹配
def forward_segment(text, dic):
    word_list = []
    i = 0
    while i < len(text):
        longest_word = text[i]  # 当前扫描位置的单字
        for j in range(i + 1, len(text) + 1):  # 所有可能的结尾
            word = text[i:j]  # 从当前位置到结尾的连续字符串
            if word in dic:  # 是否在词典中
                if len(word) > len(longest_word):  # 且更长
                    longest_word = word  # 则优先输出
        word_list.append(longest_word)  # 输出最长词
        i += len(longest_word)  # 正向扫描
    return word_list

三、逆向最长匹配算法


  代码非常简单,见代码注释。

# 逆向最长匹配
def backward_segment(text, dic):
    word_list = []
    i = len(text) - 1
    while i >= 0:
        longest_word = text[i]  # 当前扫描位置的单字,作为词的终点
        for j in range(0, i):  # 所有可能的前缀
            word = text[j:i + 1]  # 从前缀到当前位置连续字符串
            if word in dic:  # 是否在词典中
                if len(word) > len(longest_word):  # 且更长
                    longest_word = word  # 则优先输出
        word_list.insert(0, longest_word)  # 输出最长词
        i -= len(longest_word)  # 后向扫描
    return word_list

四、双向最长匹配算法


  代码非常简单,见代码注释。

# 双向最长匹配
def bidirectional_segment(text, dic):
    # 统计单字个数
    def count_single_char(word_list):
        return sum(1 for word in word_list if len(word) == 1)
    f = forward_segment(text, dic)
    b = backward_segment(text, 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

五、切分效果测评


  切分效果与所用的语料库大小有关,不具有使用价值。我们主要使用统计方法或者深度学习来进行分词。

# 加载数据集
def load_data():
    dic = []
    data = open("words.txt", "r", encoding="utf-8")
    for line in data:
        words = line.split(" ")
        dic.append(words[0])
    return dic
# 切分效果
sent = ["欢迎新老师生", "使用户满意"]
for s in sent:
    print(forward_segment(s, load_data()))
    print(backward_segment(s, load_data()))
    print(bidirectional_segment(s, load_data()))

  结果:

# 第一个语料库(55303):
['欢迎', '新', '老师', '生'] # 前向
['欢', '迎新', '老', '师生'] # 后向
['欢', '迎新', '老', '师生'] # 双向
['使用', '户', '满意'] # 前向
['使', '用户', '满意'] # 后向
['使', '用户', '满意'] # 双向
# 第二个语料库(248303):
['欢迎', '新老', '师生'] # 前向
['欢迎', '新老', '师生'] # 后向
['欢迎', '新老', '师生'] # 双向
['使用', '户', '满意'] # 前向
['使', '用户', '满意'] # 后向
['使', '用户', '满意'] # 双向

六、切分速度测评


  测评代码,就是让算法切分一句话,重复循环切分多次:

# 速度测评
def evaluate_speed(segment, text, dic):
    start_time = time.time()
    for i in range(100):
        segment(text, dic)
    elapsed_time = time.time() - start_time
    print('%.8f 万字每秒' % (len(text) * 100 / 10000 / elapsed_time))
text = "想要了解更多北京相关的内容"
dic = load_data()
evaluate_speed(forward_segment, text, dic)
evaluate_speed(backward_segment, text, dic)
evaluate_speed(bidirectional_segment, text, dic)

  结果:

# 第一个语料库(55303):
0.03538441 万字每秒 # 前向
0.04058394 万字每秒 # 后向
0.01625951 万字每秒 # 双向
# 第二个语料库(248303):
0.00714074 万字每秒 # 前向
0.00730858 万字每秒 # 后向
0.00372891 万字每秒 # 双向

七、结论


  1、切分速度与电脑配置、语料库大小强相关;

  2、后向匹配算法的速度略优于前向匹配算法;

  3、双向匹配算法的性能是前向、后向的一半,因为它执行了一次前向+一次后向;

  4、由于每次匹配都要去语料库判断是否含有字符串,吃了太多时间,我们要想办法通过一些数据结构的手段来解决这个问题,树就是一个好办法!

相关文章
|
3月前
|
机器学习/深度学习 人工智能 自然语言处理
"揭秘TF-IDF算法的神奇力量:如何一招制胜,让自然语言处理焕发新生?"
【8月更文挑战第20天】自然语言处理(NLP)是AI的关键领域,旨在使计算机理解人类语言。TF-IDF是一种重要的文本特征提取方法,用于衡量词汇的重要性。算法结合词频(TF)与逆文档频(IDF),强调文档独有词汇。示例代码展示了如何利用Python的scikit-learn库实现TF-IDF,并应用于文本分类任务,通过朴素贝叶斯分类器实现高效分类。此方法广泛应用于信息检索、文本挖掘等领域。
47 0
|
23天前
|
自然语言处理 算法 搜索推荐
NLP中TF-IDF算法
TF-IDF(词频-逆文档频率)是一种用于信息检索与数据挖掘的加权技术,通过评估词语在文档中的重要性来过滤常见词语,保留关键信息。本文介绍了TF-IDF的基本概念、公式及其在Python、NLTK、Sklearn和jieba中的实现方法,并讨论了其优缺点。TF-IWF是TF-IDF的优化版本,通过改进权重计算提高精度。
48 1
|
3月前
|
机器学习/深度学习 人工智能 自然语言处理
【自然语言处理】TF-IDF算法在人工智能方面的应用,附带代码
TF-IDF算法在人工智能领域,特别是自然语言处理(NLP)和信息检索中,被广泛用于特征提取和文本表示。以下是一个使用Python的scikit-learn库实现TF-IDF算法的简单示例,并展示如何将其应用于文本数据。
258 65
|
2月前
|
自然语言处理 算法
NLP之距离算法Levenshtein
NLP之距离算法Levenshtein
|
3月前
|
机器学习/深度学习 人工智能 自然语言处理
【深度学习】探讨最新的深度学习算法、模型创新以及在图像识别、自然语言处理等领域的应用进展
深度学习作为人工智能领域的重要分支,近年来在算法、模型以及应用领域都取得了显著的进展。以下将探讨最新的深度学习算法与模型创新,以及它们在图像识别、自然语言处理(NLP)等领域的应用进展。
122 6
|
5月前
|
机器学习/深度学习 自然语言处理 算法
分词算法在自然语言处理中的应用与性能比较
分词算法在自然语言处理中的应用与性能比较
|
4月前
|
机器学习/深度学习 自然语言处理 算法
分词算法在自然语言处理中的应用与性能比较
分词算法在自然语言处理中的应用与性能比较
|
4月前
|
机器学习/深度学习 自然语言处理 算法
分词算法在自然语言处理中的基本原理与应用场景
分词算法在自然语言处理中的基本原理与应用场景
|
6月前
|
自然语言处理 算法 搜索推荐
用自然语言表示计算机算法
用自然语言表示计算机算法
100 1
|
6月前
|
自然语言处理 算法 索引
【Python自然语言处理】隐马尔可夫模型中维特比(Viterbi)算法解决商务选择问题实战(附源码 超详细必看)
【Python自然语言处理】隐马尔可夫模型中维特比(Viterbi)算法解决商务选择问题实战(附源码 超详细必看)
75 0