Brat标注

1.安装过程

Step1:进入brat的主页,下载安装包。链接为:http://brat.nlplab.org/index.html

Step2:解压后,进行安装

./install.sh

Step3:配置apache2的内容来支持brat(macos和linux的配置不同,详见)

  1. 进入apache2的目录:

    cd /private/etc/apache2
  2. 编辑httpd.conf文件,在最末尾添加如下内容:

    <Directory "/opt/brat-v1.3_Crunchy_Frog">
       Options Indexes MultiViews FollowSymLinks
       Order allow,deny
       Allow from all
    
       AllowOverride Options Indexes FileInfo Limit
       AddHandler cgi-script .cgi
       AddType application/xhtml+xml .xhtml
       AddType font/ttf .ttf
    </Directory>

Step4:每次运行需要进入brat的根目录,然后运行:

【Tips】

为了方便,我在oh my zsh的配置文件配置了便捷命令:

这样的话,每次再登入brat就OK了:

2.Brat使用指北

2.0 标注过程

  1. 将待标注的文本数据copy到Brat的目录的data下:/opt/brat-v1.3_Crunchy_Frog/data/medecial

  2. cd到上述文件夹中,然后对应生成空的ann文件(或者是运行第3章的预标注的脚本来生成):

  3. 修改支持中文,记住待标注的文件名别有中文,要不然brat是不识别的。到./server/src/projectconfig.py第163行,修改为如下:

  4. medecial文件夹下,创建annotation.confvisual.conf

    annotation.conf:用于定义Schema

    visual.conf:用于定义可视化的颜色和显示的别称

2.1 标注Schema

实体类别

  • 身体部位 Body

  • 症状和体征 Symptom

  • 疾病和诊断 Disease

  • 检查和检验 Examine

  • 治疗 Treatment

关系类型

  • R1 Arg1:Body, Arg2:Symptom

  • R2 Arg1:Examine,Arg2:Disease

  • R3 Arg1:Body, Arg2:Disease

  • R4 Arg1:Body, Arg2:Examine

2.2 标注中遇到的问题

问题1:当2个实体存在包含关系时,怎么办?

标注规则规定如下:

实体I\subset实体J,标注为实体J

注:这个规则可以合并入下面的规则3

问题2:出现标注标准不同的情况,怎么办?

规定标注规则如下:

  • 规则1:N*实体A+实体B,标注为实体B

  • 规则2:实体A+Others+实体A+实体C,分开标注;并分别标注实体A实体C的关系。

  • 规则3:实体A+实体C可构成实体实体D时,标注为实体D

上述规则中:

实体A身体部位

实体B检查和检验

实体C症状与体征

实体D疾病和诊断

3.根据词典预标注

这块主要思想是:用已知的部分领域词在语料中进行预标注,预生成ann文件,用以起到部分辅助标注的工作。

在甲方爸爸这里拿到了一小部分的领域词,词数为1350词,主要包括:作战单元的类型与命名、部分作战区域的名称、常见气象名称。

预标注后需要人工来检测验证的问题:

  1. 标注的词在文章出现重叠/交叉(根据标注规则,来选择是分开标注or最长标注)

  2. 标注中出现错误(像比如把武大靖中的武大给标记出来了)

  3. 标注中未标注的(在词典中未出现过的词,以及部分词的缩略称/别称)

3.1 预标注伪代码描述

  1. 输入

    • enti_list,其中每个元素为(enti_name,enti_type)

    • unlabeled_txt_list,其中每个元素为txt

  2. 预标注伪代码

  3. 时间复杂度

设文本集T=t1,t2,...,tNT={t_1,t_2,...,t_N}中文本数量为N,已有词典D=d1,d2,...,dKD={d_1,d_2,...,d_K},词数为K

  • 对于任意一篇文章tit_i而言,复杂度主要取决于词典D中的每个词出现的频数:那么时间复杂度为O(CK)

    O(CK)C与文章的总长度和词在文章的频数有关

  • 对于整个文本数据集T,时间复杂度为O(N*CK)

效率随着每篇文章的长度、词典的长度、文本集中文本个数增加而增加。

3.2 AC自动机算法原理

Aho-Corasick算法是多模式匹配中的经典算法,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法,目前在实际应用中较多。

AC自动机的基本算法原理是基于:Trie树数据结构 + 确定性有穷自动机。这样,AC自动机能够在一次运行中找到给定集合所有字符串。

3.2.1 算法步骤及原理

它大概分为三个步骤:构建前缀树(生成goto表),添加失配指针(生成fail表),模式匹配(构造output表)。下面,我们拿模式集合[say, she, shr, he, her]为例,构建一个AC 自动机。

1. 构建Trie树

将模式串逐字符放进Trie树,如下图。

我们尝试用它处理字符串sher。理想情况下是这样:

很遗憾,前缀树只会顺着某一路径往下查找,最多到叶子节点折回树节点,继续选择另一条路径。

因此我们需要添加一些横向的路径,在失配时,跳到另一个分支上继续查找,保证搜索过的节点不会冗余搜索。

2. 添加失配指针

很显然,对于每个节点,其失配指针应该指向其他子树中的表示同一字符的那些节点,并且它与其子树能构成剩下的最长后缀。

即,我们要匹配sher, 我们已经在某一子树中命中了sh,那么我们希望能在另一个子树中命中er

现在的问题是,如何求fail指针?

我们发现root的每个儿子的fail都指向root(前缀和后缀是不会包含整个串的)。

也就是上图中root所连的sh的fail都指向root。若已经求得sh所在点的fail,我们来考虑如何求she所在点的fail。

根据sh所在点的fail得到hsh的最长后缀,而h又有儿子e,因此she的最长后缀应该是he,其fail指针就指向he所在点。

概括AC自动机求fail指针的过程:

  1. 1.对整个字典树进行宽度优先遍历。

  2. 若当前搜索到点x,那么对于x的第i个儿子(也就是代表字符i的儿子):循环迭代x的兄弟节点,直到跳到某个点也有i这个儿子,x的第i个儿子的fail就指向这个点的儿子i

3. 模式匹配

我们从根节点开始查找,如果它的孩子能命中目标串的第1个字符串,那么我们就从这个孩子的孩子中再尝试命中目标串的第2个字符串。否则,我们就顺着它的失配指针,跳到另一个分支,找其他节点。

如果都没有命中,就从根节点重头再来。

当我们节点存在表示有字符串在它这里结束的标识时(如endCound, isEnd),我们就可以确认这字符串已经命中某一个模式串,将它放到结果集中。

如果这时长字符串还没有到尽头,我们继续收集其他模式串。

3.3 ahocorasick库

pyahocorasick是AC算法在python实现的工具库,直接pip install安装可能会有问题,用conda安装实现吧。

具体的食用方法如下:

输出结果为:

最后更新于

这有帮助吗?