处理ontonotes数据集

1.所需配置

Linux服务器一台(我使用的是Ubuntu系统),pycharm,python2,python3。

2.下载过程:

首先下载ontonotes数据集(具体可参考连接文章OntoNote5数据集下载及处理过程(完整版)_ontonotes-CSDN博客),并且下载以下6个文件(连接Index of /conll/2012/download)

 加上之前下载的OntoNote一共7个文件,将它们解压(以上链接下载的6个文件是在一个目录的),得到如下目录

其中conll-2012前缀开头的几个压缩包解压出来的文件中相同的会合并,不用管。

conll-2012内部结构

这6个文件解压后在conll-2012文件夹下。
然后将这两个文件传到linux服务器上,注意v3下的scripts是在python2的环境下运行的。

3.代码运行进行处理

首先确保python解释器是python2,然后执行命令(这里需要保证conll-2012和ontonotes-release-5.0文件夹在同一级目录)

bash ./conll-2012/v3/scripts/skeleton2conll.sh -D ./ontonotes-release-5.0/data/files/data/ ./conll-2012/

以上过程可能比较久,耐心等待。
执行完毕后,切回python3环境:

之后将以下代码放在conll-2012和ontonotes-release-5.0文件夹在同一级目录,命名为covert_into_bmes_format.py

# coding=UTF-8
import io
import os, glob, itertools

def generate_collection(data_tag, dir_name, lang):
    folder = './conll-2012/v4/data/'+ data_tag + '/data/'+ lang
    results = itertools.chain.from_iterable(glob.iglob(os.path.join(root, '*.v4_gold_conll'))
                                            for root, dirs, files in os.walk(folder))

    text, word_count, sent_count = "", 0, 0
    for cur_file in results:
        with io.open(cur_file, 'r', encoding='utf-8') as f:
            flag = None
            for line in f.readlines():
                l = ' '.join(line.strip().split())
                ls = l.split(" ")
                if len(ls) >= 11:
                    word = ls[3]
                    pos = ls[4]
                    cons = ls[5]
                    ori_ner = ls[10]
                    ner = ori_ner
                    # print(word, pos, cons, ner)
                    if ori_ner == "*":
                        if flag==None:
                            ner = "O"
                        else:
                            ner = "I-" + flag
                    elif ori_ner == "*)":
                        ner = "I-" + flag
                        flag = None
                    elif ori_ner.startswith("(") and ori_ner.endswith("*") and len(ori_ner)>2:
                        flag = ori_ner[1:-1]
                        ner = "B-" + flag
                    elif ori_ner.startswith("(") and ori_ner.endswith(")") and len(ori_ner)>2 and flag == None:
                        ner = "B-" + ori_ner[1:-1]

                    text += "\t".join([word, pos, cons, ner]) + '\n'
                    word_count += 1
                else:
                    text += '\n'
                    if not line.startswith('#'):
                        sent_count += 1
            text += '\n'

    if data_tag == 'development':
        data_tag = 'dev'
    filepath = os.path.join(dir_name, data_tag + '.bio')
    with io.open(filepath, 'w', encoding='utf-8') as f:
        f.write(text)

    filepath = os.path.join(dir_name, data_tag+'.info.txt')
    with io.open(filepath, 'w', encoding='utf-8') as f:
        f.write("For file:{}, there are {} sentences, {} tokens.".format(filepath, sent_count, word_count))

def nertag_bio2bioes(dir_name):
    for bio_file in glob.glob(dir_name + '/*.bio'):
        with io.open(bio_file.rsplit('/', 1)[0]+'/ontonotes5.'+bio_file.rsplit('/',1)[1].rstrip('bio')+'bmes', 'w', encoding='utf-8') as fout, open(bio_file, 'r', encoding='utf-8') as fin:
            lines = fin.readlines()
            for idx in range(len(lines)):
                if len(lines[idx])<3:
                    fout.write('\n')
                    continue

                word, pos, label = lines[idx].split()[0], lines[idx].split()[1], lines[idx].split()[-1]
                if "-" not in label:        # O
                    for idx in range(len(word)):
                        fout.write(word[idx]+' O\n')
                else:
                    label_type=label.split('-')[-1]
                    if 'B-' in label:       # B
                        if (idx<len(lines)-1 and len(lines[idx+1])<3) or \
                            idx==len(lines)-1                         or \
                            (idx<len(lines)-1 and 'I' not in lines[idx+1].split()[-1]):
                            if len(word)==1:    # S
                                fout.write(word+' S-'+label_type+'\n')
                            else:               # 对于BIE在同一个word
                                fout.write(word[0]+' B-'+label_type+'\n')
                                for char_idx in range(1, len(word)-1):
                                    fout.write(word[char_idx]+' M-'+label_type+'\n')
                                fout.write(word[-1]+' E-'+label_type+'\n')
                        else:
                            fout.write(word[0]+' B-'+label_type+'\n')
                            for char_idx in range(1, len(word)):
                                fout.write(word[char_idx]+' M-'+label_type+'\n')
                    elif 'I-' in label:     # I
                        if (idx<len(lines)-1 and len(lines[idx+1])<3) or \
                            idx==len(lines)-1                         or \
                            (idx<len(lines)-1 and 'I' not in lines[idx+1].split()[-1]):
                            for char_idx in range(0, len(word)-1):
                                fout.write(word[char_idx]+' M-'+label_type+'\n')
                            fout.write(word[-1]+' E-'+label_type+'\n')
                        else:
                            for idx in range(len(word)):
                                fout.write(word[idx]+' M-'+label_type+'\n')

