最详细NER实战讲解-bilstm+crf(1)数据准备

bilstm+crf也是现在实际应用上用的最多的模型!

1.数据介绍

最详细NER实战讲解-bilstm+crf(1)数据准备_第1张图片

一个txt文件对应一个ann文件

文件内容展示

.txt文件就是一些关于糖尿病的文档

最详细NER实战讲解-bilstm+crf(1)数据准备_第2张图片

T1 T2标号 symptom症状 anatomy 结构test_value等等实体类型

1845 1850就是指 实体出现的位置

最详细NER实战讲解-bilstm+crf(1)数据准备_第3张图片

做这个模型的目的是什么??

将来直接用算法 拿来一个文本 直接标注 不再需要人工标注

1.先设计好标签 每个字都有一个标注

 标签要做成什么样子?

最详细NER实战讲解-bilstm+crf(1)数据准备_第4张图片

隐马尔科夫模型里 这些字就是可观测序列  这些标记就是不可见的隐状态序列 也就是后续要预测的内容  O就是不是实体的意思  B-就是开始 I-就是中间的 E-就是结束 -后面接的实体类型

最详细NER实战讲解-bilstm+crf(1)数据准备_第5张图片

 那么要怎么处理.ann文件呢 就是该怎么处理我们的数据得到我们想要的标签呢?

1.统计总共有多少个实体

读取所有的ann文件 统计一下最终有多少个不同的实体 以及每一个实体有多少个

ok 我们开始下一步

2.统计实体种类

返回目录下所有的名字 然后再读取.ann文件  注意看注释!这里写的很详细 这也是经常用到的操作

import os

# train_dir = '自己写'
train_dir = 'datas/ruijin_round1_train2_20181022'

def get_entities(dir):
    entities = {}  # 用来存储实体名
    files = os.listdir(dir)
    files = list(set([file.split('.')[0] for file in files]))  # 以.为分割符 要下标为0的 只要前面的名字 然后set一下 去重 然后再list一下转化为列表
    # 遍历一下 再加上扩展名
    for file in files:
        path = os.path.join(dir, file + '.ann')  # 这样就可以读取到所有.ann文件
        with open(path, 'r', encoding = 'utf8') as f:
            for line in f.readlines():
# 如果这里不知道遍历的是什么 直接 print
                print(line)
                name = line.split('\t')[1].split(' ')[0]    # 按tab切分 要下标为1的 就是拿到Disease 1845 1850 Test 89 94这种实体类别名称 加上位置 然后再按空格切分 拿到实体类别名称
                if name in entities:     
                    entities[name] += 1   # entities[name]返回的是index值为name的数量有多少
                                                          就是实体名为name的有多少个
                else:
                    entities[name] = 1   # 如果这个实体名不在entities这里面 那么这个实体名的数量就等于1  如果在就+=1

          
    
    return entities

if __name__ = '__main__':
    print(get_entities(train_dir))
    print(len(get_entities(train_dir)))  # 总共15个实体

 十五个实体 每个实体有B 和I 两种 再加上不是实体的O一共就有三十一种实体类型

3.构建实体字典

def get_labelencoder(entities):
    entities = sorted(entities.items(), key=lambda x:x[1], reverse=True)
    entities = [x[0] for x in entities]
    id2label = []
    id2label.append('O')
    for entity in entities:
        id2label.append('B-' + entity)
        id2label.append('I-' + entity)
    label2id = {id2label[i]:i for i in range(len(id2label))}  # 键是 id2label 值是i
    return id2label, label2id

# 测试一下
if __name__ == '__main__':
    label = get_labelencoder(entities)
    print(label)

输出值为

最详细NER实战讲解-bilstm+crf(1)数据准备_第6张图片

 可以看见上面已经创建了31个实体类型 以后的每一个字都要打上的标记

接下来要干嘛?

一个文本的内容太长了 我们要将文本切分成一个个句子 并且进行数据预处理 数据预处理是个人觉得整个ner工程甚至所有nlp工作中最重要的部分 下章讲

你可能感兴趣的:(NER实战系列,自然语言处理,人工智能,nlp)