文章目录
1.前言
- 本文主要分析本次实验的代码,讲解主要流程和代码含义,并不关注参数的选择和模型的选择
- 后续可能还会更新
model的原理 - 如果有问题,欢迎评论或私聊讨论
- 若分析过程出现错误,请及时指正,谢谢
2.数据预处理
- 原始标注:对句子中的每个字标注上一个标签,可以简单地看成是直接对每个字分类(需要融合上下文信息),因此可以使用一个多分类器,分类器输出类别就是该字的标签
- 联合标注:对一串连续的字标注相同的标签。在NER任务中,实体由一个或多个字组成,所以它属于联合标注任务。
但是在联合标注中,相邻词语标签之间可能会存在依赖关系。这一问题可以通过标签转化的方式,把联合标注转化成原始标注解决。
我们这里使用的是BIOS标注
| 标签 | 含义 |
|---|---|
| B-X | 该字是词片段 X 的起始字 |
| I-X | 该字是词片段 X 起始字之后的字 |
| S-X | 该字单独标记为 X 标签 |
| O | 该字不属于事先定义的任何词片段类型 |
在process.py中,我们将.json文件中的语句和标签,按照BIOS方式,处理转换成了.npz文件。主要代码如下。分析过程写在注释中,依据样例.json。
text = json_line['text']
words = list(text) # 自动将句子按字符分开
# 如果没有label,则返回None
label_entities = json_line.get('label', None) # 参照下面的例子, 该项对应 label 之后的内容
labels = ['O'] * len(words) # [len(words) 个 'O'] 都初始化为 `O`
if label_entities is not None:
for key, value in label_entities.items(): # key 对应 name 和 company, value 对应后面存储内容
for sub_name, sub_index in value.items(): # sub_name 对应 叶老桂等, sub_value 对应后面的索引
for start_index, end_index in sub_index: # 对应列表中的两个数,是标签开始和结束的位置
assert ''.join(words[start_index:end_index + 1]) == sub_name
if start_index == end_index: # 单个字作为索引
labels[start_index] = 'S-' + key
else:
labels[start_index] = 'B-' + key # 开头
labels[start_index + 1:end_index + 1] = ['I-' + key] * (len(sub_name) - 1) # 中间的字
-
字符串转
list验证- 这里很重要的一点是,输入的字符串都转成单字符了,下面使用 tokenize 的时候会看到为什么
a = "你好,我是nsy,哈哈哈" print(list(a)) >>['你', '好', ',', '我', '是', 'n', 's', 'y', ',', '哈', '哈', '哈']
.json文件中,数据存储结构如下所示
{
"text": "浙商银行企业信贷部叶老桂博士则从另一个角度对五道门槛进行了解读。叶老桂认为,对目前国内商业银行而言,",
"label": {
"name": {
"叶老桂": [
[9, 11],
[32, 34]
]
},
"company": {
"浙商银行": [
[0, 3]
]
}
}
}
2.1本地查看数据转换后的结果
-
code
import numpy as np a = np.load(r'D:\2022 spring\nlp\exp4\code\BERT-LSTM-CRF\data\clue\test.npz', allow_pickle=True) index = 0 words = a['words'] labels = a['labels'] print(words[0]) print(labels[0]) -
结果
['彭

本文详细解析了使用BERT、LSTM与CRF结合实现命名实体识别(NER)的技术流程,涵盖数据预处理、模型架构及训练等多个方面。
最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



