自然语言处理hanlp------7-1双数组字典树

本文涉及的产品
NLP自然语言处理_高级版,每接口累计50万次
NLP自然语言处理_基础版,每接口每天50万次
NLP 自学习平台,3个模型定制额度 1个月
简介: 自然语言处理hanlp------7-1双数组字典树

前言

上一节的BinTrie的接口做到了1000万字每秒的速度,比Python的64万字每秒提高了两个数量级。但我们是算法工程师,要做到挑战极限。


提示:以下是本篇文章正文内容,下面案例可供参考


一、双数组字典树(DAT)是什么?

Trie树本质是一个确定的有限状态自动机(DFA),核心思想是空间换时间,利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。


但由于Trie树的稀疏现象严重,空间利用率较低为了让Trie树实现占用较少的空间,同时还要保证查询的效率,最后提出了用2个线性数组来进行Trie树的表示,即双数组Trie(Double Array Trie).

双数组Trie(Double-ArrayTrie)是trie树的一个简单而有效的实现,由两个整数数组构成,一个是base[],另一个是check[]。


base数组的每个元素表示一个Trie节点,即一个状态(分为空闲状态和占用状态)

check数组的每个元素表示某个状态的前驱状态


公式如下:

p = base[b] + c
check[p] = base[b]


若不满足此条件,则状态转移失败。举个例子,当前状态为自然(状态由一个整数下标表示,下同),我们想知道是否可以转移到自然人。那么我们先执行自然人=base [自然]+人,然后检查 check [ 自然人]==base[自然]是否成立,据此判断转移是否成功。

也就是说,我们仅仅执行一次加法和一次整数比较就能进行状态转移,因而只花费了常数时间。


二、了解一下源码

1.定义一个双数组

代码如下(示例):

class DoubleArrayTrie(object):
    def __init__(self, dic: dict) -> None:
        m = JClass('java.util.TreeMap')()
        for k, v in dic.items():
            m[k] = v
        DoubleArrayTrie = JClass('com.hankcs.hanlp.collection.trie.DoubleArrayTrie')
        dat = DoubleArrayTrie(m)
        self.base = dat.getBase()
        self.check = dat.getCheck()
        self.value = dat.getValueArray([''])

这里的双数组的构造直接由Hanlp实现,直接拿到对应的base,check,value值


2.状态转移

前面有讲述,Python的散列值不适合字符,所以直接借用 javahashcode()

代码如下(示例):

@staticmethod
    def char_hash(c) -> int:
        return JClass('java.lang.Character')(c).hashCode()

此处根据java的character对象创建字符并用hashcode方法取得其散列值


考虑到不是所有节点都对应词语终点,只有字典树中的终点节点(蓝色节点)才对应一个词语。为了区分它们,实现上可以借鉴C语言中的设计,在每个字符串末尾添加一个散列值等于0的\0,也就是说,\0充当了蓝色节点的角色,这样普通节点就不需要分配内存标记自己的颜色了。考虑到用户输入的文本中也可能含有\0,为了避免与此混淆,HanLP采用将文本字符的hashCode加一。一个兼容\0的转移函数的实现如下:

def transition(self, c, b) -> int:
        """
        状态转移
        :param c: 字符
        :param b: 初始状态
        :return: 转移后的状态,-1表示失败
        """
        p = self.base[b] + self.char_hash(c) + 1
        if self.base[b] == self.check[p]:
            return p
        else:
            return -1

除了额外加一的技巧外,这段代码与双数组字典树一致。


3.查询

有了状态转移函数,我们再对键取值查询就方便多了,带上多出来的+1(\0),也就是状态转移至多是len(key)+1次。

def __getitem__(self, key: str):
        b = 0
        for i in range(0, len(key)):  # len(key)次状态转移
            p = self.transition(key[i], b)
            if p is not -1:
                b = p
            else:
                return None
        p = self.base[b]  # 按字符'\0'进行状态转移
        n = self.base[p]  # 查询base
        if p == self.check[p] and n < 0:  # 状态转移成功且对应词语结尾
            index = -n - 1  # 取得字典序
            return self.value[index]
        return None


测试一下效果:

