精华内容
下载资源
问答
  • 导出的excel有嵌套实体怎么办?

    千次阅读 2018-06-07 14:02:53
    用JXLS、轻松导,嵌套、样式随你设 jxls是一个简单的、轻量级的excel导出库,使用特定的标记在excel模板文件中来定义输出格式和布局。java中成熟的excel导出工具有pol、jxl,但他们都是使用java代码的方式来导出...

    JXLS、轻松导,嵌套、样式随你设

        jxls是一个简单的、轻量级的excel导出库,使用特定的标记在excel模板文件中来定义输出格式和布局。java中成熟的excel导出工具有pol、jxl,但他们都是使用java代码的方式来导出excel,编码效率很低且不方便维护。

    另外,jxls2.3的运行效率也相当不错,经过测试,在禁用日志输出的情况下,导出excel单表66535条记录仅仅3000毫秒,与poi几乎没什么大的差距。【源】

    使用:

        首先pom文件中添加

     <!-- https://mvnrepository.com/artifact/net.sf.jxls/jxls-core -->
            <dependency>
                <groupId>net.sf.jxls</groupId>
                <artifactId>jxls-core</artifactId>
                <version>1.0.6</version>
            </dependency>

    其次定义模板:


    这个contents一会代码中map的key要对应上,其实就是foreach循环,简单吧;下面再说一个比较常用的if判断、没错 还有if判断哦,从此在也不导出生气


        jx:if标签可以基于某些条件来排除某些行或是某些列,如果你把jx:if标签的开始标签和结束标签放在同一行的话,JXLS会根据test的条件来处理或删除包含在标签提内的列;如果你把jx:if标签的开始标签和结束标签放在不同行的话,JXLS会根据test的条件来处理或删除包含在标签提内的行。【

    下面上代码:数据量有点大,所以加了个线程、执行一遍 速度上去了 文件没有数据惊讶 有知道原理的欢迎指导一二

     
        /**
         * 普通按照模板导出为excel
         * @throws IOException
         */
        @Test
        public void Test1() throws IOException, InvalidFormatException {
    
            String tplPath = "E:\\image\\ne\\jxls方式导出excel模板.xls";
            UUID uuid = UUID.randomUUID();
            String destPath = "E:\\image\\ne\\贝瓦资源" + uuid.toString() + ".xls";
    
            //查询Excel用科目树
            List<OriginBevaContentModel> subjectTree = new ArrayList<OriginBevaContentModel>();
            subjectTree = getBevaData.getCatContentAndSaveToMySQL();
    
            Map<String, List<OriginBevaContentModel>> beanParams = new HashMap<String, List<OriginBevaContentModel>>();
            beanParams.put("contents", subjectTree);
    
            XLSTransformer former = new XLSTransformer();
            former.transformXLS(tplPath, beanParams, destPath);
    //        ExecutorService executorService = Executors.newFixedThreadPool(3);
    //        executorService.execute(new Runnable() {
    //            @Override
    //            public void run() {
    //                try {
    //                    former.transformXLS(tplPath, beanParams, destPath);
    //                } catch (IOException e) {
    //                    e.printStackTrace();
    //                } catch (InvalidFormatException e) {
    //                    e.printStackTrace();
    //                }
    //            }
    //        });
    //        executorService.shutdown();
        }
    结果一角:


    if判断其作用了,因为太长没有截取,大概就是这样;还有有点瑕疵 大家也看到了 :没有合并! 合并的方法还是有点,有图为证:(前方高能、请相信这是jxls做出来的,而且代码不是很多哦)


    【官网】

    https://blog.csdn.net/hu_shengyang/article/list/8 大牛博客里面有系列博文

    https://blog.csdn.net/sinat_27115575/article/details/60957207 


    O(∩_∩)O哈哈~真让人高兴




    展开全文
  • 对于大部分的NER论文,Decoder都会用到CRF,主要的创新在不同的子任务(比如中文NER的词汇增强,少标注样本以及低资源学习、重叠实体识别等)的Encoder部分。 目录基本模型1. Bidirectional LSTM-

    写在最前面。最近对NER做了一个调研,看了一些论文,将论文中提到的NER方法汇总到博客里,此博客还会继续更新。相关论文和数据集整理可见Github
    按照我的个人理解,NER任务可以分为Encoder和Decoder两部分。前者获取输入句子的向量化表示,后者得到对每个字符的分类结果。对于大部分的NER论文,Decoder都会用到CRF,主要的创新在不同的子任务(比如中文NER的词汇增强,少标注样本以及低资源学习、重叠实体识别等)的Encoder部分。

    基本模型

    基本模型包括RNN-CNN based模型及其变种,也有一部分使用了多任务学习的方法,图神经网络在近几年也开始出现在相关NER任务里,主要用于Flat NER的任务。对于小样本或者低资源没有特定的解决方案。

    1. Bidirectional LSTM-CRF Models for Sequence Tagging

    在这里插入图片描述
    BiLSTM+CRF,没有什么好描述的,不过却奠定了NER的基调。

    2. A Multi-task Approach for Named Entity Recognition in Social Media Data,ACL2017

    采用多任务学习的解决方案:次要任务实体分割;主要任务实体识别。整个模型分为三部分:feature representation, model description, and sequential inference。
    使用了三种不同的特征作为模型的输入: character, word(预训练的词向量+词性标注), and lexicons(专业词典)。这三种不同的输入分别使用CNN,LSTM和Dense进行提取。
    整个模型表示为:
    在这里插入图片描述
    首先,系统将句子嵌入到高维空间中,使用CNN、BLSTM和Dense编码器提取特征。然后,它将每个编码器的结果向量串联起来并执行多任务。左上方的单节点层表示分割(红色),右上方的三节点层表示分类(蓝色)。最后,CRF分类器使用公共Dense层的权重来执行序列标注。
    其中的CNN和BiLSTM分别如下:
    在这里插入图片描述

    3. Empower Sequence Labeling with Task-Aware Neural Language Model,AAAI2018

    依然是多任务的,本文的多任务是语言模型以及NER。在character level LSTM之上加入了一个highway layer,用来将LSTM产生的字符表示映射到不同的表示空间,这样语言模型和序列标注模型就可以共享character level LSTM。
    在这里插入图片描述
    字符级LSTM只会在单词边界处对下一个单词进行预测,因此在图中,输出到下highway的都是 c i , _ c_{i,\_} ci,_这种表示单词边界的向量。对于BLSTM,前向和后向分别有两种不同的结果,分别表示为 f i , r i f_i, r_i fi,ri。Highway的本质其实就是门操作,论文中给出了如下公式:
    在这里插入图片描述
    图中提到的蓝色和灰色的Highway的输出被用于语言模型(Language Model),而黄色和粉丝的Highway的输出和单词的embedding结合起来被输入到单词级别的BLSTM中,最终过一个CRF进行词性标注。
    这里要提及一下LM,它是描述序列生成的一组模型,当前单词的概率与之前所有的单词相关:
    在这里插入图片描述
    而在本文的语言模型中的输入是 c i , _ c_{i,\_} ci,_,所以写作:
    在这里插入图片描述
    然后又做了一个逆向的:
    在这里插入图片描述
    最终,总体的loss被表示为:
    在这里插入图片描述

    4. Neural Chinese Named Entity Recognition via CNN-LSTM-CRF and Joint Training withWord Segmentation,WWW2019

    引入一个CNN-LSTM-CRF神经结构来为CNER捕获本地和远程上下文。其次,提出了一个统一的框架来联合训练CNER模型和分词模型,以提高CNER模型识别实体边界的能力。第三,引入了一种从已有标记数据中自动生成伪标记样本的方法,可以丰富训练数据。
    在这里插入图片描述
    其中,中文分词的损失函数为:
    在这里插入图片描述
    其中 y s s e g y_s^{seg} ysseg为句子的标签序列, c s c_s cs为CNN网络输出语句的隐藏字符表示, θ s e g θ^{seg} θseg为参数。最终的损失函数依旧是联合损失:
    在这里插入图片描述
    本文提到的标记数据生成方法值得强调一下,假如标记数据中“张三在阿里工作”,张三被标记为人名,阿里为公司,那么“李四在腾讯工作”这个未标记数据中的李四也可以被认为是人名。其实这对应了一个trigger的提取操作,这中想法有被应用在其他论文里,咱们后续再说。

    5. CAN-NER: Convolutional Attention Network for Chinese Named Entity Recognition,NAACL2019

    首先将CNN与局部注意机制相结合,增强模型捕捉字符序列之间隐含的局部上下文关系的能力。与使用正常CNN层的基线的实验结果相比,我们的卷积注意层的F1性能有了明显的提高;其次,引入了一个基于字符的中文NER模型,该模型由具有局部注意的CNN和具有全局自注意层的Bi-GRU组成。我们的模型实现了最先进的f1分数没有使用任何外部词嵌入和词汇资源,这是更实际的真实NER系统。
    在这里插入图片描述
    这个图看起来有点抽象,不过使用公式拆解开来就很好理解了:
    首先是输入的embedding。 d e = d c h + d p o s + d s e g d_e = d_{ch}+d_{pos}+d_{seg} de=dch+dpos+dseg,也就是输入的维度包含了三种特征:中文字级别的特征,position的特征,分割的特征(通过BMES编码,俺也不太清楚具体是啥)。然后,是一个local attention,用于获取局部大小为 k k k的窗口内部的字符级别的注意力:
    在这里插入图片描述
    最终的输出为 h m h_m hm。然后是对其进行经典的卷积,最后接一个sum-pooling。
    之后是GRU和一个全局的注意力机制,计算过程和local注意力差不多:
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
    最终通过CRF得到的预测值为:
    在这里插入图片描述

    词汇增强

    词汇增强有一些列论文,旨在借助预定义的专业提点提升中文NER的准确率。因为基于词的中文NER还需要一个上层的分词任务,与英文不同。关于词汇增强有一系列的论文,最早发表于2018ACL。词汇增强中经常出现的关键词有:Lexicon,FLat,Lattice。强调一下,我最后把Gazetteers的相关任务也算作词汇增强的一种。
    此处偷懒,放一下知乎大佬的文章,我们在此只介绍一下复旦大学邱锡鹏老师团队的文章。

    FLAT: Chinese NER Using Flat-Lattice Transformer,ACL2020

    传统的lattice结构存在复杂性和动态性,现有的大多数基于格的模型难以充分利用gpu的并行计算,推理速度通常较低。
    在这里插入图片描述
    因此本文提出了一种新的flat的lattice结构,将词典的相对位置信息编码并加到输入的后边。
    在这里插入图片描述
    Flat的结构可以和transformer结合起来,作为encoder的部分服务于文本表示学习的下游任务:
    在这里插入图片描述
    图中的矩阵代表四种不同的position encoder方法(这是在transformer中必不可少的),通过对位置信息的编码,使得模型对不同词之间的相对位置信息敏感。本文的四种位置编码分别为:
    在这里插入图片描述
    其中, i j ij ij表示不同的实体, ( h h ) (hh) (hh)表示两个单词head之间的距离。那么,所有实体相对位置的编码的融合向量为:
    在这里插入图片描述在这里插入图片描述
    那么,实体之间融合了位置信息的注意力为:
    在这里插入图片描述
    其中 E x i , j E_{x_i,j} Exi,j表示实体的向量。使用这个新的注意力计算方法代替transformer中的self-attention,也就是下面公式中的 A A A
    在这里插入图片描述
    接下来的计算方式就和transformer一毛一样了。

    嵌套实体

    嵌套这个词被表示为Nested,与其相对的是Flat的NER。举个例子,“中国银行”在Flat NER中只对应一个“组织”实体,但是“中国”也是一个国家的实体,Flat NER无能为力。Nested一般通过建模单词之间的关联关系得到两两词(英文中的词,中文里的字)之间的概率转移矩阵 M i j M_{ij} Mij i i i被视为潜在的可能作为实体的开始词(字), j j j则被视为结束词(字)。如果二者之间的概率高,可能就会被作为一个新的实体。图神经网络也会被用到此任务中去建模长距离的依赖关系。

    小样本

    展开全文
  • 在这篇文章中,作者使用了partially-observed TreeCRFs(PO-TreeCRFs),将标记的实体跨度看作树中的可见节点,将其他的看作潜在节点,与其他实体部分重叠的就reject(因为嵌套实体是完全嵌套的,不会部分重叠)。...

    Nested Named Entity Recognition with Partially-Observed TreeCRFs

    (作者: 英国爱丁堡大学和阿里巴巴)

    传统的序列标记的方法已经不适合用来识别嵌套实体。在这篇文章中,作者使用了partially-observed TreeCRFs(PO-TreeCRFs),将标记的实体跨度看作树中的可见节点,将其他的看作潜在节点,与其他实体部分重叠的就reject(因为嵌套实体是完全嵌套的,不会部分重叠)。为了提高速度,作者还用了Masked Inside算法来提高速度(一些相关的就是1,无关的就是0)。然后用了一个归一为均值为0,方差为1的经验分布,用一个很小值代替0的两种正则化方法,使得nested NER在3个嵌套数据集上性能都有所提升。

     

    嵌套实体的几个相关工作

    hypergraph-based(基于超图的)

    设计一个超图表示所有可能的嵌套结构。但是这个图需要精心设计避免结构虚假和结构歧义。这会导致结构构建和计算复杂。

    transiton-based(基于转换的)

    与shift-reduce pasers相似,对于不同形式的词设计不同的动作。通过shift/reduce/unary这些动作来处理不同的实体(A Neural Transition-based Model for Nested Mention Recognition)。或者是合并tokens and/or entities到实体中。这些方法依赖于特定的转换系统,需要领域专家,不够一般化。

    span-based(基于跨度的)

    计算所有的序列的跨度表示,并给出一个分数,从这些跨度中分类出可能的实体跨度。这些方法有局部依赖性。

    其他的

    有gap-based tagging(Labeling Gaps Between Words: Recognizing Overlapping Mentions with Mention Separators

    有sequence-to-nuggets结构方法的(Sequence-to-Nuggets: Nested Entity Mention Detection via AnchorRegion Networks

    有sequence-to-sequence结构方法的(Neural Architectures for Nested NER through Linearization

    还有当成阅读理解来做的(A Unifified MRC Framework for Named Entity Recognition

     

    结构与模型

    TreeCRFs局限于O(n^{3})时间复杂度,但现在有并行计算和高效率的张量优化库,可以把时间复杂度降到O(n^{2})甚至O(nlogn)(如果是2分类就可以达到O(nlogn)。

    用Biaffine计算实体跨度得分

    (还不是要计算跨度分数,Named Entity Recognition as Dependency Parsing也是用这个biaffine来计算跨度评分的,他的思想很简单,容易理解。而且得到的性能还更高。Biaffine的具体思想我还不明白,有时间再去仔细研究一下

    跨度评分计算方法如下:

    Enc(·)表示预训练编码(文章用的BERT和),FF(·)表示前馈网络。e_{i}表示每个词x_{i}的嵌入表示。U_{k}^{(1)},U_{k}^{(2)},b_{k}是biaffine评分机制的参数。s_{ijk}是区间跨度分数。每个词x_{i}都有标签k属于可见节点的那几个标签和隐藏节点的那几个标签。

    Partially-Observed TreeCRFs(PO-TreeCRFs)

    对每个句子x构造一个选区TreeCRFs树T。T表示为一个秩为3的张量,如果从词x_{i}x_{j}是一个类型为k的实体,那么T_{ijk}=1

    总的来说,感觉就是做了一个计算实体跨度的分数,再加上分别考虑了对应的不同实体类别的标签。

    时间复杂度的降低是因为将串行改成了并行计算。

    后面再做了一个小小的正则化。

    文章的突出点是构建了PO-TreeCRFs,并且做了mask使得时间复杂度降低。

    (记录一下阅读的论文,仅个人理解,不知道是否有误)

    最后的实验结果,懒得写了,先贴个结果上来,草草结束一下。

     

    展开全文
  • 浅谈嵌套命名实体识别(Nested NER)

    千次阅读 2020-04-06 13:11:58
    ©PaperWeekly 原创 ·作者|张成蹊单位|北京大学硕士生研究方向|自然语言处理序命名实体识别(Named Entity Recognition, 下称 NER)任务,主要目...

    ©PaperWeekly 原创 · 作者|张成蹊

    单位|北京大学硕士生

    研究方向|自然语言处理


    命名实体识别(Named Entity Recognition, 下称 NER)任务,主要目的是从一段话中抽取出其中可能为实体的所有元素。比如:

    “Hi Siri, 今天北京天气怎么样?”

    如果下游任务要求我们从其中抽取出地点,那我们期望 北京 能被识别成 Location,如果我们希望从中抽取的产品名称,那么 Siri 应该被标记成 Product —— 换言之,能从句子中抽出什么实体,是由我们提前给定的标签集合定义的。

    在一个任务型对话系统中,一些可能在后台处理中使用到的实体都应该被抽出来:我们有理由相信,Siri 是真正将 北京 给提取出来了,然后再通过后台查询到了天气~~,而不是找了一个人工客服在后台即时回复~~。

    NER 在很多下游任务中都是非常重要的一环。比如在电商行业,我们可能需要从用户的查询中提取出品牌或商品,来针对性地给用户返回内容。金主爸爸可能也希望用户在查指定品牌的时候,将一些商品放在第一位。

    在任务型人机对话方面,正如上面所说,一个合格的 Chatbot 需要能够准确地识别时间、地点、事件等元素以回答相关问题或安排日程,同时做到不偷听用户的日常对话。

    嵌套 NER,顾名思义,就是识别的实体中可能会存在嵌套的情况。比如北京大学不仅是一个组织,同时北京也是一个地点;雅诗兰黛小棕瓶是一个产品,同时雅诗兰黛是一个品牌。

    准确地识别嵌套内容有什么作用呢?简单来讲,如果一个模型能够识别出北京大学是一个组织,它倾向于将所有出现的北京大学都标记成组织。

    但如果它能够在识别前者的同时将北京标记成地点,我们就认为它有能力将所有[地点]大学的模式都识别出来,因为后者的角度,模型学到的是一种 pattern,而非记住了一种具体情况。此外,提取出来的额外信息也能作为辅助特征,增强其他任务的效果。

    具体地,我会介绍以下几部分内容:

    • 当前普遍使用的传统 NER 解决方案;

    • 传统 NER 在解决嵌套 NER 任务时存在的问题;

    • 如何解构 NER 任务,从不同的角度解决问题,使模型能够识别嵌套的 NER;

    • 介绍近几年嵌套 NER 领域有代表性的解决方案。

    NER Nested NER

    2.1  NER 任务的解决方案

    在进入 Nested NER 之前,我们先来简单谈谈目前普通 NER 任务(下称 Flat NER)的解决方案,即,将实体识别当做序列标注问题。

    具体来说,对于一个长度为 的句子 ,其中 表示句子中的第 个 token。序列标注即给每个 token 打一个标签,来表示这个 token 所在的实体类别。

    一组相邻且类别相同的 token 构成的子序列 就是我们想要的实体。这样,一个抽取实体的问题就被转化为一个给每个 token 进行分类的问题。

    在序列标注中,需要定义不同的 Schema,来使得将序列标注的结果从 token 层面提高到实体层面,并且保持其唯一性。定义有效的 Schema 的意义在于消除从 token 标注复原出实体时的歧义,例如:

    如果我们希望识别出地点。给定句子:北京市海淀区。我们希望抽取出来两个实体,分别为:北京市+海淀区。然而如果只对每个 token 进行分类,所有的 token 都将被分到 Location 标签中,这样两个相邻的同类型实体边界就无法正确区分开来。

    为此,我们需要定义一个 Schema(即类型标签),使得给 token 打完标签之后,能够从 token 复原出实体,同时有效标识两个实体之间的边界。在这里介绍两种最常见的 Schema:

    • BIO:即 Beginning、Inside、Outside,对于一个实体的第一个 token,标注为 B-[type],实体其他位置的 token 标注为 I-[type],不属于任何实体的 token 标注为 O;这样,对于一个标签数    的实体集,使用 BIO 标注将转变为 个标签;

    • BIOES:即 Beginning、Inside、End、Outside、Single。其中 End 用来标识一个实体的结束,而 Single 用来标识仅包含一个 token 的实体。

    在给定 BIO 标注 Schema 的前提下,北京市海淀区的标注结果为:B-Location, I-Location, I-Location, B-Location, I-Location, I-Location。能够完整且没有歧义地复原出模型的标注结果。

    基于上述表述,我们可以将一个基于序列标注(Sequence Labeling)的 NER 任务解决方案总结为两个简单的步骤:

    1. 选择一个有效的标注 Schema;

    2. 选择分类模型(常用 CNN/Bi-LSTM/BERT),对每个 token 进行分类;根据分类结果复原出原文中的实体。

    2.2 Nested NER

    我们现在回头来看嵌套 NER 的解决方式,一步步提出该问题的基础解决方案,并探讨这些方案存在的不足。

    很显然,2.1 节中所定义的 Flat NER 解决方案是没有办法解决嵌套情况的,因为在嵌套 NER 中,一个 token 可能分别拥有两个不同的类型。

    例如:北京大学中的同时属于 B-Location,也属于 B-Organization;而也拥有 I-Location 与 I-Organization 两个标签。

    如果从最简单的角度出发,能够想出什么方法,使得现有的NER解决方案支持嵌套的情况呢?

    2.2.1 将分类任务的目标从单标签变成多标签

    一个容易想到的解决方式是:Schema 不变,模型也不变,将输出从单分类转变为多分类:即在最后分类的时候,从输出一个类到输出所有满足一个指定阈值 的所有类。更为具体地,存在以下两种方案:

    • [1] 完全不改变 Schema,只是在输入训练集的时候,训练集中的 label 从原来的 one-hot 编码形式变成一个指定类别的均匀分布;在训练时将损失函数改为 BCE 或 KL-divergence;在进行推理时,给定一个 hard threshold,所有概率超过这个阈值的类别都会被预测出来,当做这个 token 的类。

    • [2] 修改 Schema,将可能共同出现的所有类别两两组合,产生新的标签(如:将 B-Location与 B-Organization 组合起来,构造一个新的标签 B-Loc|Org);这样做的好处是最后的分类任务仍然是一个单分类,因为所有可能的分类目标我们都在 Schema 中覆盖了。

    我相信在这些年探索中,这个方案是有学者研究过的,因为它简单易行,改动也小;不过除了 NAACL18 与 ACL19 中的两篇文章仔细探讨了这些方案以外,我很少有见到有使用这种思路解决问题的 paper。因为它存在一些比较明显的问题:

    1. (仅针对第一种实现方式)模型学习的目标设置过难,阈值定义比较主观,很难泛化;

    2. (仅针对第二种实现方式)指数级增加了标签,导致分布过于稀疏,很难学习;对于多层嵌套,需要定义非常多的复合标签;

    3. 以及最初的问题:修改后的 Schema 预测的结果,复原回实体的时候又不再具有唯一性了。

    当然,我们仍然能够给模型添加规则与约束,来一一解决这些问题,具体内容在论文中有相应的阐述。

    2.2.2 修改模型的Decode过程

    在这里,Decode 过程指的是基于模型输出的 token 表示来给 token 分类的过程,在 Sequence Labeling 中指的是 FFN + Softmax/CRF + Argmax 这一套操作。

    严格来说,解决方案 1 的第一个实现方式也算是非常 naive 的修改了 Decode 过程,不过在这里我们讨论一些更加有效的方案。

    值得注意的是,修改 Decoder 的目的是为了保证能够给一个 token 同时赋予多个类别,所以我们仍然将下面的方案视作 Sequence Labeling 任务(尽管最后输出的 label list 长度可能与 token 的数量不同,但这是因为由原来的单分类变成了多分类所必然导致的)。

    • [2] 既然直接使用 FFN 映射做单分类没法解决嵌套问题,做多分类又不容易做work,那是否可以考虑使用生成式的方法,如 seq2seq 中的 Decoder 来逐个生成每个 token 的标签?使用 Decoder 能够将输入的 token 数量与输出的类别数量解绑,允许给token打上超过一个的标签——但是与原来的生成方法不同,除了使用特殊字符[EOS](end of sentence)来标识整个生成过程结束以外,我们需要引入一个特殊字符[EOW](end of word)来标识接下来生成的是属于下一个 token 的标签。

    • [3] 使用分层的方式对token的表示进行预测也是一个非常有意思的方案:如果一次分类无法解决实体嵌套的问题,那就对第一次的分类结果继续做分类,如是迭代,直到达到最大迭代次数或是不再有新的实体产生为止。这种解决方案存在的问题是对 Decoder 的学习要求较高,如果前面的迭代过程中出现了错判,这个问题可能会传递到后续迭代过程中。

    这一类方法相较于普通的多标签分类,从任务本身的角度来进行设计,通过横向(序列生成)与纵向(分层标注)两个层面修改了原始的 Sequence Labeling 模型将输入 token 与输出 label 强制绑定的形式。

    2.2.3 抛弃Sequence Labeling

    依稀记得之前看过一篇让我印象深刻的知乎文章,名为"丢掉幻想,全面拥抱Transformer"。借由此名,最后一种解决嵌套 NER 问题的方式可以叫做"丢掉序列标注,全面拥抱 Multi-Stage"

    我们已经在上文中多次提到,序列标注任务是天然不支持给一个 token 赋予多个标签的,尽管我们已经进行了多个层面的修饰,使它能够应用到多标签分类上。

    但是既然它应用到 Nested 任务上时效果并不突出,也没有其不可替代性,为什么不直接舍弃掉这个任务形式,尝试其它的解决方案呢?

    撇开原来的 NER 解决方案,从头考虑一个实体识别的方案,我们仍然从一个非常 naive 的 proposal 出发:

    将句子 中所有的子序列全部枚举出来,即得到一个子序列集合:

    训练一个分类器  ,负责将子序列映射到给定的标签集合(即:Location, Organization, ..., O)中:

    如果上面的 proposal 真的能够做 work,它就完美地胜过了以 Sequence Labeling 为基准的 Flat NER 解决方案:因为这个方案同时能够应用到 Flat 与 Nested 情况下 —— 倒不如说,这是一个理论上的 NER 任务终极解决方案

    当然,通过常识来推断,这个任务做 work 的概率非常小,因为这样的设定会带来包括(但不限于):时空复杂度极高、分类器训练十分困难、负样本极多(大部分的子序列都是没有意义的  标签)等等。

    当然,我们仍旧可以通过一些人工规则或设定来减弱这些问题,例如:

    • 模型训练困难:给每个类型单独训练一个分类器;

    • 时空复杂度:假设最长的实体长度为  ,全枚举子序列时只枚举长度小于  的所有情况;

    • 负样本很多:在执行分类之前,先训练一个/多个通用的筛选器,或通过人工规则首先筛掉一批负样本;在训练过程中对负样本进行采样,而非使用全部。

    事实上,目前几乎所有撇掉 Sequence Labeling,另辟蹊径的解决方案都是在寻找好用的 2-stage 模型,并致力于减弱这些问题:

    • 非常典型地,我们可以以现有的模型骨架(Bi-LSTM、ELMo 等)来简便地搭建一份上面所描述的模型。[4] 使用了 7 个 Bi-LSTM 与 1 个 ELMo 来提取不同 level 的上下文信息,并使用了一个 Self-Attention 来通过上下文来增强每个子序列的表示。

    由于这篇 paper 不会在下面详细讲到,我在这里冒昧做个简单的评价:

    尽管是非常典型的上述 proposal 实现模板,这篇 paper 的建模操作总体而言并不算特别 elegant,并且加了一些人工设定,有少部分的操作甚至难以解读,而作者也没有专门去解释一些操作的含义,导致我读完之后小小的脑袋里充满着大大的问号。

    我倾向于以为是因为这篇 paper 提出的方案除了约束长度为  的全枚举以外,其他与上面那个比较 naive 的 proposal 比较接近,所以把它做 work 相对会更难。

    在文中作者引入了多个 Bi-LSTM 模型以期学到不同层次的信息,就我而言,此举本质上是引入了更多的参数量与外部信息以解决这个问题。

    另外还有一个比较有意思的设定,想与大家分享:在通过 3 个 Bi-LSTM+1 个 ELMo 让 token 获得了全局信息之后,作者将 token 的输出 通过一个全连接网络映射到了一个  的空间。

    然后表示:这个向量的前  个数值,代表了这个 token 前后的  个子序列是一个合理的实体 candidate 的概率,然后这个空间的后  个数值,代表了它前后 个子序列不是一个合理的 candidate 的概率,比较这两个概率,我们就能对这个包含这个 token 的共  个候选实体进行筛选。

    这个设定能够 work 超过了我的常识。我能理解 Encode 以后的 token 表示中确实有蕴含整个句子中上下文信息。

    但就此判定,并期许它所表示的正好就是该 token 附近特定区域的某一概率,似乎比直接用该区域的表示来做出这个判定要来得牵强些。希望有阅读过这篇 paper 的同学与我讨论,解答我的疑惑。

    • [5] 给出了思路上与 [4] 相似的解决方案。不过相较于全枚举,[5] 选择从另一个角度来获得候选实体:预测两个 token 之间相连的概率。如果两个 token 之间相连的概率较大(在文中体现为值趋向于 0),认为它们在当前 level 更倾向于在同一个实体中。随后迭代更新实体中每个 token 的表示,就能识别多层的嵌套信息。

    • [6] 提出了一个假设:在一个实体中,总会存在一个或多个 token 是该实体的锚点(即如果这个 token 出现,则有相当概率该 token 在一个实体之内。作者以The department of [xxx]中的department为例,阐述它很有可能出现在一个类型为 Organization 的实体中)。由此,我们可以将识别嵌套实体的任务转换为寻找锚点的任务:首先找到锚点并判定它所代表的类别,随后找到该锚点所在实体的边界。

    • [7] 将寻找实体的任务视为阅读理解(Machine Reading Comprehension,下称 MRC)任务,即:查询句子中是否存在指定问句的答案。在这里问句代表了一个指定类别的查询(如:Is there any Location in this sentence?),而作为问句的答案,模型将输出句子中所有对应实体的开始与结束位置。

    • [8] 受到构造一棵语句解析树过程的启发,将识别嵌套实体视为一个构造解析树的过程:在每一个时间步中,模型将根据当前状态来决定是给指定 token 赋予一个标签,还是给已经赋予标签的两段实体打上一个更高层次的标签(以此实现了标签的嵌套),抑或是跳过当前处理的 token。这样的操作比较像一个内部带着条件语句的 RNN 单元,它能根据当前的情况来以不同的方式处理一个 token:给它打标签,或者不做处理。

    相关Paper选读

    上面的部分主要是阐述了 Flat NER 与 Nested NER 任务形态上的区别,通过 Sequence Labeling 的缺陷来从各个方面推导出一些可行的解决方案。

    由于篇幅与时间所限,接下来我将挑选三篇思路上比较有趣的 paper,来具体阐述研究者是究竟是如何解决 Nested NER 这一任务的。

    3.1 逐个token的解析:基于状态转换(Transition)的方法

    [8] 基于状态转换的方法在近三年所提出的 Nested NER 解决方案中占据了一席之地。这个方法有些像编译原理中的有穷自动机,而且十分相似的一点是,它们确实都在对某个输入进行解析。

    如果对自动机有了解,大家知道自动机的下一个状态依赖于当前状态与当前的输入,而如果从玄学的角度来看待,自动机当前的状态是由从开始到现在所有的状态转换以及所有的输入共同影响达到的,也就是说当前状态中理应 Encode 了从开始为止所有操作的信息

    但是实际上,当前的状态只是一个状态而已,之前的所有操作与信息都随着时间的流逝进入到历史的长河中去了。

    现在回头考虑 Nested NER 的问题:如果我们能通过以一个状态转换的形式来解析一个句子,从中提取出所有的嵌套实体,我们首先需要解决的就是如何在当前状态中把之前的信息也放进来,令人高兴的是有一个结构天然带有这样的性质:即 时间序列 模型。

    首先我们来看一个带有嵌套实体的句子:

    constituency parsing中 shift-reduce 解析方式的启发,作者设计出了一个解析上述句子的体系。在整个过程中,我们需要维护下面三个结构:

    1. 一个(Stack),栈顶元素是当前需要处理的元素。我们需要根据上下文与当前的状态来决定:忽略该元素、给该元素打标签,或是将该元素与前一个元素进行复合,打上更高层次的标签。

    2. 一个队列(Buffer)。队列中是句子中待处理的剩余 token。

    3. 一个操作器(Action)。这个操作器本质是一个模型,它将根据目前的系统状态来决定执行哪一种解析操作。

    解析操作共有下面三种:

    1. SHIFT将队列头部的一个 token 弹出,移入栈中。值得注意的是,这并不代表我们跳过了当前 token 的处理,由栈的功能定义可知,这一步的目的实际是要开始处理这个 token 了;

    2. Unary-X将栈顶的元素弹出,给它打上标签 [X],随后重新压入栈中;

    3. Reduce-X弹出两次栈顶元素,给它们打上标签 [X],随后重新压入栈中。

    从上述操作中容易看到,只有 Reduce 操作是赋予了实体更高层次,也即嵌套的标签。

    假设目前输入句子:Indonesian leaders visited him ,一个正确的解析操作序列应该如下图的 Action 列所示:

    上图的操作十分易懂,在此不多解释了。值得注意的是在句子的末尾需要添加一个结束符 $,当这个符号被移入栈顶时,意味着整个处理过程的结束(实际上我们也可以通过:下一步要执行的操作是 SHIFT,并且队列为空 这两个情况的出现来标志处理过程的结束,不过队列为空不便于对未处理的句子进行表示,因此作者添加了这一符号)。

    这个设定其实非常的有意思(至少我看到的时候是这样认为的),但是直接移植到嵌套 NER 任务时,仍存在一些亟待解决的问题:

    1. 上述的  Unary+Reduce 操作最终得到的解析树中的每个实体只能是一棵二叉树(可以参照上图的解析过程来辅助理解为什么一定是一棵二叉树);二叉树意味着一个被识别出来的实体里面只能包含最多两个 token,然而现实中非常多的实体是由超过两个 token 所构成的;

    2. 如果不停的进行无意义的操作,会显著加剧栈所占的内存空间,同时得到的结果是不合理的(例如反复连续执行同一个类型的 Unary),需要对操作进行约束;

    3. 最后一个问题,同时也是 Deep Learning 大家族灵魂拷问:在完全正确的 Action 操作顺序下,我们确实能完成对嵌套实体的识别,但怎样判断当前应该执行哪一个 Action 呢?

    好消息是,这些问题都很好解决。对于问题 1,我们引入对于每个标签  都引入一个辅助标签  ,如果有一个类型为 Person 的实体  ,我们只需要转化为解析结果:

    就可以了。对于问题 2,我们人工添加规则来约束,禁止反复给一个元素标多个相同标签等不符合事实的情况出现。

    接下来主要讲述的是问题 3,也就是论文的核心部分:如何获得一个尽可能准确地 Action 序列。下面的处理方式堪称万物皆可Embedding的实践典范。

    我们的目的是通过当前整体系统的状态来判断接下来应该执行的操作,操作将在上面预定义的三种中任选一种,这就允许我们将其视为一个分类任务。如果我们能够将整个系统进行表示,集成到一个数值向量中,再通过一个 FFN,就能实现这个分类任务了。

    正如上面所说,有三个部分共同构成了当前的整个系统,作者分别对它们进行了表示:

    • 队列中保存的是当前还未处理的所有 token,作者使用了一个反向的 LSTM 来学习这个队列的表示。之所以使用反向(即从队列尾开始到队列头),是由于我们当前下一个待处理 token 是队列头的字符,因此所需要的信息自然是从文本尾部到当前文本的信息;

    • 中保存的是目前已经处理的 token 以及处理结果(即目前为止嵌套实体的识别结果),与队列的表示方法相似,从栈底到栈顶使用单向 LSTM 来获得栈顶元素的表示;值得注意的是,由于栈顶的两个元素可能会被修改(或因为下一个 token 的移入而被改变),作者在此使用了 Stack-LSTM 来避免频繁修改带来的时空开销;

      • 当一个新 token 被移入栈顶时,基于该 token 的表示与 Stack-LSTM 特性更新新的栈顶表示;

      • 当栈顶元素被执行 Unary-X 操作时,我们将类型  的表示集成到当前栈顶元素的表示中去,即  ,其中  是新的向量, 是栈顶元素当前向量, 分别是类型  的权重矩阵与正则项, 表示当前执行的是 unary 操作;

      • 当栈顶元素执行Reduce-X操作时,与上面操作相同,更新栈顶元素的表示为 ,其中  分别是次栈顶元素与栈顶元素的表示,即二叉树的左右子节点。

    • 操作器之前所做的历史操作我们也使用一个结构将其保存下来,并使用一个单向 LSTM 来获得整体表示,方向为从第 1 个 Action 一直到离当前最近的 Action。

    获得队列的表示  ,操作历史的表示  与当前栈的表示  之后,当前整个系统的向量就可以表示为三者的拼接:

    最后我们使用一个 FFN 来判断在给定  的条件下应当执行哪一个 Action就可以了。模型最后的 Loss 定义为所有训练数据中的 Action 的损失之和:

    其中  意味第  个句子的第  个动作,Loss 的第二项是一个 L2 正则参数。

    简单总结一下,作者相当于将待处理的文本内容、已处理的文本结果,与已经进行的  Action 操作视为一个系统,将其 Embed 到一个向量中,以表征当前的整体状态,再基于这个状态使用分类器来判断下一步执行的操作。

    这里的每一步都在 Embed 层面进行。当然,这样的做法虽然 work,但这种将一切都看成 Embed,然后使用各种模型结构进行交互的方式,放在自动机体系中或许成立,放在其他应用中,是否仍然可行?

    即便可行,这种将所有一切元素都视作表示的思路究竟又是否能够直观上进行解释,能否引申出一条截然不同的理解语言之路,这些都是值得进一步探索的。

    3.2 基于超图(Hypergraph)的方法

    现在我们重新审视句子:***... that his fellow pilot Dabid William had ...*** 及其嵌套标注结果(其中 L=Last=End=E, U=Unit=Single=S):

    可以看到,像 his 这样的 token 虽然嵌套在三个实体中,但只会有两种取值。我们将每个 token 的相同取值合并,能够得到下图所示的 Hypergraph:

    值得注意的是,我们需要保证每个 token 至少都有一个 O 标签。这么做的目的是为了能够有效的建模每个新实体的开头的概率。如上图所示,如果一个 token 没有 O 标签,我们需要加一个虚空 O 进去。

    接下来,我们期望训练的模型能够给定一个输入的 token,输出它所有可能的标签。例如:输入 his 模型应该输出  以及 (这里没有直接预测输出 O,不过我们会在后面提到加入的虚空 O 应该怎么加入到训练过程中去)。

    我们可以使用一个 Decoder 来实现这个过程。

    值得注意的是,虽然这里使用了 Decoder,但是这个 Decode r输出的标签数量与输入的 token 数量是一致的,这也是我在第二章节划分体系时将其分类到多标签任务体系,而非修改了 Decode 过程体系的原因:在该模型中,使用 Decoder 的原因并不是因为 Decoder 能够以生成式的方式产生非等量标签的特性,而是因为 RNN 家族的单元在 Decoder 中能够传递隐层信息以增强当前标签识别结果的特性。在这样的理解上,将这个 Decoder 换成一个表达能力相对较差的 CRF 也是成立的,(虽然效果不会那么好但)大概率也能做 work。

    作者在文中提到 we have a decoder-style model 而非直接提出 we apply a decoder,或许也是因为这个原因吧

    这个 Decoder 使用的是 LSTM Unit,以下的分析假设读者已经对 LSTM 的内部结构有一定的了解。

    首先,假设我们已经获得了所有标签的 Embedding 表示,这个表示可以在训练时初始化,在训练过程中进行更新。对于标签  ,它所对应的表示为 

    我们采用以小见大的方式,先来考虑假设已经有了上一个时间步 Unit 的隐层输出  ,上一个时间步的模型输出  ,以及当前时间步输入的 token 表示  ,如何基于这些参数来求出当前的隐层输出  与当前时间步的模型输出 

    1. 上一个时间步的模型输出  是一个概率分布,我们将整个分布通过 softmax 映射到 01 区间,随后将所有概率大于我们预先设定的 hard threshold: 的标签找出来。以上图举例,如果模型得到我们预期的结果,对于当前 token his,模型应该找到两个符合阈值要求的标签  与  注意,由于这里没有预测出标签 O,我们手动给它加上 O 的标签,即模型最终预测得到  与 

    2. 由于上一个时间步模型预测得到了三个可能的标签,我们需要考察这三个标签在当前步分别可能对应哪个标签。所以我们将当前的  复制三份,每一份都通过 LSTM 单元计算当前的隐层输出。特别地,对于上一个时间步的可能标签 ,当前时间步的隐层结果为:

    3. 这样,对于上一个时间步的每一个预测结果,我们都能得到对应的当前时间步的隐层表示。现在我们有了三个隐层表示,将它求平均:

      其中  就是上一个时间步中所有满足阈值的标签数量,在当前我们所讲的 case 中取值为 3.

    4. 获得当前时间步的输出  ,其中  分别为 FFN 的权重矩阵与正则项。

    以上就是使用类似 Decoder 的形式来逐个输出每个 token 所有可能标签的形式,如果上面表述比较难以直接理解,也可以通过 paper 中所给的模型结构图来比较理解。

    与我们的讨论过程一致,我们在此给出基于上述思路的损失函数的公式描述:

    本质上就是一个多分类交叉熵损失函数,就不再一一讲述其中符号的含义了。

    作者在文中也比较了使用 softmax 与 sparse softmax 的结果,采用后者是因为作者认为在每个时间步中输出的标签大部分都比较少,换言之即比较稀疏,因此使用 sparse softmax 会有更好的效果。

    后面的实验中也证明了这一点:使用 sparse softmax 相较于普通的 softmax,能在 ACE2004 与 ACE2005 测试集中得到 5 个点以上的提升,令人震惊 TAT,有兴趣的同学可以去原文中详细阅读作者的试验分析过程。

    此外,这里对于一些 word embedding 层、multi-layer Bi-LSTM 层也不再进行详述,因为他们的实现方式大同小异,只在于使用了静态 GLoVe 还是动态 ELMo、加 Character LSTM 与否,以及使用了 Bi-LSTM 还是 BERT 作为上下文信息学习框架,亦或在顶层是否添加了一个 Attention 的区别。

    3.3 基于阅读理解的方法

    Shannon.AI 在去年年中左右提出了将 NER 任务作为 MRC 来做的思路 [7]。这是目前在 ACE04&05、GENIA 与 KBP2017 四个嵌套实体识别数据集中都位于 SOTA 的方法,尤其在后两个数据集上做到了大幅度的提升。

    此外,作者在中英文的 Flat NER 任务上也进行了测试,都得到了 SOTA 的结果。

    据笔者所知,MSRA有位同学应该做了更好的结果出来,不过考虑它要投的顶会时间,保守估计在5月份才会挂到Arxiv上,让我们一起期待吧: )

    MRC 任务一般可以被形式化表述为:

    给定一段信息(passage)与给定一个问题(question),模型需要从信息中找到回答这个问题的短语(span)

    从任务理解上来看,这个解决思路似乎与NER是十分相似的:我们只需要将每个标签  都看做一个问句:这个句子中的  标签的实体是什么? 随后输入待抽取实体的句子进行询问,然后将模型输出的短语作为这个句子中  标签的实体就好了。

    乍一听这个方法充满了玄学,但当我们拥有一个 BERT 的时候,这个任务就非常好做了。由于预训练时的任务设计,BERT 天生就允许往模型中同时输入两个不同的句子。我们向 BERT 中以下面的形式输入问题与信息:

    其中 [CLS] 与 [SEP] 分别用于标识一个输入的开头与间隔两个句子。然后静静等待模型给我们结果就可以了。

    问题是,怎么拿到这个结果,再将这个结果复原回原来的实体结果呢?

    作者训练了三个分类器,分别用于预测模型输出后的:

    • 当前 token 是否为一个实体的开头位置;

    • 当前 token 是否为一个实体的结束位置;

    • 前两个分类器中的两两位置是否匹配(如果开头位置  与结束位置  匹配,我们就认为从  是一个实体。

    如果没有完全理清楚整个处理逻辑,你可能会有疑惑:即便我知道了  是一个实体,但是这个实体类型是什么呢?答案是:这个实体类型就是这个问题的类型,如果问题的类型是:这个句子中 PERSON 的实体是什么,那么抽出来的实体类型就是 PERSON。是不是非常有趣?

    如此看来,一个问题的优秀程度直接影响了模型抽取实体的效果,那如何设计问题呢?

    首先要明确的一点是,像我们上文一直使用的:这句子中的 [X]实体是什么? 这种问句是十分不合理的。

    想象一下更换不同的 [x] 时,整个句子的其他 token 表示都没有变,只有 [x] 所在的一个或几个 token 的表示被改变了,我们怎么能寄希望于模型像找茬一样能够分清楚这些问句之间微小的差异,并将其有效应用在文章理解中呢?

    作者在 paper 中讨论了多种问句的设计方式,有兴趣的同学可以自行阅读原文。作为问句设计的结果,作者最后使用了数据一开始标注时的每个标签的指南来作为一个问句:我们在人工标注一个数据之前,如果希望能够标出 Location 标签,我们首先会对 Location 进行一个定义,如:

    Location: Find locations in the text, including non-geographical locations, mountain ranges and bodies of water. (地点:找到文中所有的地点,包括非地理的位置,山脉与水体。)

    使用类型标注指南作为定义在结果上会 work,个人觉得是因为指南中会存在许多 "head word"(还记得上面所提到的 department 会有很大概率作为 organization 实体的 head word吗?),与此同时这些head word基本不会出现在其他标签的标注指南中。

    这些非常 unique 的信息作为问句,能够让模型很好地区分当前的问题,从而在句子中找到更加精确的实体。

    作为以上任务设计的结果,整个模型的损失函数由:起始位置识别+末尾位置识别+位置匹配三者的交叉熵损失之和决定,即:


    以上就是近几年来 Nested NER 领域的整体研究现状综述,在最后想加点我的个人感想。

    在第二部分我着重从我理解的角度出发,来分析为什么 Nested NER 不适用于现在普遍应用的 NER 任务的解决方案。

    也从我个人的感受出发,给近几年所有的相关 paper 分了体系,其划分依据主要是撇开整个故事不谈,从模型角度它究竟修改了原来 NER 解决方案中的哪个部分,或者说解决了其中哪个不足。

    于是在第三部分,我解读了三篇我觉得非常有意思的解决方案。他们可能不是结果最好的,但都给我以眼前一亮的感觉:原来这个问题还能这么做。

    我觉得从接触一个领域,到了解该领域的研究现状,到提出该领域存在的不足,这三个过程是每个研究过程中都不可或缺的,但是最重要的是在此之后针对存在的问题,提出有效的解决方案

    作为全新角度来解决问题的 paper,他们一开始的构思可能比较简单,但之后也能通过人为增加约束的形式将任务做 work,这是研究中不断实验进步的过程。而后面这两个过程,才是研究者能否做出有独创性、有价值成果的决定性因素。

    毕竟只会前三步的我,只能写博客,而掌握后两步的大家,就能发顶会了。

    与君共勉。

    References

    [1] Nested Named Entity Recognition Revisited

    [1] Straková, Jana, Milan Straka, and Jan Hajič. "Neural architectures for nested NER through linearization." arXiv preprint arXiv:1908.06926 (2019).

    [2] Straková, Jana, Milan Straka, and Jan Hajič. "Neural architectures for nested NER through linearization." arXiv preprint arXiv:1908.06926 (2019).

    [3] Shibuya, Takashi, and Eduard Hovy. "Nested Named Entity Recognition via Second-best Sequence Learning and Decoding." arXiv preprint arXiv:1909.02250 (2019).

    [4] Xia, Congying, et al. "Multi-Grained Named Entity Recognition." arXiv preprint arXiv:1906.08449 (2019).

    [5] Fisher, Joseph, and Andreas Vlachos. "Merge and Label: A novel neural network architecture for nested NER." arXiv preprint arXiv:1907.00464 (2019).

    [6] Lin, Hongyu, et al. "Sequence-to-nuggets: Nested entity mention detection via anchor-region networks." arXiv preprint arXiv:1906.03783 (2019).

    [7] Li, Xiaoya, et al. "A Unified MRC Framework for Named Entity Recognition." arXiv preprint arXiv:1910.11476 (2019).

    [8] Wang, Bailin, et al. "A neural transition-based model for nested mention recognition." arXiv preprint arXiv:1810.01808 (2018).

    点击以下标题查看更多往期内容: 

    ????

    现在,在「知乎」也能找到我们了

    进入知乎首页搜索「PaperWeekly」

    点击「关注」订阅我们的专栏吧

    关于PaperWeekly

    PaperWeekly 是一个推荐、解读、讨论、报道人工智能前沿论文成果的学术平台。如果你研究或从事 AI 领域,欢迎在公众号后台点击「交流群」,小助手将把你带入 PaperWeekly 的交流群里。

    展开全文
  • 1.html基本结构: <!... ... ...这里书写的是网站的内容,包括文字,图片,视频等 ...标签,标记,元素 常规标记标记 <标记名 属性=”属性值” 属性=”属性值”></标记> 写在< &g...
  • Java嵌套

    千次阅读 2015-10-27 15:57:18
    标记为在类中使用 static 声明的类。静态成员类可以访问外围类的任何成员,包括声明为private的成员。但是非静态的外围成员,则需要经过恰当的对象引用才能访问。因为是静态成员类,所以可以不依赖于外围类而独立...
  • 嵌套对象属性平铺实现

    千次阅读 2019-04-09 16:09:20
    最近遇到一个需求大致的实现效果就是给一个object类型的数据里面有多层...博主小白比较愚钝一开始想着一层一层的标记起来,但是一写,发现如果是无限嵌套,就不行了。于是就想到递归来解决 对象也可以用for循环遍...
  • 标签的嵌套与超链接

    2020-03-04 19:34:10
    4.标签的嵌套 一个标签中嵌套另外一个标签 标签不能乱嵌套,如以下标签的嵌套是错误的 <p style="width:300px;height:300px;background:green"> <div style="width:200px;height:200px;background:blue...
  • ElasticSearch嵌套模型基本操作

    千次阅读 2017-03-08 20:02:38
    上篇介绍了ES嵌套模型使用场景和优缺点,本篇接着介绍关于ES嵌套的索引一些基本的操作,包括插入,追加,更新,删除,查询单独放下一篇文章介绍。 首先来看下如何添加数据,上篇提到了我们项目中有三个实体类分别...
  • 举个例子,地址这种实体概念就非常适合被定义为一个嵌套类型,比如家庭地址,收件地址等等,都拥有共通的几个字段,但是它们通常是属于另外一个实体类型,比如客户这一实体,它就能够拥有家庭地址以及收件地址。...
  • HTML语言标记详解

    万次阅读 多人点赞 2018-10-20 15:06:36
    HTML语言的标记就可以理解成控件的标记,一个标记指定了一个控件,但是标记并不是控件本身,仅仅是那个控件的标记。HTML文件中的标记由浏览器来解析,产生相应的界面元素(控件),最终生成网页上可见的那些内容。 ...
  • 实体和数据库之间存在某种映射关系,hibernate根据这种映射关系完成数据的存取。在程序中这种映射关系由映射文件(*.hbm.xml)或者java注解(@)定义。 本文以java注解的形式总结映射关系配置。 实体类组件以及...
  • 嵌套(词向量)简史

    千次阅读 2015-10-19 03:51:40
    当前自然语言处理最大的趋势是对词嵌套的使用,词嵌套是指由语义相关性所度量的相似性向量。这些向量不仅可以表示计算词语之间的相关性,同时它还是其他自然语言处理项目的基础,比如文本分类、文档聚类、词性标注、...
  • 实体引用(entity reference) 非法的 XML 字符必须被替换为实体引用(entity reference)。 假如您在 XML 文档中放置了一个类似 " if salary 为了避免此类错误,需要把字符 " if salary < 1000 then 在 ...
  • 好用的对象转xml、xml转对象工具类-支持集合嵌套转换(Java实现) 网上找了很多转换工具,对于自己的业务都不是很合适,所以总结了一下网上的方案,最终定下来是这样子的,主要使用dom4j做操作 maven依赖 <...
  • javabean 实体类的转换

    2019-01-20 21:30:00
    如果两个实体的类的里面嵌套实体类的类型不一样,copy后实体类的变为原实体类的类型,当在此使用目标实体类的时候会发生类型的转化异常。2. MapStruct是一个代码生成器的工具类,简化了不同的Java Bean之间映...
  • XML-CDATA标记

    2014-11-02 21:52:37
    全名:character data 在标记CDATA下,所有的标记实体引用都被忽略,而被XML处理程序一视同仁地当做字符数据看待,CDATA的形式如下: CDATA的文本内容中不能出现字符串“]]>”,另外,CDATA不能嵌套
  • XML标记语言

    热门讨论 2018-10-21 18:25:17
    ... 是为不同的目的而设计的 ...xml设计的核心是包含与传输数据 ...实体引用 ...  为了避免把字符数据和标签中需要用到的一些特殊符号相混淆,xml提供了实体...(4)xml元素必须被正确的嵌套 (5)xml属性必须加引号
  • 命名实体识别

    万次阅读 2016-09-14 16:46:02
    命名实体识别(Named Entity Recognition, NER)的主要任务是识别出文本中的人名、地名等专有名称和有意义的时间、日期等数量短语加以归类。命名实体识别技术是信息抽取、信息检索、机器翻译、问答系统等多种自然...
  • SAX解析多层嵌套XML

    千次阅读 2016-07-22 17:28:34
    BillItem model实体类,保存BillItem节点下数据 package com.example.saxdemo; import java.util.Set; /** * * * @author dl * */ public class BillItem { private String ...
  • HTML标记语言

    千次阅读 2019-03-05 10:39:16
    3. 文档设置标记 4. 图像标记 5. 超链接的使用 6. 表格 7. HTML框架 8. 表单设计 HTML语法 1. HTML标记语言 表示网页信息的符号标记语言 特点 可以设置文本的格式,比如标题、字号、文本颜色、段落等 可以创建链表...
  • 实体引用抽取: ERA1 许多与数据处理相关的系统设计,都会基于这样一个假设:即它所处理的数据源所包含的是结构化的数据。所谓结构化数据,是指该数据源中的实体信息以一种一致的,可被预测的形式组织起来的。...
  • FreeRTOS 中断优先级嵌套错误引发HardFault异常解决
  • 第1章 HTML基本概念测试1、网页中空格的字符实体为(_____)。A、>B、"C、©D、2、HTML文档属于(_____)。A、可执行文件B、文本文件C、批处理文件D、图像文件3、在网页头部信息中不包含下面的(_____)对象。A、...
  • HTML常用标记

    千次阅读 2011-07-03 17:57:57
    回顾一下html的知识: HTML(Hypertext Markup Language)超文本标记语言,适用于编写网页的一种标记语言。 ... 一个标签由开始标签,属性,值对,内容和结束标签组成,并且标签可以嵌套
  • 命名实体识别——日期识别

    千次阅读 2018-07-26 15:36:32
    而命名实体识别效果的评判标准主要是看实体的边界是否划分正确,以及实体的类型是否标注正确,对于英文来说命名实体的边界识别相对简单,因为一般都有明显的形式标志,而对于实体类型的确定相对较难。在中文中相较于...
  • XML实体

    2007-05-19 16:06:00
    实体可以用以下3种方式分类:1、通用实体和参数实体,通用实体(general entity)用于XML文档中,在文档中通过引用来生成文字数据或二进制数据;而参数实体(parameter entity)只能用于DTD中。2、内部实体和外部实体,...
  • 实体、用css修饰xml

    2011-09-21 20:22:04
    今天和大家共同分享一下实体的规则; 一般实体:在DTD声明,在正文引用 ...可以嵌套使用 参数实体;在DTD声明,在DTD中使用       &price; 命名空间 目的:防止同名标记的冲突 xml使用教程
  • Vue中使用Element表格嵌套实现复杂逻辑报表 某天,接到一个逻辑比较复杂的报表开发任务,如下: 这里是这个报表的左半部分,可以看到,左边的四列属性,功能属性,物料编码,产品名称,规格为固定属性,右边的所有...
  • 妙用XML实体引用

    千次阅读 2017-09-29 08:44:27
    看到实体引用还能这么搞,学习了一波,转载一下,方便以后查看。 感谢原作者的分享。 XML的实体引用先看xml的文档结构:1,XML声明 xml文档是由一组使用唯一名称标识的实体组成的。始终以一个声明开始,这个声明...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 29,238
精华内容 11,695
关键字:

嵌套实体标记方式