对BERT分词之后的文本序列进行BIO标注

扫码关注“自然语言处理与算法”,学习更多NLP知识~
在这里插入图片描述

待标注文本(text.txt):

河南宏光正商置业有限公司2019年非公开发行公司债券(第一期)(品种二)定于2019123日起在本所综合协议交易平台进行转让,现将有关事项通知如下:河南宏光正商置业有限公司2019年非公开发行公司债券(第一期)(品种二)证券代码“114613”,证券简称“19正商02”,发行总额7.5亿元,票面利率7.2%,债券期限3年,附第1年末和第2年末发行人调整票面利率选择权及投资者回售选择权。深圳证券交易所二○一九年十一月二十九日
荣盛石化股份有限公司2019年面向合格投资者公开发行绿色公司债券(第一期)定于2019122日起在本所集中竞价系统和综合协议交易平台同时交易,现将有关事项通知如下:荣盛石化股份有限公司2019年面向合格投资者公开发行绿色公司债券(第一期)证券代码“112914”,证券简称“19荣盛G1”,发行总额10亿元,票面利率5.42%,债券期限2年。特此通知深圳证券交易所二○一九年十一月二十九日

经BERT分字之后的待标注文本(token_text.txt):

利用BERT的wordPiece进行分字青看我的另一篇文章:使用Bert自带的WordPiece分词工具将文本分割成单字

河 南 宏 光 正 商 置 业 有 限 公 司 2019 年 非 公 开 发 行 公 司 债 券 ( 第 一 期 ) ( 品 种 二 ) 定 于 2019123 日 起 在 本 所 综 合 协 议 交 易 平 台 进 行 转 让 , 现 将 有 关 事 项 通 知 如 下 : 河 南 宏 光 正 商 置 业 有 限 公 司 2019 年 非 公 开 发 行 公 司 债 券 ( 第 一 期 ) ( 品 种 二 ) 证 券 代 码 [UNK] 114 ##61 ##3 [UNK] , 证 券 简 称 [UNK] 19 正 商 02 [UNK] , 发 行 总 额 7 . 5 亿 元 , 票 面 利 率 7 . 2 % , 债 券 期 限 3 年 , 附 第 1 年 末 和 第 2 年 末 发 行 人 调 整 票 面 利 率 选 择 权 及 投 资 者 回 售 选 择 权 。 深 圳 证 券 交 易 所 二 ○ 一 九 年 十 一 月 二 十 九 日
荣 盛 石 化 股 份 有 限 公 司 2019 年 面 向 合 格 投 资 者 公 开 发 行 绿 色 公 司 债 券 ( 第 一 期 ) 定 于 2019122 日 起 在 本 所 集 中 竞 价 系 统 和 综 合 协 议 交 易 平 台 同 时 交 易 , 现 将 有 关 事 项 通 知 如 下 : 荣 盛 石 化 股 份 有 限 公 司 2019 年 面 向 合 格 投 资 者 公 开 发 行 绿 色 公 司 债 券 ( 第 一 期 ) 证 券 代 码 [UNK] 112 ##91 ##4 [UNK] , 证 券 简 称 [UNK] 19 荣 盛 g1 [UNK] , 发 行 总 额 10 亿 元 , 票 面 利 率 5 . 42 % , 债 券 期 限 2 年 。 特 此 通 知 深 圳 证 券 交 易 所 二 ○ 一 九 年 十 一 月 二 十 九 日

标注字典(dict.txt):

注:标注字典是通过其他工具从待标注文本中得到,如借助结巴分词词性标注。

河南宏光正商置业有限公司
荣盛石化股份有限公司

标注代码:

#!/usr/bin/python
# -*- coding: UTF-8 -*-