if __name__ == '__main__':
    dic = {'自然': 'nature', '自然人': 'human', '自然语言': 'language', '自语': 'talk  to oneself', '入门': 'introduction'}
    dat = DoubleArrayTrie(dic)
    #assert dat['自然'] == 'nature'
    #assert dat['自然语言'] == 'language'
    #assert dat['不存在'] is None
    #assert dat['自然\0在'] is None
    print(dat['自然'])
    print(dat['自然语言'])
    print(dat['不存在'])
    print(dat['自然\0在'])

20210125124936895.png


总结

多看,多思考,不懂的先保留,重在理解晗佬的思路,解决方案。

相关文章
|
存储 自然语言处理
自然语言处理hanlp------9基于双数组字典树的AC自动机
自然语言处理hanlp------9基于双数组字典树的AC自动机
自然语言处理hanlp------9基于双数组字典树的AC自动机
|
存储 自然语言处理 算法
自然语言处理hanlp------7-2双数组字典树(*初学者可选择性学习)
自然语言处理hanlp------7-2双数组字典树(*初学者可选择性学习)
自然语言处理hanlp------7-2双数组字典树(*初学者可选择性学习)
|
自然语言处理 算法 Java
自然语言处理hanlp------6-2字典树的实现
自然语言处理hanlp------6-2字典树的实现
自然语言处理hanlp------6-2字典树的实现
|
自然语言处理 算法 Java
自然语言处理hanlp------6-1字典树的实现
自然语言处理hanlp------6-1字典树的实现
自然语言处理hanlp------6-1字典树的实现
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【自然语言处理】TF-IDF算法在人工智能方面的应用,附带代码
TF-IDF算法在人工智能领域,特别是自然语言处理(NLP)和信息检索中,被广泛用于特征提取和文本表示。以下是一个使用Python的scikit-learn库实现TF-IDF算法的简单示例,并展示如何将其应用于文本数据。
117 65
|
3天前
|
机器学习/深度学习 人工智能 自然语言处理
【自然语言处理】python之人工智能应用篇——文本生成技术
文本生成是指使用自然语言处理技术,基于给定的上下文或主题自动生成人类可读的文本。这种技术可以应用于各种领域,如自动写作、聊天机器人、新闻生成、广告文案创作等。
20 8
|
3天前
|
机器学习/深度学习 人工智能 自然语言处理
【深度学习】探讨最新的深度学习算法、模型创新以及在图像识别、自然语言处理等领域的应用进展
深度学习作为人工智能领域的重要分支,近年来在算法、模型以及应用领域都取得了显著的进展。以下将探讨最新的深度学习算法与模型创新,以及它们在图像识别、自然语言处理(NLP)等领域的应用进展。
16 6
|
1天前
|
机器学习/深度学习 自然语言处理
深度学习在自然语言处理中的应用与挑战
【8月更文挑战第19天】深度学习技术已成为自然语言处理(NLP)领域的一股不可忽视的力量,它通过模拟人脑处理信息的方式,极大地推动了语言识别、机器翻译、情感分析等任务的发展。然而,技术的快速进步也带来了新的挑战,包括数据依赖性强、模型可解释性差等问题。本文将深入探讨深度学习在NLP中的主要应用及其面临的技术障碍,并展望未来的发展方向。
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
【自然语言处理】自然语言处理NLP概述及应用
自然语言处理(Natural Language Processing,简称NLP)是一门集计算机科学、人工智能以及语言学于一体的交叉学科,致力于让计算机能够理解、解析、生成和处理人类的自然语言。它是人工智能领域的一个关键分支,旨在缩小人与机器之间的交流障碍,使得机器能够更有效地识别并响应人类的自然语言指令或内容。
10 4
|
6天前
|
机器学习/深度学习 自然语言处理 数据可视化
深度学习在自然语言处理中的应用与挑战
【8月更文挑战第14天】本文将深入探讨深度学习技术在自然语言处理领域的应用及其所面临的挑战。我们将分析深度学习如何改变了文本分析、语音识别和机器翻译等领域,并讨论当前技术的局限性以及未来的发展方向。文章旨在为读者提供一个全面的视角,了解深度学习技术在处理人类语言方面的能力及其潜在的改进空间。

热门文章

最新文章