精华内容
下载资源
问答
  • bert词典构建
    千次阅读
    2020-08-28 10:11:38

    参考网址

    https://www.yinxiang.com/everhub/note/c9c56496-cc07-4cf3-81d4-ff2a3353272f (bert三种token方式详解,这篇博客较详细地介绍了bert的3种token方式)

    https://github.com/fighting41love/funNLP (各种词库)

    https://tech.meituan.com/2019/11/14/nlp-bert-practice.html (美团实践)

    https://blog.csdn.net/u011984148/article/details/99921480 (词向量详解)

    https://www.jiqizhixin.com/articles/2019-06-27-17 (各种词典的构造方法)

    https://www.jiqizhixin.com/sota (分类的项目)

    http://fancyerii.github.io/2019/03/09/bert-codes/ (bert代码详解)

    https://cloud.tencent.com/developer/article/1449248 (从字到词,大词典中文BERT模型的探索之旅;目前这篇博客报道的是基于词的bert预训练模型在公开数据集上还比基于字的逊色一些)

    http://fancyerii.github.io/2019/03/09/bert-codes/ (这是我见过bert代码分析最全的一篇blog;里面bert的词构建很详细)

    更多相关内容
  • 在bert4keras>=0.8.8版本中,实现上述改动只需要在构建Tokenizer的时候传入一行参数,例如: tokenizer = Tokenizer( dict_path, do_lower_case=True, pre_tokenize=lambda s: jieba.cut(s, HMM=False) ) 其中pre_...

    文 | 苏剑林

    编 | 小轶


    背景

    当前,大部分中文预训练模型都是以字为基本单位的,也就是说中文语句会被拆分为一个个字。中文也有一些多粒度的语言模型,比如创新工场的ZEN和字节跳动的AMBERT,但这类模型的基本单位还是字,只不过想办法融合了词信息。目前以词为单位的中文预训练模型很少,据笔者所了解到就只有腾讯UER开源了一个以词为颗粒度的BERT模型,但实测效果并不好。

    那么,纯粹以词为单位的中文预训练模型效果究竟如何呢?有没有它的存在价值呢?最近,我们预训练并开源了以词为单位的中文BERT模型,称之为WoBERT(Word-based BERT,我的BERT!)。实验显示,基于词的WoBERT在不少任务上有它独特的优势,比如速度明显的提升,同时效果基本不降甚至也有提升。在此对我们的工作做一个总结。

    开源地址
    https://github.com/ZhuiyiTechnology/WoBERT

    字还是词?

    究竟是“字”好还是“词”好?这是中文NLP一个很让人抓狂的问题,也有一些工作去系统地研究这个问题。比较新的是香侬科技在ACL2019上发表的《Is Word Segmentation Necessary for Deep Learning of Chinese Representations?》,里边得到了字几乎总是优于词的结论。前面也说了,现在中文预训练模型确实也基本上都是以字为单位的。所以,看上去这个问题已经解决了?就是字更好?

    事情远没有这么简单。就拿香侬科技的这篇论文来说,它的实验结果是没有错,但却是没有代表性的。为什么这样说呢?因为在该文的实验设置下,模型的embedding层皆从随机初始化状态开始训练。这样一来,对于同样的任务,以词为单位的模型Embedding层参数更多,自然就更容易过拟合,效果容易变差,这不用做实验都能猜个大概。问题是,我们用基于词的模型的时候,通常并不是随机初始化的,往往都是用预训练好的词向量的(下游任务看情况选择是否微调词向量),这才是分词的NLP模型的典型场景,但论文里边却没有比较这个场景,所以论文的结果并没有什么说服力。

    事实上,“过拟合”现象具有两面性,我们要防止过拟合,但过拟合也正好说明了模型拥有比较强的拟合能力,而如果我们想办法抑制过拟合,那么就能够在同样复杂度下得到更强的模型,或者在同样效果下得到更低复杂度的模型。而缓解过拟合问题的一个重要手段就是更充分的预训练,所以不引入预训练的比较对以词为单位的模型来说是不公平的,而我们的WoBERT正是证实了以词为单位的预训练模型的可取性

    词的好处

    一般认为,以字为单位的好处是:

    1. 参数更少,不容易过拟合

    2. 不依赖于分词算法,避免边界切分错误

    3. 没那么严重的稀疏性,基本上不会出现未登录词

    至于以词为单位的理由是:

    1. 序列变短,处理速度更快

    2. 在文本生成任务上,能缓解Exposure Bias问题;

    3. 词义的不确定性更低,降低建模复杂度

    对于词的好处,大家可能会有些疑惑。比如第2点,词能缓解Exposure Bias,这是因为理论上来说,序列越短Exposure Bias问题就越不明显(词模型单步预测出一个n字词,相当于字的模型预测了n步,这n步都递归依赖,所以字的模型Exposure Bias问题更严重)。至于第3点,虽然有多义词的存在,但是多数词的含义还是比较确定的,至少比字义更加明确,这样一来可能只需要一个Embedding层就能把词义建模好,而不是像字模型那样,要通用多层模型才能把字组合成词。

    看起来不相伯仲,但事实上以字为单位的好处,并非就是以词为单位的缺点了。只要多一些技巧,以词为单位也能一定程度上避免这几个问题。比如:

    1. 以词为单位的参数确实增多了,但是可以通过预训练来缓解过拟合,所以这个问题不会很严重;

    2. 依赖分词算法是个问题,如果我们只保留最常见的一部分词,那么不管哪个分词工具分出来的结果都是差不多的,差异性不大;

    3. 至于边界切分错误,这个难以避免,但是需要准确的边界的,只是序列标注类任务而已,文本分类、文本生成其实都不需要准确的边界,因此不能就此否定词模型;

    4. 如果我们把大部分字也加入到词表中,也不会出现未登录词。

    所以,其实用词的好处是相当多的,除了需要非常精确边界的序列标注类型的任务外,多数NLP任务以词为单位都不会有什么问题。因此,我们就去做了以词为单位的BERT模型了。

    Tokenizer

    往BERT里边加入中文词,首先得让Tokenizer能分出词来。只需要把词加入到字典vocab.txt里边就行了吗?并不是。BERT自带的Tokenizer会强行把中文字符用空格隔开,因此就算你把词加入到字典中,也不会分出中文词来。此外,BERT做英文word piece的分词的时候,使用的是最大匹配法,这对中文分词来说精度也不够。

    为了分出词来,我们修改了一下BERT的Tokenizer,加入了一个“前分词(pre_tokenize)”操作。这样我们就可以分出中文词来,具体操作如下:

    1. 把中文词加入到vocab.txt;

    2. 输入一个句子s,用pre_tokenize先分一次词,得到

    3. 遍历各个 ,如果 在词表中则保留,否则将 用BERT自带的tokenize函数再分一次;

    4. 将每个 的tokenize结果有序拼接起来,作为最后的tokenize结果。

    在bert4keras>=0.8.8版本中,实现上述改动只需要在构建Tokenizer的时候传入一行参数,例如:

    tokenizer = Tokenizer(
        dict_path,
        do_lower_case=True,
        pre_tokenize=lambda s: jieba.cut(s, HMM=False)
    )
    

    其中pre_tokenize为外部传入的分词函数,如果不传入则默认为None。简单起见,WoBERT使用了结巴分词,删除了BERT自带词表的冗余部分(比如带##的中文词),然后加入了20000个额外的中文词(结巴分词自带的词表词频最高的两万个),最终WoBERT的vocab.txt规模是33586。

    模型细节

    目前开源的WoBERT是Base版本,在哈工大开源的RoBERTa-wwm-ext基础上进行继续预训练,预训练任务为MLM。初始化阶段,将每个词用BERT自带的Tokenizer切分为字,然后用字embedding的平均作为词embedding的初始化。

    到这里,WoBERT的技术要点基本上都说清楚了,剩下的就是开始训练了。我们用单张24G的RTX训练了100万步(大概训练了10天),序列长度为512,学习率为5e-6,batch_size为16,累积梯度16步,相当于batch_size=256训练了6万步左右。训练语料大概是30多G的通用型语料。训练代码已经在文章开头的链接中开源了。

    此外,我们还提供了WoNEZHA,这是基于华为开源的NEZHA进行再预训练的,训练细节跟WoBERT基本一样。NEZHA的模型结构跟BERT相似,不同的是它使用了相对位置编码,而BERT用的是绝对位置编码,因此理论上NEZHA能处理的文本长度是无上限的。这里提供以词为单位的WoNEZHA,就是让大家多一个选择。

    模型效果

    最后,说一下WoBERT的效果。简单来说,在我们的评测里边,WoBERT相比于BERT,在不需要精确边界的NLP任务上基本都没有变差的,有些还会有一定的提升,而速度上则有明显提升,所以一句话就是“提速不掉点”。

    比如中文榜单上的两个分类任务:

    我们内部还测了不少任务,结果都是类似的,表明这些NLU任务上WoBERT和BERT基本上都差不多的。但是速度上,WoBERT就比BERT有明显优势了,下表是两个模型在处理不同字数的文本时的速度比较:

    我们还测了WoBERT+UniLM的方式Seq2Seq任务(CSL/LCSTS标题生成),结果是比以字为单位的模型有明显提升:

    这说明以词为单位来做文本生成其实是更有优势的。要是生成更长的文本,这个优势还能进一步放大。

    当然,我们也不否认,用WoBERT去做NER等序列标注任务时,可能会有明显的掉点,比如做人民日报的NER,掉了3%左右,可能让人意外的是,经过bad case分析,我们发现掉点的原因并不是因为切分错误,而是因为稀疏性(平均来说每个词的样本更少,所以训练得没那么充分)。

    不管怎么说,我们把我们的工作开源出来,给大家在使用预训练模型的时候,多一个尝试的选择吧。

    文章小结

    在这篇文章里,我们开源了以词为单位的中文BERT模型(WoBERT),并讨论了以词为单位的优缺点,最后通过实验表明,以词为单位的预训练模型在不少NLP任务(尤其是文本生成)上有它独特的价值,一方面它有速度上的优势,一方面效果上能媲美以字为单位的BERT,欢迎大家测试。


    文末福利
    后台回复关键词【 入群
    加入卖萌屋NLP/IR/Rec与求职讨论群
    有顶会审稿人、大厂研究员、知乎大V和妹纸
    等你来撩哦~
    展开全文
  • 字典树建立(python)

    2020-11-13 09:35:32
    比如Word2Vec的Huffman树、K近邻的DKTree、频繁项集的FP树、字典Trie树、高效的DAT树。 字典树的建立 注意:跟trie树并不完全相同 import pickle #保存类对象用 class root: def __init__(self): self.sub_nodes...

    启文

      在算法这块,树结构多次都会被用到,不管是二叉树还是多叉树。比如Word2Vec的Huffman树、K近邻的DKTree、频繁项集的FP树、字典Trie树、高效的DAT树。

    字典树的建立

    注意:跟trie树并不完全相同

    import pickle #保存类对象用
    
    class root:  
        def __init__(self):
            self.sub_nodes= {}#记录字符对应的node对象
            self.string_name = "" #记录root到当前节点形成的字符串
    
    class node:
        def __init__(self):
            self.sub_nodes= {}#同root
    
            self.lexeme=None #记录这个节点的字符
    
            self.string_name="" #root
    
            self.text_dic={} #记录词所在文章对应这个词有多少个
    
    class trie_tree:
        def __init__(self):
            self.head=root()  ##root类的存在
    
        def add_node(self,string,ownOfString) :
            new_node=self.head
            for char in string:
                if not new_node.sub_nodes.get(char):
                        new_node1 = node()
                        new_node1.lexeme = char
                        new_node1.string_name =new_node.string_name+ char
                        if char==string[-1]:
                            new_node1.text_dic[ownOfString]=1
                        new_node.sub_nodes[char] = new_node1
                        new_node = new_node1
                else:
                    new_node=new_node.sub_nodes[char]
                    if char == string[-1]:
                        if new_node.text_dic.get(ownOfString):
                            new_node.text_dic[ownOfString] += 1
                        else:
                            new_node.text_dic[ownOfString] = 1
            return self
    
    
        def search_node(self,string):
            snode=self.head
            for char in string:
               if char not in  snode.sub_nodes:
                   return False
               else:
                   snode=snode.sub_nodes[char]
            return snode.text_dic
    
        def obj_save(self,path):
            with open(path,'wb') as f:
                pickle.dump(self,f)
    
        def obj_load(self,path):
            with open(path,'rb') as f:
                d = pickle.load(f)
            return d
    
    if __name__ == '__main__':
    
        st=trie_tree()
    
        st.add_node("明天你",3).add_node('明天',4).add_node('明天',6).add_node('明天',4).add_node("聚合物",3)
    
        st.obj_save("obj.pkl")
    
        d=st.obj_load("obj.pkl")
    

    说明:
    为什么有3个类?

    • 第一个类root类的目的其实为了方便定位树的开头,因为树生成时添加字符串向后遍历的时候更新节点位置就找不到树根了;
    • 第二个类node类就是描述树结构的节点;
    • 第三个类trie_tree是实现用;

    总结

      这里用的就是共用字符建立词的多叉树,做法仅供参考,实现的目的是用于统计同一个词分布在哪些文本中。也就是DAT中的倒排序,计算过程没有DAT高级,DAT计算过程看似简单实际有点复杂,还没完全搞通。

    展开全文
  • 一些网站会直接提供实体词典,如搜狗词典; 可以从结构化/半结构化数据中挖掘实体词典,例如百度百科、医学网站的Link等等; 从文本中挖掘。用户可能提供一些非标准化表达,这时候就需要用到新词挖掘技术,可以...
    1. 一些网站会直接提供实体词典,如搜狗词典;
    2. 可以从结构化/半结构化数据中挖掘实体词典,例如百度百科、医学网站的Link等等;
    3. 从文本中挖掘。用户可能提供一些非标准化表达,这时候就需要用到新词挖掘技术,可以参考美团搜索的新词挖掘技术:

     

    获取实体词典后,要根据任务特点和数据特点选择实体词典的使用方式。

    有时候需要对实体词典做质量评估和筛选、分类,例如把歧义性高的实体组成一个词典,歧义词低的实体组成一个词典,新词组成一个词典等等。

    词典的质量评估,包括词典大小、词典准确度、覆盖度、实体歧义性、实体频率...完整全面地了解词典,才能更高地选择使用方式。

    关于使用方式,可以结合到NER模型里面使用,也可以单独匹配,也可以匹配后再与模型结合。

    关于结合到NER模型的方式,可以调研已有的论文,大多都是构建词典特征,然后作为bilstm等编码器的输入。构建词典特征的方式也要根据任务和数据来设计。

    关于匹配的方式,可以直接匹配,也可以先分词再匹配,例如对文本分词后匹配,或者对词典的item也分词,然后再匹配。

    上述使用方式都对应解决不同的问题。

     

    展开全文
  • 本文实例讲述了Python实现简单字典树的方法。分享给大家供大家参考,具体如下:#coding=utf8"""代码实现了最简单的字典树,只支持由小写字母组成的字符串。在此代码基础上扩展一下,就可以实现比较复杂的字典树,...
  • 字典树(java实现)

    千次阅读 2020-05-13 11:30:23
    字典树(java实现)
  • 改进主要思路:利用字典树(Trie)预先扫描文本,并把识别到的实体替换为一个标准词(这里我用了"人占位符"),再使用jieba的add_word使得标准词一定会被分词器识别出来,最后再在分词结果中...
  • 【知识图谱】知识图谱的基础概念与构建流程

    千次阅读 多人点赞 2019-11-09 18:46:49
    目录 1、引言 2、知识图谱的定义 3、知识图谱的架构 3.1知识图谱的逻辑结构 3.2知识图谱的体系架构 ...5、知识图谱构建的关键技术 ...【导读】知识图谱技术...我们专知的技术基石之一正是知识图谱-构建AI知识体系-专...
  • 第二十六章 命名实体识别和实体消歧 1 命名实体识别概论 PART1 什么是命名实体识别 PART2 命名识别识别的应用 PART3 简历中抽取关键信息 2 命名实体识别不同方法 PART1 实体识别方法 基于规则的方法 基于...
  • 知识图谱构建技术

    千次阅读 2020-03-17 15:26:29
    知识图谱构建技术主要包括关系抽取技术、知识融合技术、实体链接技术和知识推理技术。 1知识图谱技术地图 整个技术图主要分为三个部分, 第一个部分是知识获取,主要阐述如何从非结构化、半结构化、以及结构化数据...
  • 字典是键/值对构成的集合,字典通过大括号来创建,字典的键是字符串,而值可以是任何数据对象。 字典有两个重要的特征: 字典是无序的,字典项没有特定的顺序,只能通过键来获取值; 字典是可变的,支持原处修改键...
  • 创建字典的方法 1. 直接创建 >>> d1 = {'a':1, 'b':2} >>> d1 {'a': 1, 'b': 2} >>> d2 = dict(a=1,b=2) >>> d2 {'a': 1, 'b...
  • 数据流图、数据字典的画法

    万次阅读 多人点赞 2020-10-30 14:40:50
    它采用简单的图形妇好分别表示数据流、加工、数据源和外部实体等,不涉及任何具体物理元素,仅仅描述数据在系统中的流动和处理的情况。 - - 《软件工程》科学出版社版 具体画法: 常见两种数据流图元素的画法: ...
  • 基本流程为先通过知识库中的实体名字以及实体别称构建实体字典,然后采用精确匹配的方式匹配得到候选实体。 实体消歧 现在比较流行的消歧模型常用的方案是提取实体所在短文本的上下文特征,以及候选实体描述文本的...
  • 需求:在springboot项目启动完毕之后,自动查询业务字典表,将查询结果存入缓存,供其他代码模块调用(如果数据库中更新了字典表,则需要重新启动项目才能完成更新) 实现方式: 1.配置类实现CommandLineRunner...
  • post请求格式为application/x-www-form-urlencoded时,然后传参data中存在嵌套字典,如下可成功: header = {'Content-Type': 'application/x-www-form-urlencoded'} url='https://api/add' address={"province":...
  • 数据字典

    千次阅读 2021-03-18 20:03:35
    parent_id:上级id,通过id与parent_id构建上下级关系,例如:我们要获取所有行业数据,那么只需要查询parent_id=20000的数据 name:名称,例如:填写用户信息,我们要select标签选择民族,“汉族”就是数据字典的...
  • ObjectARX2015 + vs2012扩展字典和有名对象字典
  • 文章目录关于知识图谱知识图谱的概念知识图谱与异质网络知识图谱与知识库知识图谱构建研究背景知识图谱构建知识图谱的构建流程知识图谱本体构建知识图谱构建核心步骤实体消岐知识图谱关系补全知识图谱关系推理知识...
  • 本系列文章主要结合Python语言实现知识图谱构建相关工程,具有一定创新性和实用性,非常希望各位博友交流讨论,相互促进成长。第一篇文章主要介绍哈工大pytltp工具,包括安装过程、中文分词等;第二篇文章主要讲解...
  • 如果您无法掌握生成器函数,可以在顶部粘贴result=[],用result.append行替换yield行,然后在末尾添加return result,将其转换为进入一个函数,立即构建整个列表并返回它。 (列表显然也可以作为一系列值迭代。)但是...
  • 【命名实体识别(NER)】(1):命名实体识别综述

    万次阅读 多人点赞 2019-03-23 09:41:44
    命名实体识别综述 什么是命名实体识别? 命名实体识别(Named Entity Recognition,简称NER),又称作**“专名识别”,是自然语言处理中的一项基础任务,应用范围非常广泛。命名实体一般指的是文本中具有特定意义...
  • 【NLP】一文了解命名实体识别

    千次阅读 2020-09-06 11:00:00
    导读:从1991年开始,命名实体识别逐渐开始走进人们的视野,在各评测会议的推动下,命名实体识别技术得到了极大地发展,从最初的基于规则和字典的方法,到现在热门的注意力机制、图神经网络等方法...
  • 之前很长一段时间,我都不知道数据字典如何在web系统中应用,在网上看完关于数据字典的应用方面的文章后,也是迷迷糊糊。博主写的长篇大论,貌似博主对数据字典很熟悉,但有时我看完之后,就产生了“写的什么玩意?...
  • 我们可以对敏感词字典进行预处理,构建成 Trie 树结构。这个预处理的操作只需要做一次,如果敏感词字典动态更新了,比如删除、添加了一个敏感词,那我们只需要动态更新一下 Trie 树就可以了。 当用户输入一个文本...
  • 数据字典的使用

    千次阅读 2019-07-15 22:39:23
    数据字典的内容主要是对数据流程图中的数据项、数据结构、数据流、处理逻辑、数据存储和外部实体等六个方面进行具体的定义。数据流程图配以数据字典,就可以从图形和文字两个方面对系统的逻辑模型进行完整的描述。 ...
  • 命名实体识别实践(词典匹配)

    千次阅读 2019-03-09 21:24:09
    //词典构建和初始化 public static void initSearchParm ( String filePath ) throws Exception { String fileContent = readAllFile ( filePath ) ; String [ ] words = fileContent . split...
  • 【知识图谱】命名实体识别(NLP)

    千次阅读 多人点赞 2021-06-15 21:44:38
    命名实体识别实验内容实验原理命名实体识别任务序列标注条件随机场BiLSTM-CRF实验步骤1. 数据处理1.1将标注转换为 BMEO 格式1.2 数据集预处理2. 构建网络模型3. 模型训练4. 模型预测总结 实验内容 从本实验开始,...
  • 融易宝项目之EasyExcel和数据字典的使用 欢迎关注微信公众号:序辑 一、Alibaba EasyExcel 1.EasyEscel简介 1.1Excel导入导出的应用场景 数据导入 减轻录入工作量 数据导出 统计信息归档 数据传输 异构系统之间数据...
  • 结构化系统分析——数据流图和数据字典案例分析一、数据流图案例分析1、案例1:商店业务管理系统2、案例2:学籍管理系统3、案例3:大型企业数据中心二、数据字典案例分析1、案例1:学籍管理系统 接上一篇文章的内容...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,994
精华内容 5,597
关键字:

构建实体字典