def main():
    for language in ('english', 'chinese', 'arabic'):
        dir_name = os.path.join('./result/', language)
        if not os.path.exists(dir_name):
            os.makedirs(dir_name)
        for split in ['train', 'development', 'test']:
            generate_collection(data_tag=split, dir_name=dir_name, lang=language)
        if language=='chinese':
            nertag_bio2bioes(dir_name)

if __name__ == "__main__":
    main()

 执行代码:python covert_into_bmes_format.py
然后在当前目录下会出现一个result文件,里面就是三种语言的处理结果:

打开chinese文件,可以看到我们所需要的ontonotes5.train.bmes,ontonotes5.dev.bmes,ontonotes5.test.bmes 已经得到。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: BERT-CRF是一种基于深度学习的序列标注模型,可以实现对自然语言文本进行序列标注。在实现BERT-CRF模型时,需要准备一个数据集,用于训练和评估模型的性能。 数据集是BERT-CRF模型中非常重要的一部分,它决定了模型的性能和泛化能力。数据集应当包含一组有标注的样本,每个样本都应该是一个输入序列和其对应的标注序列。 对于自然语言处理任务,常用的数据集包括CoNLL-2003、OntoNotes、ACE2005等。这些数据集包含了大量的有标注文本数据,并被广泛应用于序列标注任务中。在准备数据集时,需要根据具体的任务和数据集格式对数据集进行处理。 对于CoNLL-2003数据集,其格式为每个词占据一行,每行包含9个字段,分别为:单词、词性、分块标签和4个NER标记。在处理数据集时,需要将每个样本中的文本与其对应的NER标签分离,并进行适当的编码和分割。 在BERT-CRF实现过程中,还需要考虑如何将输入向量化,并将其转换为能够被BERT模型接受的格式。一种常用的方法是使用bert-serving来将原始文本转换为BERT向量,然后将向量输入到CRF模型中进行标注。 总之,BERT-CRF实现需要准备一个有效的训练数据集数据集应当包含有标注的样本,并符合模型的输入格式。同时,还需要针对具体的任务和数据集格式对数据集进行适当的预处理和编码。 ### 回答2: BERT-CRF是一种基于BERT模型和条件随机场(CRF)的序列标注模型。在实现bert-crf之前,我们需要一个数据集来进行训练和测试。数据集就是文本序列上每个词的标注结果,例如分句、分词、命名实体标注、词性标注等。下面我们来介绍一下如何准备一个数据集。 首先,选择一个合适的任务,例如中文命名实体识别(NER)。NER任务是指识别文本数据中具有特定意义的实体,如人名、组织机构名、地名等。选择该任务的原因是其具有广泛的应用场景,适合用来演示bert-crf模型的实现流程。 接下来是数据收集和预处理。我们需要收集一些包括实体标注信息的文本语料库,并进行预处理,例如分词、去除停用词、标注实体、划分训练集和测试集等。在这一步可以使用一些工具来简化操作,例如jieba分词、StanfordNLP、pyltp等。最终得到的文本序列和标注序列是该数据集的核心部分。 然后是特征工程,即将文本序列和标注序列转化为模型可接受的特征格式。具体来说,需要将文本序列中每个词转化为对应的BERT向量表达形式,同时将标注序列转化为one-hot编码形式。这些特征都可以通过使用相应的Python工具来进行处理。 最后是模型训练和测试。BERT-CRF模型的训练可以使用已经训练好的BERT权重作为初始值,并在预训练期的基础上进行finetuning。模型测试时可以使用在预处理阶段划分的测试集进行验证,最终将预测的标注序列与真实标注序列进行比较,并计算评价指标,如精度、召回率、F1值等。 总之,准备一个数据集是BERT-CRF模型实现的重要一步。数据集的质量将直接影响模型的表现效果和应用效果。因此,数据集的准确性和完备性都需要得到重视。 ### 回答3: BERT-CRF是一种自然语言处理技术,其基本思想是结合 BERT(Bidirectional Encoder Representations from Transformers)预训练模型和条件随机场(CRF)来完成对于自然语言序列标注的任务。 在这种技术中,BERT被用来对输入文本进行特征提取,并且将提取的特征序列作为CRF模型的输入,CRF负责对序列进行标注。 对于BERT-CRF,数据集的构建非常重要。数据集必须包含大量的标记数据,即标有正确标注的文本的数据,以确保CRF模型的准确性和效果。构建数据集的主要步骤如下: 1. 定义标记标准 在构建数据集之前,需要定义标记标准。在自然语言处理任务中,标记通常包含实体标记、词义标记、词性标记等。标志标准将大大影响数据集的构建和模型的学习效果,因此必须尽可能严格定义。 2. 选择文本样本 选择文本样本时,需要选择具有代表性的样本来训练模型,应尽可能覆盖各种文本类型和语言风格。这些文本样本应来自于各种来源,例如新闻报道、论坛、社交媒体等。 3. 标记数据 将选定的文本样本转换为适合模型学习的标记数据。还可以利用现成的标记工具进行标记化,例如Stanford NER、spaCy等。 4. 数据预处理 对标注好的数据进行清洗、切分、建立词典等预处理操作,使其适合于BERT-CRF模型进行学习和训练。这些任务可以使用Python等语言的自然语言处理库来完成。 5. 划分数据集数据集划分为训练集、开发集和测试集,通过不断调整模型参数和超参数,并在开发集上测试结果来优化模型,最终在测试集上进行评估。 总而言之,BERT-CRF技术在自然语言处理领域的应用,需要基于一组标记良好且具有代表性的数据集。通过上述步骤,我们可以建立一个完善的数据集来支持BERT-CRF模型的学习和训练。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值