def labeling():
    dict_list = []
    token_list = []
    token_label_list = []
    text_list = []
    with open('./dict.txt', 'r', encoding='utf-8')as f:
        for line in f.readlines():
            dict_list.append(line.strip())
    with open('./text.txt', 'r', encoding='utf-8')as f1:
        for line in f1.readlines():
            text_list.append(line.strip())
    with open('./token_text.txt', 'r', encoding='utf-8')as f2:
        for line in f2.readlines():
            token_list.append(line.strip())
    assert len(dict_list) == len(text_list) == len(token_list)
    ff = open('./token_label.txt', 'w', encoding='utf-8')
    #cnt = 0
    for token, dict_Bio, text in zip(token_list, dict_list, text_list):
        word_list = token.strip().split(' ')
        label_list = ['O' for i in range(len(word_list))]
        index = -1
        index = text.find(dict_Bio)
        print(index)
        #cnt+=1
        #if cnt ==8:break

        for j in range(len(word_list)):
            if word_list[j].startswith('#'):
                label_list[j] = '[##WordPiece]'

        if index >= 0:
            label_list[index] = 'B-ORG'
            for i in range(index+1, len(dict_Bio)+index):
                label_list[i] = 'I-ORG'
        #print(*label_list,len(label_list))
        label_text = ''
        for label in label_list:
            label_text += label + ' '
        token_label_list.append(label_text.strip())
        ff.write(label_text + '\n')
    ff.close()

labeling()

标注好的label(token_label.txt):

B-ORG I-ORG I-ORG I-ORG I-ORG I-ORG I-ORG I-ORG I-ORG I-ORG I-ORG I-ORG O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O [##WordPiece] [##WordPiece] O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O 
B-ORG I-ORG I-ORG I-ORG I-ORG I-ORG I-ORG I-ORG I-ORG I-ORG O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O [##WordPiece] [##WordPiece] O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O 

### 如何使用BIO标注的数据训练BERT模型 #### BIO标注简介 BIO是一种常见的序列标注方法,其中“B”代表实体的起始位置,“I”代表实体内部的位置,“O”则表示不属于任何实体的部分。这种标注方式广泛应用于命名实体识别(NER)等任务中。 为了使用带有BIO标注的数据训练BERT模型,可以采用如下方法: #### 数据准备 首先需要将带BIO标签的数据转换成适合输入到BERT模型的形式。假设有一个简单的数据集样例: ```text John B-PERSON is O a O teacher O in O New B-LOCATION York I-LOCATION City I-LOCATION . ``` 这些数据可以通过脚本读取并转化为标准格式。例如,在Python中可以用Pandas或其他工具加载CSV文件或TXT文件中的标记数据[^1]。 #### 加载预训练模型 接下来,利用Hugging Face Transformers库加载预训练好的BERT模型及其分词器(Tokenzier),以便后续操作能够顺利执行。 ```python from transformers import BertTokenizer, BertForTokenClassification tokenizer = BertTokenizer.from_pretrained('bert-base-cased') model = BertForTokenClassification.from_pretrained('bert-base-cased', num_labels=9) ``` 这里`num_labels`应设置为你具体任务所需的类别数,比如如果只考虑PER、LOC两类加上'O'总共就是三个类别,则可能扩展至更多子类如MISC等等[^2]。 #### 定义Dataset与DataLoader 构建自定义数据集类继承torch.utils.data.Dataset,并重写__getitem__()和__len__()函数;同时创建相应的collate_fn用于批量处理样本。 ```python import torch from torch.utils.data import Dataset, DataLoader class NERDataset(Dataset): def __init__(self, texts, tags, tokenizer, max_len): self.texts = texts self.tags = tags self.tokenizer = tokenizer self.max_len = max_len def __len__(self): return len(self.texts) def __getitem__(self, idx): text = self.texts[idx] tag = self.tags[idx] encoding = self.tokenizer.encode_plus( text.split(), is_split_into_words=True, padding='max_length', truncation=True, max_length=self.max_len, return_tensors="pt" ) item = {key: val.squeeze(0) for key, val in encoding.items()} item['labels'] = torch.tensor(tag[:self.max_len], dtype=torch.long) return item ``` #### 微调过程配置 设定好超参数之后就可以开始正式训练了。下面给出一个基本框架作为参考: ```python training_args = TrainingArguments(output_dir="./results", evaluation_strategy="epoch") trainer = Trainer( model=model, args=training_args, train_dataset=train_dataset, eval_dataset=val_dataset, compute_metrics=lambda p: {"accuracy": accuracy_score(p.label_ids, p.predictions.argmax(axis=-1))}, ) trainer.train() ``` 注意这里的TrainingArguments以及Trainer均来自transformers库,它们简化了许多繁杂的手动编写逻辑。 #### 结果评估与保存 完成一轮或多轮迭代后记得验证效果并通过save_pretrained()保存下最终版本的权重文件供以后部署或者进一步改进时使用。 ---
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值